static int ipanic_write_userspace(unsigned int off) { int saved_oip, rc, rc2; unsigned int copy_count = 0; DumpNativeInfo(); while (1) { saved_oip = oops_in_progress; oops_in_progress = 1; rc = panic_dump_user_info(emmc_bounce, PAGE_SIZE, copy_count); oops_in_progress = saved_oip; if (rc <= 0) break; copy_count += rc; rc2 = emmc_ipanic_write(emmc_bounce, off, rc); if (rc2 <= 0) { xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: Flash write failed (%d)\n", __func__, rc2); return rc2; } off += rc2; } xlog_printk(ANDROID_LOG_DEBUG, IPANIC_LOG_TAG, "%s: count %d, strlen(NativeInfo):%d, off:%d\n", __func__, copy_count, strlen(NativeInfo), off); return copy_count; }
static int ipanic_write_log_buf(unsigned int off, int log_copy_start, int log_copy_end) { int saved_oip; int rc, rc2; unsigned int last_chunk = 0, copy_count = 0; while (!last_chunk) { saved_oip = oops_in_progress; oops_in_progress = 1; rc = log_buf_copy2(emmc_bounce, PAGE_SIZE, log_copy_start, log_copy_end); BUG_ON(rc < 0); log_copy_start += rc; copy_count += rc; if (rc != PAGE_SIZE) last_chunk = rc; oops_in_progress = saved_oip; if (rc <= 0) break; rc2 = emmc_ipanic_write(emmc_bounce, off, rc); if (rc2 <= 0) { xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "aee-ipanic: Flash write failed (%d)\n", rc2); return rc2; } off += rc2; } return copy_count; }
int ipanic_write_log_buf(unsigned int off, struct ipanic_log_index start, struct ipanic_log_index end) { int saved_oip; int rc, rc2; unsigned int last_chunk = 0, copy_count = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) int log_copy_start = start.value; int log_copy_end = end.value; #else struct kmsg_dumper dumper; dumper.active = true; dumper.cur_idx = start.idx; dumper.cur_seq = start.seq; dumper.next_idx = end.idx; dumper.next_seq = end.seq; #endif while (!last_chunk) { saved_oip = oops_in_progress; oops_in_progress = 1; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) rc = log_buf_copy2(emmc_bounce, PAGE_SIZE, log_copy_start, log_copy_end); BUG_ON(rc < 0); log_copy_start += rc; #else rc = ipanic_kmsg_dump3(&dumper, emmc_bounce, PAGE_SIZE); BUG_ON(rc < 0); #endif copy_count += rc; if (rc != PAGE_SIZE) last_chunk = rc; oops_in_progress = saved_oip; if (rc <= 0) break; rc2 = emmc_ipanic_write(emmc_bounce, off, rc); if (rc2 <= 0) { xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "aee-ipanic: Flash write failed (%d)\n", rc2); return rc2; } off += rc2; } return copy_count; }
static void ipanic_write_mmprofile(int offset, struct ipanic_header *hdr) { int rc = 0; unsigned int index = 0; unsigned int pbuf = 0; unsigned int bufsize = 0; unsigned int mmprofile_dump_size = 0; offset = ALIGN(offset, EMMC_BLOCK_SIZE); hdr->mmprofile_offset = offset; #ifdef MTK_MMPROFILE_SUPPORT mmprofile_dump_size = MMProfileGetDumpSize(); if (mmprofile_dump_size == 0 || mmprofile_dump_size > IPANIC_OOPS_MMPROFILE_LENGTH_LIMIT) { xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: ignore INVALID MMProfile dump size 0x%x", mmprofile_dump_size); return; } do { MMProfileGetDumpBuffer(index, &pbuf, &bufsize); if (bufsize == 0) { hdr->mmprofile_length = index; break; } index += bufsize; rc = emmc_ipanic_write((char*)pbuf, offset, bufsize); if (rc < 0) { xlog_printk(ANDROID_LOG_ERROR, IPANIC_LOG_TAG, "%s: Error writing MMProfile to emmc! (%d)\n", __func__, rc); hdr->mmprofile_length = 0; } else { offset += rc; } } while(rc <= IPANIC_OOPS_MMPROFILE_LENGTH_LIMIT); #else //MTK_MMPROFILE_SUPPORT disabled, no mmprofile dumped. hdr->mmprofile_length = 0; #endif }
static void __mrdump_mini_core(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg, va_list ap) { int i; unsigned long reg, start, end, size; loff_t offset = 0; struct mrdump_mini_header *hdr = (struct mrdump_mini_header *)mrdump_mini_buf; char *buf = mrdump_mini_buf + MRDUMP_MINI_HEADER_SIZE; if (!msdc_init_panic(DUMP_INTO_BOOT_CARD_IPANIC)) { /* ipanic init fail */ return; } #ifdef DUMMY /* * test code - write dummy data to ipanic partition */ memset(mrdump_mini_buf, 0x3e, MRDUMP_MINI_BUF_SIZE); if (emmc_ipanic_write(mrdump_mini_buf, IPANIC_MRDUMP_OFFSET, MRDUMP_MINI_BUF_SIZE)) { printk(KERN_ALERT"card_dump_func_write failed (%d)\n", i); } else { printk(KERN_ALERT"card_dump_func_write ok, (%d)\n", i); } #else memset(mrdump_mini_buf, 0x0, MRDUMP_MINI_BUF_SIZE); if (sizeof(struct mrdump_mini_header) > MRDUMP_MINI_HEADER_SIZE) { /* mrdump_mini_header is too large, write 0x0 headers to ipanic */ printk(KERN_ALERT"mrdump_mini_header is too large(%d)\n", sizeof(struct mrdump_mini_header)); offset += MRDUMP_MINI_HEADER_SIZE; goto ipanic_write; } for(i = 0; i < ELF_NGREG; i++) { reg = regs->uregs[i]; hdr->reg_desc[i].reg = reg; if (virt_addr_valid(reg)) { /* * ASSUMPION: memory is always in normal zone. * 1) dump at most 32KB around valid kaddr */ /* align start address to PAGE_SIZE for gdb */ start = round_down((reg - SZ_16K), PAGE_SIZE); end = start + SZ_32K; start = clamp(start, (unsigned long)PAGE_OFFSET, (unsigned long)high_memory); end = clamp(end, (unsigned long)PAGE_OFFSET, (unsigned long)high_memory) - 1; hdr->reg_desc[i].kstart = start; hdr->reg_desc[i].kend = end; hdr->reg_desc[i].offset = offset; hdr->reg_desc[i].valid = 1; size = end - start + 1; memcpy(buf + offset, (void*)start, size); offset += size; } else { hdr->reg_desc[i].kstart = 0; hdr->reg_desc[i].kend = 0; hdr->reg_desc[i].offset = 0; hdr->reg_desc[i].valid = 0; } } ipanic_write: if (emmc_ipanic_write(mrdump_mini_buf, IPANIC_MRDUMP_OFFSET, ALIGN(offset, SZ_512))) { printk(KERN_ALERT"card_dump_func_write failed (%d), size: 0x%llx\n", i, (unsigned long long)offset); } else { printk(KERN_ALERT"card_dump_func_write ok (%d), size: 0x%llx\n", i, (unsigned long long)offset); } #endif }