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
}
Beispiel #5
0
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 
}