int write_mi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct r4300_core* r4300 = (struct r4300_core*)opaque; uint32_t reg = mi_reg(address); const uint32_t* cp0_regs = r4300_cp0_regs(); switch(reg) { case MI_INIT_MODE_REG: if (update_mi_init_mode(&r4300->mi.regs[MI_INIT_MODE_REG], value & mask) != 0) { clear_rcp_interrupt(r4300, MI_INTR_DP); } break; case MI_INTR_MASK_REG: update_mi_intr_mask(&r4300->mi.regs[MI_INTR_MASK_REG], value & mask); check_interupt(); cp0_update_count(); if (next_interupt <= cp0_regs[CP0_COUNT_REG]) gen_interupt(); break; } return 0; }
void got_packet (u_char *useless,const struct pcap_pkthdr *pheader, const u_char *packet) { if ( intr_flag != 0 ) { check_interupt(); } inpacket = 1; tstamp = pheader->ts; /* are we dumping */ if (mode & MODE_DUMP) { time_t now = time(NULL); /* check if we should roll on time */ if( ( roll_time != 0 ) && ( now >= (roll_time_last + roll_time) ) ) { roll_time_last = now; printf("Rolling on time.\n"); dump_file_roll(); } dump_file_offset = (uint64_t)ftell((FILE *)dump_handle); /* check if we should roll on size */ if ( (roll_size > 0) && (dump_file_offset >= roll_size) ) { printf("Rolling on size.\n"); dump_file_roll(); } /* write the packet */ pcap_dump((u_char *)dump_handle, pheader, packet); if ( dump_with_flush ) pcap_dump_flush(dump_handle); } else if ( mode & MODE_FILE ) { read_file_offset = (uint64_t)ftell(pcap_file(handle)) - pheader->caplen - 16; } /* printf("[*] Got network packet...\n"); */ ether_header *eth_hdr; eth_hdr = (ether_header *) (packet); u_short eth_type; eth_type = ntohs(eth_hdr->eth_ip_type); int eth_header_len; eth_header_len = ETHERNET_HEADER_LEN; vlanid = 0; if ( eth_type == ETHERNET_TYPE_8021Q ) { /* printf("[*] ETHERNET TYPE 8021Q\n"); */ eth_type = ntohs(eth_hdr->eth_8_ip_type); eth_header_len +=4; vlanid = ntohs(eth_hdr->eth_8_vid); } else if ( eth_type == (ETHERNET_TYPE_802Q1MT|ETHERNET_TYPE_802Q1MT2|ETHERNET_TYPE_802Q1MT3|ETHERNET_TYPE_8021AD) ) { /* printf("[*] ETHERNET TYPE 802Q1MT\n"); */ eth_type = ntohs(eth_hdr->eth_82_ip_type); eth_header_len +=8; vlanid = ntohs(eth_hdr->eth_82_vid); } /* zero-ise our structure, simplifies our hashing later on */ int ip_tracked = 0; ip_t *ip_src = calloc(1, sizeof(ip_t)); ip_t *ip_dst = calloc(1, sizeof(ip_t)); if ( eth_type == ETHERNET_TYPE_IP ) { /* printf("[*] Got IPv4 Packet...\n"); */ ip4_header *ip4; ip4 = (ip4_header *) (packet + eth_header_len); ip_set(&ip_config, ip_src, &ip4->ip_src, AF_INET); ip_set(&ip_config, ip_dst, &ip4->ip_dst, AF_INET); if ( ip4->ip_p == IP_PROTO_TCP ) { tcp_header *tcph; tcph = (tcp_header *) (packet + eth_header_len + (IP_HL(ip4)*4)); /* printf("[*] IPv4 PROTOCOL TYPE TCP:\n"); */ ip_tracked = cx_track(ip_src, tcph->src_port, ip_dst, tcph->dst_port, ip4->ip_p, pheader->len, tcph->t_flags, tstamp, AF_INET); } else if (ip4->ip_p == IP_PROTO_UDP) { udp_header *udph; udph = (udp_header *) (packet + eth_header_len + (IP_HL(ip4)*4)); /* printf("[*] IPv4 PROTOCOL TYPE UDP:\n"); */ ip_tracked = cx_track(ip_src, udph->src_port, ip_dst, udph->dst_port, ip4->ip_p, pheader->len, 0, tstamp, AF_INET); } else if (ip4->ip_p == IP_PROTO_ICMP) { icmp_header *icmph; icmph = (icmp_header *) (packet + eth_header_len + (IP_HL(ip4)*4)); /* printf("[*] IP PROTOCOL TYPE ICMP\n"); */ ip_tracked = cx_track(ip_src, icmph->s_icmp_id, ip_dst, icmph->s_icmp_id, ip4->ip_p, pheader->len, 0, tstamp, AF_INET); } else { /* printf("[*] IPv4 PROTOCOL TYPE OTHER: %d\n",ip4->ip_p); */ ip_tracked = cx_track(ip_src, ip4->ip_p, ip_dst, ip4->ip_p, ip4->ip_p, pheader->len, 0, tstamp, AF_INET); } } else if ( eth_type == ETHERNET_TYPE_IPV6) { /* printf("[*] Got IPv6 Packet...\n"); */ ip6_header *ip6; ip6 = (ip6_header *) (packet + eth_header_len); ip_set(&ip_config, ip_src, &ip6->ip_src, AF_INET6); ip_set(&ip_config, ip_dst, &ip6->ip_dst, AF_INET6); if ( ip6->next == IP_PROTO_TCP ) { tcp_header *tcph; tcph = (tcp_header *) (packet + eth_header_len + IP6_HEADER_LEN); /* printf("[*] IPv6 PROTOCOL TYPE TCP:\n"); */ ip_tracked = cx_track(ip_src, tcph->src_port, ip_dst, tcph->dst_port, ip6->next, pheader->len, tcph->t_flags, tstamp, AF_INET6); } else if (ip6->next == IP_PROTO_UDP) { udp_header *udph; udph = (udp_header *) (packet + eth_header_len + IP6_HEADER_LEN); /* printf("[*] IPv6 PROTOCOL TYPE UDP:\n"); */ ip_tracked = cx_track(ip_src, udph->src_port, ip_dst, udph->dst_port, ip6->next, pheader->len, 0, tstamp, AF_INET6); } else if (ip6->next == IP6_PROTO_ICMP) { //icmp6_header *icmph; //icmph = (icmp6_header *) (packet + eth_header_len + IP6_HEADER_LEN); /* printf("[*] IPv6 PROTOCOL TYPE ICMP\n"); */ ip_tracked = cx_track(ip_src, ip6->hop_lmt, ip_dst, ip6->hop_lmt, ip6->next, pheader->len, 0, tstamp, AF_INET6); } else { /* printf("[*] IPv6 PROTOCOL TYPE OTHER: %d\n",ip6->next); */ ip_tracked = cx_track(ip_src, ip6->next, ip_dst, ip6->next, ip6->next, pheader->len, 0, tstamp, AF_INET6); } } if ( ip_tracked == 0 ) { if (ip_src != NULL) ip_free(ip_src); if (ip_dst != NULL) ip_free(ip_dst); } inpacket = 0; return; (void) useless; /* else { */ /* printf("[*] ETHERNET TYPE : %x\n", eth_hdr->eth_ip_type); */ /* return; */ /* } */ }
void MTC0(void) { switch(PC->f.r.nrd) { case 0: // Index Index = rrt & 0x8000003F; if ((Index & 0x3F) > 31) { DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31"); stop=1; } break; case 1: // Random break; case 2: // EntryLo0 EntryLo0 = rrt & 0x3FFFFFFF; break; case 3: // EntryLo1 EntryLo1 = rrt & 0x3FFFFFFF; break; case 4: // Context Context = (rrt & 0xFF800000) | (Context & 0x007FFFF0); break; case 5: // PageMask PageMask = rrt & 0x01FFE000; break; case 6: // Wired Wired = rrt; Random = 31; break; case 8: // BadVAddr break; case 9: // Count update_count(); if (next_interupt <= Count) gen_interupt(); debug_count += Count; translate_event_queue(rrt & 0xFFFFFFFF); Count = rrt & 0xFFFFFFFF; debug_count -= Count; break; case 10: // EntryHi EntryHi = rrt & 0xFFFFE0FF; break; case 11: // Compare update_count(); remove_event(COMPARE_INT); add_interupt_event_count(COMPARE_INT, (unsigned int)rrt); Compare = rrt; Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear break; case 12: // Status if((rrt & 0x04000000) != (Status & 0x04000000)) { shuffle_fpr_data(Status, rrt); set_fpr_pointers(rrt); } Status = rrt; PC++; check_interupt(); update_count(); if (next_interupt <= Count) gen_interupt(); PC--; break; case 13: // Cause if (rrt!=0) { DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value"); stop = 1; } else Cause = rrt; break; case 14: // EPC EPC = rrt; break; case 15: // PRevID break; case 16: // Config Config = rrt; break; case 18: // WatchLo WatchLo = rrt & 0xFFFFFFFF; break; case 19: // WatchHi WatchHi = rrt & 0xFFFFFFFF; break; case 27: // CacheErr break; case 28: // TagLo TagLo = rrt & 0x0FFFFFC0; break; case 29: // TagHi TagHi =0; break; default: DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", PC->f.r.nrd); stop=1; } PC++; }
void MTC0() { switch(PC->f.r.nrd) { case 0: // Index Index = rrt & 0x8000003F; if ((Index & 0x3F) > 31) { printf ("il y a plus de 32 TLB\n"); stop=1; } break; case 1: // Random break; case 2: // EntryLo0 EntryLo0 = rrt & 0x3FFFFFFF; break; case 3: // EntryLo1 EntryLo1 = rrt & 0x3FFFFFFF; break; case 4: // Context Context = (rrt & 0xFF800000) | (Context & 0x007FFFF0); break; case 5: // PageMask PageMask = rrt & 0x01FFE000; break; case 6: // Wired Wired = rrt; Random = 31; break; case 8: // BadVAddr break; case 9: // Count update_count(); if (next_interupt <= Count) gen_interupt(); translate_event_queue(rrt & 0xFFFFFFFF); Count = rrt & 0xFFFFFFFF; break; case 10: // EntryHi EntryHi = rrt & 0xFFFFE0FF; break; case 11: // Compare update_count(); remove_event(COMPARE_INT); add_interupt_event_count(COMPARE_INT, (unsigned long)rrt); Compare = rrt; Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear break; case 12: // Status if((rrt & 0x04000000) != (Status & 0x04000000)) { shuffle_fpr_data(Status, rrt); set_fpr_pointers(rrt); } Status = rrt; update_count(); PC++; check_interupt(); if (next_interupt <= Count) gen_interupt(); PC--; break; case 13: // Cause if (rrt!=0) { printf("écriture dans Cause\n"); stop = 1; } else Cause = rrt; break; case 14: // EPC EPC = rrt; break; case 15: // PRevID break; case 16: // Config Config = rrt; break; case 18: // WatchLo WatchLo = rrt & 0xFFFFFFFF; break; case 19: // WatchHi WatchHi = rrt & 0xFFFFFFFF; break; case 27: // CacheErr break; case 28: // TagLo TagLo = rrt & 0x0FFFFFC0; break; case 29: // TagHi TagHi =0; break; default: printf("unknown mtc0 write : %d\n", PC->f.r.nrd); stop=1; } PC++; }
void MTC0(void) { switch(PC->f.r.nrd) { case 0: // Index Index = rrt & 0x8000003F; if ((Index & 0x3F) > 31) { printf ("il y a plus de 32 TLB\n"); stop=1; } break; case 1: // Random break; case 2: // EntryLo0 EntryLo0 = rrt & 0x3FFFFFFF; break; case 3: // EntryLo1 EntryLo1 = rrt & 0x3FFFFFFF; break; case 4: // Context Context = (rrt & 0xFF800000) | (Context & 0x007FFFF0); break; case 5: // PageMask PageMask = rrt & 0x01FFE000; break; case 6: // Wired Wired = rrt; Random = 31; break; case 8: // BadVAddr break; case 9: // Count update_count(); //if (next_interupt <= Count) gen_interupt(); debug_count += Count; translate_event_queue(rrt & 0xFFFFFFFF); Count = rrt & 0xFFFFFFFF; debug_count -= Count; break; case 10: // EntryHi EntryHi = rrt & 0xFFFFE0FF; break; case 11: // Compare update_count(); remove_event(COMPARE_INT); add_interupt_event_count(COMPARE_INT, (unsigned int)rrt); Compare = rrt; Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear break; case 12: // Status if((rrt & 0x04000000) != (Status & 0x04000000)) { if (rrt & 0x04000000) { int i; for (i=0; i<32; i++) { reg_cop1_double[i]=(double*)®_cop1_fgr_64[i]; reg_cop1_simple[i]=(float*)®_cop1_fgr_64[i]; } } else { int i; for (i=0; i<32; i++) { if(!(i&1)) reg_cop1_double[i]=(double*)®_cop1_fgr_64[i>>1]; #ifndef _BIG_ENDIAN reg_cop1_simple[i]=(float*)®_cop1_fgr_64[i>>1]+(i&1); #else reg_cop1_simple[i]=(float*)®_cop1_fgr_64[i>>1]+(1-(i&1)); #endif } } } Status = rrt; //WTF? This screws up the count... //PC++; check_interupt(); update_count(); //if (next_interupt <= Count) gen_interupt(); //PC--; break; case 13: // Cause if (rrt!=0) { printf("écriture dans Cause\n"); stop = 1; } else Cause = rrt; break; case 14: // EPC EPC = rrt; break; case 15: // PRevID break; case 16: // Config Config = rrt; break; case 18: // WatchLo WatchLo = rrt & 0xFFFFFFFF; break; case 19: // WatchHi WatchHi = rrt & 0xFFFFFFFF; break; case 27: // CacheErr break; case 28: // TagLo TagLo = rrt & 0x0FFFFFC0; break; case 29: // TagHi TagHi =0; break; default: printf("unknown mtc0 write : %d\n", PC->f.r.nrd); stop=1; } PC++; }
void clear_rcp_interrupt(struct r4300_core* r4300, uint32_t mi_intr) { r4300->mi.regs[MI_INTR_REG] &= ~mi_intr; check_interupt(); }
/* interrupt execution is scheduled (if not masked) */ void signal_rcp_interrupt(struct r4300_core* r4300, uint32_t mi_intr) { r4300->mi.regs[MI_INTR_REG] |= mi_intr; check_interupt(); }