Пример #1
0
static int __init memdump_init(void)
{
	struct memdump *mem_info;
	void __iomem *memdump_head;

	if (!check_himntn(HIMNTN_GOBAL_RESETLOG)) {
		return 0;
	}
	if (g_memdump_addr == 0)
		return 0;

	/* to free the reserve mem of memdump */
	if (NULL == balong_create_memory_proc_entry("dump_end", S_IRUGO,
					    &dump_end_proc_fops, NULL)) {
		return 0;
	}
	memdump_head = memdump_remap(g_memdump_addr, PAGE_SIZE);
	mem_info = (struct memdump *)memdump_head;

	while (mem_info->name[0] != 0) {
		pr_err("%s,name:%s\n", __func__, mem_info->name);
		pr_err("%s:base:0x%lx, size:0x%lx\n", __func__,
		       mem_info->base, mem_info->size);
		create_dump_phy_mem_proc_file(mem_info->name, mem_info->base,
					      (size_t)mem_info->size);
		mem_info++;
	}

	memdump_unmap(memdump_head);

	return 0;
}
Пример #2
0
void ddrc_events_handler()
{
    int portnum = 1;
    int end_port = 8;
    int base_addr = (int)REG_BASE_DDRC_SEC0_VIRT;
    int first_invader;
    unsigned int fail_addr;
    unsigned int masterval = 0;
    unsigned int accesstype = 0;
    unsigned int ddrc_rint = 0;
    unsigned int ddrc_sec_event = 0;
    struct ddrc_info_stru *p_ddrc_info = DDRC_INFO_SAVE_ADDR;

    p_ddrc_info->count++;

    p_ddrc_info->ddrc_intmask = readl(SOC_MDDRC_DMC_DDRC_INTMSK_ADDR(REG_BASE_DDRC_DMC0_VIRT));
    ddrc_rint = (readl(SOC_MDDRC_DMC_DDRC_RINT_ADDR(REG_BASE_DDRC_DMC0_VIRT)) & DDRC_DMC_ERROR_MASK);
    p_ddrc_info->ddrc_rint = ddrc_rint;
    p_ddrc_info->ddrc_intstat = readl(SOC_MDDRC_DMC_DDRC_INTSTS_ADDR(REG_BASE_DDRC_DMC0_VIRT));


    pr_err("%s:count=%d,ddrc_intmask=0x%x,ddrc_rint=0x%x,ddrc_intstat=0x%x\n",__func__,p_ddrc_info->count, \
           p_ddrc_info->ddrc_intmask,p_ddrc_info->ddrc_rint,p_ddrc_info->ddrc_intstat);

    while (portnum <= end_port) {
        if (*(volatile unsigned int*)(base_addr + 0x10 + 0x400*portnum)) {  /*中断状态有效*/
            fail_addr = *(volatile unsigned int*) (base_addr + 0x20 + 0x400*portnum); /*记录越权地址*/
            masterval = *(volatile unsigned int*) (base_addr + 0x2c + 0x400*portnum); /*越权者*/
            accesstype = *(volatile unsigned int*) (base_addr + 0x28 + 0x400*portnum);/*读/写*/

            dump_error_logger(error_logger, REG_ERROR_LOGGER_0_IOSIZE);
            memcpy(&p_ddrc_info->error_logger_info[0],error_logger,REG_ERROR_LOGGER_0_IOSIZE);

            if (fail_addr < MAX_PROTECT_DDR_24M) {/*platform_ddr_protect_32k 配置为保护32k*/
                first_invader = portnum;
                printk(KERN_ERR "ddr_protect_irq: portnum! (0x%x)\n", portnum);
                dump_error_logger((void *)(base_addr + 0x400*portnum), 0x400);
                memcpy((&p_ddrc_info->ddrc_sec_info[0] + portnum*0x100),(base_addr + 0x400*portnum),0x100);
                ddrc_sec_event++;

            } else {
                printk(KERN_ERR "ddr_protect_irq: invalid! portnum (0x%x),addr(0x%x),master(0x%x), type(0x%x)\n", portnum, fail_addr,masterval,accesstype);
            }

            *(volatile unsigned int*) (base_addr + 0x14 + 0x400*portnum) = 1; /*清除中断和越权失效地址*/
        }
        portnum++;
    }

    if ((ddrc_sec_event || ddrc_rint) && check_himntn(HIMNTN_ACCESS_ERROR_REBOOT)) {
        systemError((int)BSP_MODU_MNTN, (int)EXCH_S_DDRC_SEC, 0, 0, 0);
    }

}
static int hisi_pmic_register_special_ocp(void)
{
    int ret = 0;

    if (!check_himntn(HIMNTN_SD2JTAG) && !check_himntn(HIMNTN_SD2DJTAG)) {
        ret = hisi_pmic_special_ocp_register(SUPPLY_SD, hisi_pmic_sdcard_ocp_handler);
        if (ret) {
            pr_err("[%s]supply_sd register error.\n", __func__);
            return ret;
        }

        ret = hisi_pmic_special_ocp_register(SUPPLY_SD_IO, hisi_pmic_sdcard_ocp_handler);
        if (ret) {
            pr_err("[%s]supply_sd_io register error.\n", __func__);
            return ret;
        }
    }

    return ret;
}
MAILBOX_LOCAL long mailbox_ipc_int_handle(unsigned long int_num)
{
    struct mb_local_cfg         *local_cfg    =  &g_mb_local_cfg_tbl[0];
    struct mb_local_proc        *local_proc   =   MAILBOX_NULL;
    struct mb_local_work        *local_work      =   MAILBOX_NULL;
    unsigned long count = sizeof(g_mailbox_local_proc_tbl)/sizeof(struct mb_local_proc);
    unsigned long proc_id = 0;
    unsigned long channel_id = 0;
    unsigned long is_find = MAILBOX_FALSE;
    unsigned long ret_val = MAILBOX_OK;

    /*找到传入ID对应的邮箱配置*/
    while (MAILBOX_MAILCODE_INVALID != local_cfg->channel_id) {
        /*处理所有挂接到这个中断号的接收邮箱通道*/
        proc_id = local_cfg->property;
        if ((int_num == local_cfg->int_src) && (MAILBOX_SEND 
              != (MAILBOX_PROC_MASK & local_cfg->property))) {
            channel_id = local_cfg->channel_id;

            if (check_himntn(HIMNTN_PRINTK_WHO_WAKEUP_ACPU)) {
                printk(KERN_INFO "%s:%d:mailbox channel_id:[%ld]", __func__, __LINE__, channel_id);
            }

            local_proc   =  &g_mailbox_local_proc_tbl[0];
            count          =   sizeof(g_mailbox_local_proc_tbl)/sizeof(struct mb_local_proc);
            while (count) {
                /*找到此邮箱通道对应的任务信息*/
                if (proc_id == local_proc->proc_id) {
                    local_work = local_proc->work_list;
                    is_find = mailbox_ipc_process( local_work,
                                                 local_proc,
                                                 channel_id,
                                                 proc_id);
                    break;
                }
                count--;
                local_proc++;
            }

            if (0 == count) {
                 ret_val = mailbox_logerro_p1(MAILBOX_ERR_LINUX_MAIL_TASK_NOT_FIND, channel_id);
            }
        }
        local_cfg++;
    }

    if (MAILBOX_TRUE != is_find) {
         ret_val = mailbox_logerro_p1(MAILBOX_ERR_LINUX_MAIL_INT_NOT_FIND, channel_id);
    }

    return ret_val;
}
/*reset system after saving log*/
void check_doreset_for_noc(void)
{
    if (check_himntn(HIMNTN_NOC_ERR_LOGGER_RESET))
    {
        switch (s_noc_err_init_type)
        {
        case NOC_INIT_MODEM:
            systemError((int)BSP_MODU_MNTN, EXCH_S_NOC, 0, 0, 0);
            break;
        case NOC_INIT_HIFI:
        /*    systemError((int)BSP_MODU_MNTN, EXCH_S_NOC, 0, 0, 0);*/
            break;
        default:
            break;
        }
    }
}
MAILBOX_EXTERN void mailbox_assert(unsigned long ErroNo)
{
#ifndef _DRV_LLT_

    /*产品方案*/
    if(0 == check_himntn(HIMNTN_MBFULL_ASSERT))
    {
        systemError(BSP_MODU_MAILBOX, ErroNo, 0, 0, 0);
    }
    else
    {
        while (1)
        {
            mailbox_out(("mb Assert!\n"));
            msleep(1000); 
        }
    }

#endif
}
static irqreturn_t hisi_powerkey_handler(int irq, void *data)
{
	struct hisi_powerkey_info *info = (struct hisi_powerkey_info *)data;

	wake_lock_timeout(&info->pwr_wake_lock, HZ);

	if (info->irq[0] == irq) {
			pr_info("[%s]response press interrupt!\n", __FUNCTION__);
			power_key_ps=true;

#if defined (CONFIG_HUAWEI_DSM)
			powerkey_press_count++;
                    if ((jiffies - powerkey_last_press_time) < msecs_to_jiffies(PRESS_KEY_INTERVAL)) {
                        if (!dsm_client_ocuppy(power_key_dclient)) {
                            dsm_client_record(power_key_dclient, "power key trigger on the abnormal style.\n");
                            dsm_client_notify(power_key_dclient, DSM_POWER_KEY_ERROR_NO);
                        }
                    }
                     powerkey_last_press_time = jiffies;
#endif
                    /* modify by songliangliang for dmd_log> */
			#if defined (CONFIG_FB_HI6220_CLCD)
			lcd_dcm_pwr_add_timer();
			#endif
			input_report_key(info->idev, KEY_POWER, POWER_KEY_PRESS);
			input_sync(info->idev);
	} else if (info->irq[1] == irq) {
			pr_info("[%s]response release interrupt!\n", __FUNCTION__);
			#if defined(CONFIG_HISILICON_PLATFORM_MAINTAIN)
                        #ifdef CONFIG_ARCH_HI6XXX
			if (check_himntn(HIMNTN_PRESS_KEY_TO_FASTBOOT)) {
				if ((VOL_UPDOWN_PRESS & gpio_key_vol_updown_press_get()) == VOL_UPDOWN_PRESS) {
					gpio_key_vol_updown_press_set_zero();
					if(is_gpio_key_vol_updown_pressed()) {
						systemError(0x25, EXCH_S_LOGDUMP, 0,0,0);
					}
				}
			}
			#elif defined(CONFIG_HISI_3635)
				if(is_fastboot_dumpmem_enable())
					if ((VOL_UPDOWN_PRESS & gpio_key_vol_updown_press_get()) == VOL_UPDOWN_PRESS) {
						gpio_key_vol_updown_press_set_zero();
						if(is_gpio_key_vol_updown_pressed()) {
							pr_info("[%s]Powerkey+VolUp_key+VolDn_key\n", __FUNCTION__);
							#ifdef CONFIG_HISI_REBOOT_TYPE
							set_watchdog_resetflag();
							#endif
							emergency_restart();
					}
				}
 			#endif
                        #endif
			input_report_key(info->idev, KEY_POWER, POWER_KEY_RELEASE);
			input_sync(info->idev);
	} else if (info->irq[2] == irq) {
			pr_info("[%s]response long press 1s interrupt!\n", __FUNCTION__);
			input_report_key(info->idev, KEY_POWER, POWER_KEY_PRESS);
			input_sync(info->idev);
	} else if (irq == info->irq[3]) {
		pr_info("[%s]response long press 8s interrupt!\n", __FUNCTION__);
	} else if (irq == info->irq[4]) {
		pr_info("[%s]response long press 10s interrupt!\n", __FUNCTION__);
	} else {
			pr_err("[%s]invalid irq %d!\n", __FUNCTION__, irq);
	}

	return IRQ_HANDLED;
}
int __init rdr_lpm3_init(void)
{
	struct rdr_module_ops_pub s_module_ops;
	struct rdr_exception_info_s einfo;
	s32 ret = -1;
	static u32 msg[4] = {0};
	pr_err("enter %s\n", __func__);


	/*counter_base = (char*)ioremap((phys_addr_t)SOC_ACPU_SYS_CNT_BASE_ADDR,0x1000);*/
	sctrl_base = (char *)ioremap((phys_addr_t)SOC_ACPU_SCTRL_BASE_ADDR, 0x1000);

	/*pr_err("counter_base: %p, sctrl_base: %p\n", counter_base, sctrl_base);*/
	pr_err("sctrl_base: %p\n", sctrl_base);


	ret = request_irq(M3_WDT_TIMEOUT_IRQ_NUM, m3_wdt_irq_handler, 0, "m3 wdt handler", NULL);
	if (ret != 0) {
		pr_err("request_irq m3_wdt_irq_handler failed! return 0x%x\n", ret);
		/*return ret;*/
	}


	rdr_ipc_block.next = NULL;
	rdr_ipc_block.notifier_call = rdr_lpm3_msg_handler;
	ret = RPROC_MONITOR_REGISTER(HISI_RPROC_RDR_MBX1, &rdr_ipc_block);
	if (ret != 0) {
		pr_info("%s:RPROC_MONITOR_REGISTER failed", __func__);
		return ret;
	}

	sema_init(&rdr_lpm3_sem, 0);
	if (!kthread_run(rdr_lpm3_thread_body, NULL, "rdr_lpm3_thread")) {
		pr_err("%s: create thread rdr_main_thread faild.\n", __func__);
		return -1;
	}

#if 0
	ret = request_irq(AP_WDT_TIMEOUT_IRQ_NUM, ap_wdt_irq_handler, 0, "ap wdt handler", NULL);
	if (ret != 0) {
		pr_err("request_irq ap_wdt_irq_handler failed! return 0x%x\n", ret);
		return ret;
	}
#endif

	s_module_ops.ops_dump = fn_dump;
	s_module_ops.ops_reset = fn_reset;
	ret = rdr_register_module_ops(current_core_id, &s_module_ops, &current_info);
	if (ret != 0) {
		pr_err("rdr_register_module_ops failed! return 0x%x\n", ret);
		return ret;
	}


	memset(&einfo, 0, sizeof(struct rdr_exception_info_s));
	einfo.e_modid = M3_WDT_TIMEOUT;
	einfo.e_modid_end = M3_WDT_TIMEOUT;
	einfo.e_process_priority = RDR_ERR;
	einfo.e_reboot_priority = RDR_REBOOT_WAIT;
	einfo.e_notify_core_mask = RDR_AP | RDR_LPM3;
	einfo.e_reset_core_mask = RDR_LPM3;
	einfo.e_reentrant = RDR_REENTRANT_DISALLOW;
	einfo.e_exce_type = LPM3_S_EXCEPTION;
	einfo.e_from_core = RDR_LPM3;
	memcpy(einfo.e_from_module, "RDR M3 WDT", sizeof("RDR M3 WDT"));
	memcpy(einfo.e_desc, "RDR M3 WDT",
			sizeof("RDR M3 WDT"));
	ret = rdr_register_exception(&einfo);


	rdr_lpm3_buf_addr = address_map(current_info.log_addr);
	rdr_lpm3_buf_len = current_info.log_len;

	g_lpmcu_rdr_ddr_addr = (char *)hisi_bbox_map((phys_addr_t)current_info.log_addr, current_info.log_len);

	if (g_lpmcu_rdr_ddr_addr)
		memset(g_lpmcu_rdr_ddr_addr, 0 , rdr_lpm3_buf_len);

	msg[0] = PSCI_MSG_TYPE_M3_RDRBUF;
	msg[1] = rdr_lpm3_buf_addr;
	msg[2] = rdr_lpm3_buf_addr >> 32;
	msg[3] = rdr_lpm3_buf_len;

	ret = RPROC_ASYNC_SEND(HISI_RPROC_LPM3_MBX17, (mbox_msg_t *)msg, 4);

	if (ret != 0) {
		pr_err("RPROC_ASYNC_SEND failed! return 0x%x, &msg:(%p)\n", ret, msg);
		/*return ret;*/
	}
	pr_err("%s: (ap)->(lpm3) ipc send (0x%x 0x%x 0x%x 0x%x)!\n", __func__, msg[0], msg[1], msg[2], msg[3]);

	(void)rdr_lpm3_reset_off(LPMCU_RESET_OFF_MODID_PANIC, check_himntn(HIMNTN_LPM3_PANIC_INTO_LOOP));

	return ret;
}
static int __init fastbootlog_dump_init(void)
{
	char *fastbootlog_buff;
	struct fastbootlog_head *head;
	char *lastlog_start;
	unsigned int lastlog_size;
	char *log_start;
	unsigned int log_size;
	int use_ioremap = 0;
	int need_dump_whole = 0;
	unsigned tmp_len;
	int ret = 0;

	if (!check_himntn(HIMNTN_GOBAL_RESETLOG)) {
		return ret;
	}

	if (pfn_valid(__phys_to_pfn(FASTBOOT_DUMP_LOG_ADDR))) {
		fastbootlog_buff = phys_to_virt(FASTBOOT_DUMP_LOG_ADDR);
	} else {
		use_ioremap = 1;
		fastbootlog_buff =
		    ioremap_wc(FASTBOOT_DUMP_LOG_ADDR, FASTBOOT_DUMP_LOG_SIZE);
	}
	if (!fastbootlog_buff) {
		printk(KERN_ERR
		       "%s: fail to get the virtual address of fastbootlog\n",
		       __func__);
		return -1;
	}

	head = (struct fastbootlog_head *)fastbootlog_buff;
	check_fastbootlog_head(head, &need_dump_whole);
	if (need_dump_whole) {
		head->lastlog_start = 0;
		head->lastlog_offset = 0;
		head->log_start = 0;
		head->log_offset = FASTBOOT_DUMP_LOG_SIZE;
	}

	lastlog_start = fastbootlog_buff + head->lastlog_start;
	if (head->lastlog_offset < head->lastlog_start) {
		tmp_len = FASTBOOT_DUMP_LOG_SIZE - head->lastlog_start;
		lastlog_size = tmp_len + head->lastlog_offset -
		    sizeof(struct fastbootlog_head);

		s_last_fastbootlog_buff = vmalloc(lastlog_size);
		if (!s_last_fastbootlog_buff) {
			printk(KERN_ERR
			       "%s: fail to vmalloc %#x bytes s_last_fastbootlog_buff\n",
			       __func__, lastlog_size);
			ret = -1;
			goto out;
		}
		memcpy(s_last_fastbootlog_buff, lastlog_start, tmp_len);
		lastlog_start = fastbootlog_buff + sizeof(struct fastbootlog_head);
		memcpy(s_last_fastbootlog_buff + tmp_len, lastlog_start,
		       lastlog_size - tmp_len);
		s_last_fastbootlog_size = lastlog_size;
	} else {
		lastlog_size = head->lastlog_offset - head->lastlog_start;
		if (lastlog_size > 0) {
			s_last_fastbootlog_buff = vmalloc(lastlog_size);
			if (!s_last_fastbootlog_buff) {
				printk(KERN_ERR
				       "%s: fail to vmalloc %#x bytes s_last_fastbootlog_buff\n",
				       __func__, lastlog_size);
				ret = -1;
				goto out;
			}
			memcpy(s_last_fastbootlog_buff, lastlog_start,
			       lastlog_size);
			s_last_fastbootlog_size = lastlog_size;
		}
	}

	log_start = fastbootlog_buff + head->log_start;
	if (head->log_offset < head->log_start) {
		tmp_len = FASTBOOT_DUMP_LOG_SIZE - head->log_start;
		log_size = tmp_len + head->log_offset -
		    sizeof(struct fastbootlog_head);

		s_fastbootlog_buff = vmalloc(log_size);
		if (!s_fastbootlog_buff) {
			printk(KERN_ERR
			       "%s: fail to vmalloc %#x bytes s_fastbootlog_buff\n",
			       __func__, log_size);
			ret = -1;
			goto out;
		}
		memcpy(s_fastbootlog_buff, log_start, tmp_len);
		log_start = fastbootlog_buff + sizeof(struct fastbootlog_head);
		memcpy(s_fastbootlog_buff + tmp_len, log_start,
		       log_size - tmp_len);
		s_fastbootlog_size = log_size;
	} else {
		log_size = head->log_offset - head->log_start;
		if (log_size > 0) {
			s_fastbootlog_buff = vmalloc(log_size);
			if (!s_fastbootlog_buff) {
				printk(KERN_ERR
				       "%s: fail to vmalloc %#x bytes s_fastbootlog_buff\n",
				       __func__, log_size);
				ret = -1;
				goto out;
			}
			memcpy(s_fastbootlog_buff, log_start, log_size);
			s_fastbootlog_size = log_size;
		}
	}

out:
	if (use_ioremap && fastbootlog_buff) {
		iounmap(fastbootlog_buff);
	}

	if (s_last_fastbootlog_buff) {
		bootloader_logger_dump(s_last_fastbootlog_buff,
				       s_last_fastbootlog_size, "last");
		balong_create_log_proc_entry("last_fastboot_log",
					     S_IRUSR | S_IRGRP,
					     &last_fastbootlog_dump_file_fops,
					     NULL);
	}
	if (s_fastbootlog_buff) {
		bootloader_logger_dump(s_fastbootlog_buff, s_fastbootlog_size,
				       "current");
		balong_create_log_proc_entry("fastboot_log", S_IRUSR | S_IRGRP,
					     &fastbootlog_dump_file_fops, NULL);
	}

	return ret;
}