📄 emul_bugapi.c
字号:
tree_parse(node, "./real-address 0x%lx", (unsigned long)bugapi->stall_cpu_loop_address); tree_parse(node, "./data 0x%lx", (unsigned long)emul_loop_instruction); if (image != NULL) tree_parse(root, "/openprom/init/stack/stack-type %s", (image->xvec->flavour == bfd_target_elf_flavour ? "ppc-elf" : "ppc-xcoff")); if (image != NULL) tree_parse(root, "/openprom/init/load-binary/file-name \"%s", bfd_get_filename(image)); return bugapi;}static voidemul_bugapi_init(os_emul_data *bugapi, int nr_cpus){ int i; /* get the current input/output devices that were created during device tree initialization */ bugapi->input = tree_find_ihandle_property(bugapi->root, "/chosen/stdin"); bugapi->output = tree_find_ihandle_property(bugapi->root, "/chosen/stdout"); /* if present, extract the selected disk devices */ for (i = 0; i < nr_bugapi_disks; i++) { char disk[32]; char *chp; strcpy(disk, "/chosen/disk0"); ASSERT(sizeof(disk) > strlen(disk)); chp = strchr(disk, '0'); *chp = *chp + i; if (tree_find_property(bugapi->root, disk) != NULL) bugapi->disk[i] = tree_find_ihandle_property(bugapi->root, disk); }}static const char *emul_bugapi_instruction_name(int call_id){ static char buffer[40]; int i; for (i = 0; i < sizeof (bug_mapping) / sizeof (bug_mapping[0]); i++) { if (bug_mapping[i].value == call_id) return bug_mapping[i].info; } (void) sprintf (buffer, "Unknown bug call 0x%x", call_id); return buffer;}static intemul_bugapi_do_read(os_emul_data *bugapi, cpu *processor, unsigned_word cia, unsigned_word buf, int nbytes){ unsigned char *scratch_buffer; int status; /* get a tempoary bufer */ scratch_buffer = (unsigned char *) zalloc(nbytes); /* check if buffer exists by reading it */ emul_read_buffer((void *)scratch_buffer, buf, nbytes, processor, cia); /* read */ status = device_instance_read(bugapi->input, (void *)scratch_buffer, nbytes); /* -1 = error, -2 = nothing available - see "serial" [IEEE1275] */ if (status < 0) { status = 0; } if (status > 0) { emul_write_buffer((void *)scratch_buffer, buf, status, processor, cia); /* Bugapi chops off the trailing n, but leaves it in the buffer */ if (scratch_buffer[status-1] == '\n' || scratch_buffer[status-1] == '\r') status--; } zfree(scratch_buffer); return status;}static voidemul_bugapi_do_diskio(os_emul_data *bugapi, cpu *processor, unsigned_word cia, unsigned_word descriptor_addr, int call_id){ struct dskio_descriptor { unsigned_1 ctrl_lun; unsigned_1 dev_lun; unsigned_2 status; unsigned_word pbuffer; unsigned_4 blk_num; unsigned_2 blk_cnt; unsigned_1 flag;#define BUG_FILE_MARK 0x80#define IGNORE_FILENUM 0x02#define END_OF_FILE 0x01 unsigned_1 addr_mod; } descriptor; int block; emul_read_buffer(&descriptor, descriptor_addr, sizeof(descriptor), processor, cia); T2H(descriptor.ctrl_lun); T2H(descriptor.dev_lun); T2H(descriptor.status); T2H(descriptor.pbuffer); T2H(descriptor.blk_num); T2H(descriptor.blk_cnt); T2H(descriptor.flag); T2H(descriptor.addr_mod); if (descriptor.dev_lun >= nr_bugapi_disks || bugapi->disk[descriptor.dev_lun] == NULL) { error("emul_bugapi_do_diskio: attempt to access unconfigured disk /chosen/disk%d", descriptor.dev_lun); } else { for (block = 0; block < descriptor.blk_cnt; block++) { device_instance *disk = bugapi->disk[descriptor.dev_lun]; unsigned_1 buf[512]; /*????*/ unsigned_word block_nr = descriptor.blk_num + block; unsigned_word byte_nr = block_nr * sizeof(buf); unsigned_word block_addr = descriptor.pbuffer + block*sizeof(buf); if (device_instance_seek(disk, 0, byte_nr) < 0) error("emul_bugapi_do_diskio: bad seek\n"); switch (call_id) { case _DSKRD: if (device_instance_read(disk, buf, sizeof(buf)) != sizeof(buf)) error("emul_`bugapi_do_diskio: bad read\n"); emul_write_buffer(buf, block_addr, sizeof(buf), processor, cia); break; case _DSKWR: emul_read_buffer(buf, block_addr, sizeof(buf), processor, cia); if (device_instance_write(disk, buf, sizeof(buf)) != sizeof(buf)) error("emul_bugapi_do_diskio: bad write\n"); break; default: error("emul_bugapi_do_diskio: bad switch\n"); } } }}static voidemul_bugapi_do_write(os_emul_data *bugapi, cpu *processor, unsigned_word cia, unsigned_word buf, int nbytes, const char *suffix){ void *scratch_buffer = NULL; /* get a tempoary bufer */ if (nbytes > 0) { scratch_buffer = zalloc(nbytes); /* copy in */ emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia); /* write */ device_instance_write(bugapi->output, scratch_buffer, nbytes); zfree(scratch_buffer); } if (suffix) device_instance_write(bugapi->output, suffix, strlen(suffix)); flush_stdoutput ();}static intemul_bugapi_instruction_call(cpu *processor, unsigned_word cia, unsigned_word ra, os_emul_data *bugapi){ const int call_id = cpu_registers(processor)->gpr[10]; unsigned char uc;#define MY_INDEX itable_instruction_call ITRACE (trace_os_emul, (" 0x%x %s, r3 = 0x%lx, r4 = 0x%lx\n", call_id, emul_bugapi_instruction_name (call_id), (long)cpu_registers(processor)->gpr[3], (long)cpu_registers(processor)->gpr[4]));; /* check that this isn't an invalid instruction */ if (cia != bugapi->system_call_address) return 0; switch (call_id) { default: error("emul-bugapi: unimplemented bugapi %s from address 0x%lx\n", emul_bugapi_instruction_name (call_id), SRR0); break; /* read a single character, output r3 = byte */ /* FIXME: Add support to unbuffer input */ case _INCHR: if (device_instance_read(bugapi->input, (void *)&uc, 1) <= 0) uc = 0; cpu_registers(processor)->gpr[3] = uc; break; /* read a line of at most 256 bytes, r3 = ptr to 1st byte, output r3 = ptr to last byte+1 */ case _INLN: cpu_registers(processor)->gpr[3] += emul_bugapi_do_read(bugapi, processor, cia, cpu_registers(processor)->gpr[3], 256); break; /* output a character, r3 = character */ case _OUTCHR: { char out = (char)cpu_registers(processor)->gpr[3]; device_instance_write(bugapi->output, &out, 1); break; } /* output a string, r3 = ptr to 1st byte, r4 = ptr to last byte+1 */ case _OUTSTR: emul_bugapi_do_write(bugapi, processor, cia, cpu_registers(processor)->gpr[3], cpu_registers(processor)->gpr[4] - cpu_registers(processor)->gpr[3], (const char *)0); break; /* output a string followed by \r\n, r3 = ptr to 1st byte, r4 = ptr to last byte+1 */ case _OUTLN: emul_bugapi_do_write(bugapi, processor, cia, cpu_registers(processor)->gpr[3], cpu_registers(processor)->gpr[4] - cpu_registers(processor)->gpr[3], "\n"); break; /* output a \r\n */ case _PCRLF: device_instance_write(bugapi->output, "\n", 1); break; /* read/write blocks of data to/from the disk */ case _DSKWR: case _DSKRD: emul_bugapi_do_diskio(bugapi, processor, cia, cpu_registers(processor)->gpr[3], call_id); break; /* return to ppcbug monitor (exiting with gpr[3] as status is not part of the bug monitor) */ case _RETURN: cpu_halt(processor, cia, was_exited, cpu_registers(processor)->gpr[3]); break; } return 1; /* the instruction following this one is a RFI. Thus by just continuing the return from system call is performed */}const os_emul emul_bugapi = { "bugapi", emul_bugapi_create, emul_bugapi_init, 0, /*system_call*/ emul_bugapi_instruction_call, 0 /*data*/};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -