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; }
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, ¤t_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; }