📄 emul_chirp.c
字号:
sizeof(name), processor, cia); TRACE(trace_os_emul, ("getprop - in - phandle=0x%lx(0x%lx`%s') name=`%s' buf=0x%lx buflen=%ld\n", (unsigned long)args.phandle, (unsigned long)phandle, (phandle == NULL ? "" : device_name(phandle)), name, (unsigned long)args.buf, (unsigned long)args.buflen)); /* get the property */ if (args.phandle == 0 || phandle == NULL) { args.size = -1; } else { const device_property *prop = device_find_property(phandle, name); if (prop == NULL) { args.size = -1; } else { int size = args.buflen; if (size > prop->sizeof_array) size = prop->sizeof_array; emul_write_buffer(prop->array, args.buf, size, processor, cia); args.size = size; switch (prop->type) { case string_property: TRACE(trace_os_emul, ("getprop - string `%s'\n", device_find_string_property(phandle, name))); break; case ihandle_property: TRACE(trace_os_emul, ("getprop - ihandle=0x%lx(0x%lx`%s')\n", BE2H_cell(*(unsigned_cell*)prop->array), (unsigned long)device_find_ihandle_property(phandle, name), ihandle_name(device_find_ihandle_property(phandle, name)))); break; default: break; } } } /* write back the result */ if (data->n_returns == 0) TRACE(trace_os_emul, ("getprop - out - size=%ld (not returned)\n", (unsigned long)args.size)); else { TRACE(trace_os_emul, ("getprop - out - size=%ld\n", (unsigned long)args.size)); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); } return 0;}static intchirp_emul_nextprop(os_emul_data *data, cpu *processor, unsigned_word cia){ struct nextprop_args { /*in*/ unsigned_cell phandle; unsigned_cell previous; unsigned_cell buf; /*out*/ unsigned_cell flag; } args; char previous[32]; device *phandle; /* read in the args */ if (chirp_read_t2h_args(&args, sizeof(args), 3, 1, data, processor, cia)) return -1; phandle = external_to_device(data->root, args.phandle); if (args.previous != 0) emul_read_string(previous, args.previous, sizeof(previous), processor, cia); else /* If previous is NULL, make it look like the empty string. The next property after the empty string is the first property. */ strcpy (previous, ""); TRACE(trace_os_emul, ("nextprop - in - phandle=0x%lx(0x%lx`%s') previous=`%s' buf=0x%lx\n", (unsigned long)args.phandle, (unsigned long)phandle, (phandle == NULL ? "" : device_name(phandle)), previous, (unsigned long)args.buf)); /* find the next property */ if (args.phandle == 0 || phandle == NULL) { args.flag = -1; } else { const device_property *prev_prop = device_find_property(phandle, previous); if (prev_prop == NULL) { if (strcmp (previous, "") == 0) args.flag = 0; /* No properties */ else args.flag = -1; /* name invalid */ } else { const device_property *next_prop; if (strcmp (previous, "") == 0) { next_prop = prev_prop; /* The first property. */ } else { next_prop = device_next_property(prev_prop); } if (next_prop == NULL) { args.flag = 0; /* last property */ } else { emul_write_buffer(next_prop->name, args.buf, strlen(next_prop->name), processor, cia); TRACE(trace_os_emul, ("nextprop - name=`%s'\n", next_prop->name)); args.flag = 1; /* worked ok */ } } } /* write back the result */ TRACE(trace_os_emul, ("nextprop - out - flag=%ld\n", (unsigned long)args.flag)); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}#if 0static intchirp_emul_setprop(os_emul_data *data, cpu *processor, unsigned_word cia){ error("chirp: setprop method not implemented\n"); return 0;}#endifstatic intchirp_emul_canon(os_emul_data *data, cpu *processor, unsigned_word cia){ struct canon_args { /*in*/ unsigned_cell device_specifier; unsigned_cell buf; unsigned_cell buflen; /*out*/ unsigned_cell length; } args; char device_specifier[1024]; device *phandle; const char *path; int length; /* read in the args */ if (chirp_read_t2h_args(&args, sizeof(args), 3, 1, data, processor, cia)) return -1; emul_read_string(device_specifier, args.device_specifier, sizeof(device_specifier), processor, cia); TRACE(trace_os_emul, ("canon - in - device_specifier=`%s' buf=0x%lx buflen=%lx\n", device_specifier, (unsigned long)args.buf, (unsigned long)args.buflen)); /* canon the name */ phandle = tree_find_device(data->root, device_specifier); if (phandle == NULL) { length = -1; path = ""; args.length = -1; } else { path = device_path(phandle); length = strlen(path); if (length >= args.buflen) length = args.buflen - 1; emul_write_buffer(path, args.buf, length, processor, cia); args.length = length; } /* write back the result */ TRACE(trace_os_emul, ("canon - out - length=%ld buf=`%s'\n", (unsigned long)args.length, path)); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}static intchirp_emul_finddevice(os_emul_data *data, cpu *processor, unsigned_word cia){ struct finddevice_args { /*in*/ unsigned_cell device_specifier; /*out*/ unsigned_cell phandle; } args; char device_specifier[1024]; device *phandle; /* get the args */ if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia)) return -1; emul_read_string(device_specifier, args.device_specifier, sizeof(device_specifier), processor, cia); TRACE(trace_os_emul, ("finddevice - in - device_specifier=`%s'\n", device_specifier)); /* find the device */ phandle = tree_find_device(data->root, device_specifier); if (phandle == NULL) args.phandle = -1; else args.phandle = device_to_external(phandle); /* return its phandle */ TRACE(trace_os_emul, ("finddevice - 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_instance_to_path(os_emul_data *data, cpu *processor, unsigned_word cia){ struct instance_to_path_args { /*in*/ unsigned_cell ihandle; unsigned_cell buf; unsigned_cell buflen; /*out*/ unsigned_cell length; } args; device_instance *ihandle; const char *path; int length; /* 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, ("instance-to-path - in - ihandle=0x%lx(0x%lx`%s') buf=0x%lx buflen=%ld\n", (unsigned long)args.ihandle, (unsigned long)ihandle, ihandle_name(ihandle), (unsigned long)args.buf, (unsigned long)args.buflen)); /* get the devices name */ if (ihandle == NULL) { args.length = -1; path = "(null)"; } else { path = device_instance_path(ihandle); length = strlen(path); if (length >= args.buflen) length = args.buflen - 1; emul_write_buffer(path, args.buf, length, processor, cia); args.length = length; } /* return its phandle */ TRACE(trace_os_emul, ("instance-to-path - out - length=%ld buf=`%s')\n", (unsigned long)args.length, path)); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}static intchirp_emul_package_to_path(os_emul_data *data, cpu *processor, unsigned_word cia){ struct package_to_path_args { /*in*/ unsigned_cell phandle; unsigned_cell buf; unsigned_cell buflen; /*out*/ unsigned_cell length; } args; device *phandle; const char *path; /* get the args */ if (chirp_read_t2h_args(&args, sizeof(args), 3, 1, data, processor, cia)) return -1; phandle = external_to_device(data->root, args.phandle); TRACE(trace_os_emul, ("package-to-path - in - phandle=0x%lx(0x%lx`%s') buf=0x%lx buflen=%ld\n", (unsigned long)args.phandle, (unsigned long)phandle, (phandle == NULL ? "" : device_name(phandle)), (unsigned long)args.buf, (unsigned long)args.buflen)); /* get the devices name */ if (phandle == NULL) { args.length = -1; path = "(null)"; } else { int length; path = device_path(phandle); length = strlen(path); if (length >= args.buflen) length = args.buflen - 1; emul_write_buffer(path, args.buf, length, processor, cia); args.length = length; } /* return its phandle */ TRACE(trace_os_emul, ("package-to-path - out - length=%ld buf=`%s')\n", (unsigned long)args.length, path)); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}static intchirp_emul_call_method(os_emul_data *data, cpu *processor, unsigned_word cia){ struct call_method_args { /*in*/ unsigned_cell method; unsigned_cell ihandle; /*in/out*/ unsigned_cell stack[13]; /*6in + 6out + catch */ } args; char method[32]; device_instance *ihandle; /* some useful info about our mini stack */ int n_stack_args; int n_stack_returns; int stack_catch_result; int stack_returns; /* read the args */ if (chirp_read_t2h_args(&args, sizeof(args), -1, -1, data, processor, cia)) return -1; emul_read_string(method, args.method, sizeof(method), processor, cia); ihandle = external_to_device_instance(data->root, args.ihandle); n_stack_args = data->n_args - 2; n_stack_returns = data->n_returns - 1; stack_catch_result = n_stack_args; stack_returns = stack_catch_result + 1; TRACE(trace_os_emul, ("call-method - in - n_args=%ld n_returns=%ld method=`%s' ihandle=0x%lx(0x%lx`%s')\n", (unsigned long)data->n_args, (unsigned long)data->n_returns, method, (unsigned long)args.ihandle, (unsigned long)ihandle, ihandle_name(ihandle))); /* see if we can emulate this method */ if (ihandle == NULL) { /* OpenFirmware doesn't define this error */ error("chirp: invalid ihandle passed to call-method method"); } else { args.stack[stack_catch_result] = device_instance_call_method(ihandle, method, n_stack_args, &args.stack[0], n_stack_returns, &args.stack[stack_returns]); } /* finished */ TRACE(trace_os_emul, ("call-method - out - catch-result=%ld\n", (unsigned long)args.stack[stack_catch_result])); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}/* Device I/O */static intchirp_emul_open(os_emul_data *data, cpu *processor, unsigned_word cia){ struct open_args { /*in*/ unsigned_cell device_specifier; /*out*/ unsigned_cell ihandle; } args; char device_specifier[1024]; device_instance *ihandle; /* read the args */ if (chirp_read_t2h_args(&args, sizeof(args), 1, 1, data, processor, cia)) return -1; emul_read_string(device_specifier, args.device_specifier, sizeof(device_specifier), processor, cia); TRACE(trace_os_emul, ("open - in - device_specifier=`%s'\n", device_specifier)); /* open the device */ ihandle = tree_instance(data->root, device_specifier); if (ihandle == NULL) args.ihandle = -1; else args.ihandle = device_instance_to_external(ihandle); /* return the ihandle result */ TRACE(trace_os_emul, ("open - out - ihandle=0x%lx(0x%lx`%s')\n", (unsigned long)args.ihandle, (unsigned long)ihandle, ihandle_name(ihandle))); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}static intchirp_emul_close(os_emul_data *data, cpu *processor, unsigned_word cia){ struct close_args { /*in*/ unsigned_cell ihandle; /*out*/ } args; device_instance *ihandle; /* read the args */ if (chirp_read_t2h_args(&args, sizeof(args), 1, 0, data, processor, cia)) return -1; ihandle = external_to_device_instance(data->root, args.ihandle); TRACE(trace_os_emul, ("close - in - ihandle=0x%lx(0x%lx`%s')\n", (unsigned long)args.ihandle, (unsigned long)ihandle, ihandle_name(ihandle))); /* close the device */ if (ihandle == NULL) { /* OpenFirmware doesn't define this error */ error("chirp: invalid ihandle passed to close method"); } else { device_instance_delete(ihandle); } /* return the ihandle result */ TRACE(trace_os_emul, ("close - out\n")); chirp_write_h2t_args(&args, sizeof(args), data, processor, cia); return 0;}static intchirp_emul_read(os_emul_data *data, cpu *processor, unsigned_word cia){ struct read_args { /*in*/ unsigned_cell ihandle; unsigned_cell addr; unsigned_cell len; /*out*/ unsigned_cell actual; } args; char buf[1024]; device_instance *ihandle; /* read 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, ("read - in - ihandle=0x%lx(0x%lx`%s') addr=0x%lx len=%ld\n", (unsigned long)args.ihandle, (unsigned long)ihandle, ihandle_name(ihandle), (unsigned long)args.addr, (unsigned long)args.len)); if (ihandle == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -