18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2006-2008, IBM Corporation.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#undef DEBUG
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/types.h>
98c2ecf20Sopenharmony_ci#include <linux/kernel.h>
108c2ecf20Sopenharmony_ci#include <linux/slab.h>
118c2ecf20Sopenharmony_ci#include <linux/smp.h>
128c2ecf20Sopenharmony_ci#include <linux/reboot.h>
138c2ecf20Sopenharmony_ci#include <linux/kexec.h>
148c2ecf20Sopenharmony_ci#include <linux/crash_dump.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <asm/kexec.h>
178c2ecf20Sopenharmony_ci#include <asm/reg.h>
188c2ecf20Sopenharmony_ci#include <asm/io.h>
198c2ecf20Sopenharmony_ci#include <asm/prom.h>
208c2ecf20Sopenharmony_ci#include <asm/machdep.h>
218c2ecf20Sopenharmony_ci#include <asm/rtas.h>
228c2ecf20Sopenharmony_ci#include <asm/cell-regs.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#include "ras.h"
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic void dump_fir(int cpu)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu);
308c2ecf20Sopenharmony_ci	struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu);
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	if (pregs == NULL)
338c2ecf20Sopenharmony_ci		return;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/* Todo: do some nicer parsing of bits and based on them go down
368c2ecf20Sopenharmony_ci	 * to other sub-units FIRs and not only IIC
378c2ecf20Sopenharmony_ci	 */
388c2ecf20Sopenharmony_ci	printk(KERN_ERR "Global Checkstop FIR    : 0x%016llx\n",
398c2ecf20Sopenharmony_ci	       in_be64(&pregs->checkstop_fir));
408c2ecf20Sopenharmony_ci	printk(KERN_ERR "Global Recoverable FIR  : 0x%016llx\n",
418c2ecf20Sopenharmony_ci	       in_be64(&pregs->checkstop_fir));
428c2ecf20Sopenharmony_ci	printk(KERN_ERR "Global MachineCheck FIR : 0x%016llx\n",
438c2ecf20Sopenharmony_ci	       in_be64(&pregs->spec_att_mchk_fir));
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	if (iregs == NULL)
468c2ecf20Sopenharmony_ci		return;
478c2ecf20Sopenharmony_ci	printk(KERN_ERR "IOC FIR                 : 0x%016llx\n",
488c2ecf20Sopenharmony_ci	       in_be64(&iregs->ioc_fir));
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid cbe_system_error_exception(struct pt_regs *regs)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	int cpu = smp_processor_id();
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu);
578c2ecf20Sopenharmony_ci	dump_fir(cpu);
588c2ecf20Sopenharmony_ci	dump_stack();
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_civoid cbe_maintenance_exception(struct pt_regs *regs)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	int cpu = smp_processor_id();
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/*
668c2ecf20Sopenharmony_ci	 * Nothing implemented for the maintenance interrupt at this point
678c2ecf20Sopenharmony_ci	 */
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu);
708c2ecf20Sopenharmony_ci	dump_stack();
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_civoid cbe_thermal_exception(struct pt_regs *regs)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	int cpu = smp_processor_id();
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	/*
788c2ecf20Sopenharmony_ci	 * Nothing implemented for the thermal interrupt at this point
798c2ecf20Sopenharmony_ci	 */
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu);
828c2ecf20Sopenharmony_ci	dump_stack();
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic int cbe_machine_check_handler(struct pt_regs *regs)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci	int cpu = smp_processor_id();
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu);
908c2ecf20Sopenharmony_ci	dump_fir(cpu);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	/* No recovery from this code now, lets continue */
938c2ecf20Sopenharmony_ci	return 0;
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistruct ptcal_area {
978c2ecf20Sopenharmony_ci	struct list_head list;
988c2ecf20Sopenharmony_ci	int nid;
998c2ecf20Sopenharmony_ci	int order;
1008c2ecf20Sopenharmony_ci	struct page *pages;
1018c2ecf20Sopenharmony_ci};
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic LIST_HEAD(ptcal_list);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic int ptcal_start_tok, ptcal_stop_tok;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistatic int __init cbe_ptcal_enable_on_node(int nid, int order)
1088c2ecf20Sopenharmony_ci{
1098c2ecf20Sopenharmony_ci	struct ptcal_area *area;
1108c2ecf20Sopenharmony_ci	int ret = -ENOMEM;
1118c2ecf20Sopenharmony_ci	unsigned long addr;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	if (is_kdump_kernel())
1148c2ecf20Sopenharmony_ci		rtas_call(ptcal_stop_tok, 1, 1, NULL, nid);
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	area = kmalloc(sizeof(*area), GFP_KERNEL);
1178c2ecf20Sopenharmony_ci	if (!area)
1188c2ecf20Sopenharmony_ci		goto out_err;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	area->nid = nid;
1218c2ecf20Sopenharmony_ci	area->order = order;
1228c2ecf20Sopenharmony_ci	area->pages = __alloc_pages_node(area->nid,
1238c2ecf20Sopenharmony_ci						GFP_KERNEL|__GFP_THISNODE,
1248c2ecf20Sopenharmony_ci						area->order);
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	if (!area->pages) {
1278c2ecf20Sopenharmony_ci		printk(KERN_WARNING "%s: no page on node %d\n",
1288c2ecf20Sopenharmony_ci			__func__, area->nid);
1298c2ecf20Sopenharmony_ci		goto out_free_area;
1308c2ecf20Sopenharmony_ci	}
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	/*
1338c2ecf20Sopenharmony_ci	 * We move the ptcal area to the middle of the allocated
1348c2ecf20Sopenharmony_ci	 * page, in order to avoid prefetches in memcpy and similar
1358c2ecf20Sopenharmony_ci	 * functions stepping on it.
1368c2ecf20Sopenharmony_ci	 */
1378c2ecf20Sopenharmony_ci	addr = __pa(page_address(area->pages)) + (PAGE_SIZE >> 1);
1388c2ecf20Sopenharmony_ci	printk(KERN_DEBUG "%s: enabling PTCAL on node %d address=0x%016lx\n",
1398c2ecf20Sopenharmony_ci			__func__, area->nid, addr);
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	ret = -EIO;
1428c2ecf20Sopenharmony_ci	if (rtas_call(ptcal_start_tok, 3, 1, NULL, area->nid,
1438c2ecf20Sopenharmony_ci				(unsigned int)(addr >> 32),
1448c2ecf20Sopenharmony_ci				(unsigned int)(addr & 0xffffffff))) {
1458c2ecf20Sopenharmony_ci		printk(KERN_ERR "%s: error enabling PTCAL on node %d!\n",
1468c2ecf20Sopenharmony_ci				__func__, nid);
1478c2ecf20Sopenharmony_ci		goto out_free_pages;
1488c2ecf20Sopenharmony_ci	}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	list_add(&area->list, &ptcal_list);
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	return 0;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ciout_free_pages:
1558c2ecf20Sopenharmony_ci	__free_pages(area->pages, area->order);
1568c2ecf20Sopenharmony_ciout_free_area:
1578c2ecf20Sopenharmony_ci	kfree(area);
1588c2ecf20Sopenharmony_ciout_err:
1598c2ecf20Sopenharmony_ci	return ret;
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic int __init cbe_ptcal_enable(void)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	const u32 *size;
1658c2ecf20Sopenharmony_ci	struct device_node *np;
1668c2ecf20Sopenharmony_ci	int order, found_mic = 0;
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	np = of_find_node_by_path("/rtas");
1698c2ecf20Sopenharmony_ci	if (!np)
1708c2ecf20Sopenharmony_ci		return -ENODEV;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	size = of_get_property(np, "ibm,cbe-ptcal-size", NULL);
1738c2ecf20Sopenharmony_ci	if (!size) {
1748c2ecf20Sopenharmony_ci		of_node_put(np);
1758c2ecf20Sopenharmony_ci		return -ENODEV;
1768c2ecf20Sopenharmony_ci	}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	pr_debug("%s: enabling PTCAL, size = 0x%x\n", __func__, *size);
1798c2ecf20Sopenharmony_ci	order = get_order(*size);
1808c2ecf20Sopenharmony_ci	of_node_put(np);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	/* support for malta device trees, with be@/mic@ nodes */
1838c2ecf20Sopenharmony_ci	for_each_node_by_type(np, "mic-tm") {
1848c2ecf20Sopenharmony_ci		cbe_ptcal_enable_on_node(of_node_to_nid(np), order);
1858c2ecf20Sopenharmony_ci		found_mic = 1;
1868c2ecf20Sopenharmony_ci	}
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	if (found_mic)
1898c2ecf20Sopenharmony_ci		return 0;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	/* support for older device tree - use cpu nodes */
1928c2ecf20Sopenharmony_ci	for_each_node_by_type(np, "cpu") {
1938c2ecf20Sopenharmony_ci		const u32 *nid = of_get_property(np, "node-id", NULL);
1948c2ecf20Sopenharmony_ci		if (!nid) {
1958c2ecf20Sopenharmony_ci			printk(KERN_ERR "%s: node %pOF is missing node-id?\n",
1968c2ecf20Sopenharmony_ci					__func__, np);
1978c2ecf20Sopenharmony_ci			continue;
1988c2ecf20Sopenharmony_ci		}
1998c2ecf20Sopenharmony_ci		cbe_ptcal_enable_on_node(*nid, order);
2008c2ecf20Sopenharmony_ci		found_mic = 1;
2018c2ecf20Sopenharmony_ci	}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	return found_mic ? 0 : -ENODEV;
2048c2ecf20Sopenharmony_ci}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_cistatic int cbe_ptcal_disable(void)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	struct ptcal_area *area, *tmp;
2098c2ecf20Sopenharmony_ci	int ret = 0;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	pr_debug("%s: disabling PTCAL\n", __func__);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	list_for_each_entry_safe(area, tmp, &ptcal_list, list) {
2148c2ecf20Sopenharmony_ci		/* disable ptcal on this node */
2158c2ecf20Sopenharmony_ci		if (rtas_call(ptcal_stop_tok, 1, 1, NULL, area->nid)) {
2168c2ecf20Sopenharmony_ci			printk(KERN_ERR "%s: error disabling PTCAL "
2178c2ecf20Sopenharmony_ci					"on node %d!\n", __func__,
2188c2ecf20Sopenharmony_ci					area->nid);
2198c2ecf20Sopenharmony_ci			ret = -EIO;
2208c2ecf20Sopenharmony_ci			continue;
2218c2ecf20Sopenharmony_ci		}
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci		/* ensure we can access the PTCAL area */
2248c2ecf20Sopenharmony_ci		memset(page_address(area->pages), 0,
2258c2ecf20Sopenharmony_ci				1 << (area->order + PAGE_SHIFT));
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci		/* clean up */
2288c2ecf20Sopenharmony_ci		list_del(&area->list);
2298c2ecf20Sopenharmony_ci		__free_pages(area->pages, area->order);
2308c2ecf20Sopenharmony_ci		kfree(area);
2318c2ecf20Sopenharmony_ci	}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	return ret;
2348c2ecf20Sopenharmony_ci}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_cistatic int cbe_ptcal_notify_reboot(struct notifier_block *nb,
2378c2ecf20Sopenharmony_ci		unsigned long code, void *data)
2388c2ecf20Sopenharmony_ci{
2398c2ecf20Sopenharmony_ci	return cbe_ptcal_disable();
2408c2ecf20Sopenharmony_ci}
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_cistatic void cbe_ptcal_crash_shutdown(void)
2438c2ecf20Sopenharmony_ci{
2448c2ecf20Sopenharmony_ci	cbe_ptcal_disable();
2458c2ecf20Sopenharmony_ci}
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_cistatic struct notifier_block cbe_ptcal_reboot_notifier = {
2488c2ecf20Sopenharmony_ci	.notifier_call = cbe_ptcal_notify_reboot
2498c2ecf20Sopenharmony_ci};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_IBM_CELL_RESETBUTTON
2528c2ecf20Sopenharmony_cistatic int sysreset_hack;
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_cistatic int __init cbe_sysreset_init(void)
2558c2ecf20Sopenharmony_ci{
2568c2ecf20Sopenharmony_ci	struct cbe_pmd_regs __iomem *regs;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	sysreset_hack = of_machine_is_compatible("IBM,CBPLUS-1.0");
2598c2ecf20Sopenharmony_ci	if (!sysreset_hack)
2608c2ecf20Sopenharmony_ci		return 0;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	regs = cbe_get_cpu_pmd_regs(0);
2638c2ecf20Sopenharmony_ci	if (!regs)
2648c2ecf20Sopenharmony_ci		return 0;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	/* Enable JTAG system-reset hack */
2678c2ecf20Sopenharmony_ci	out_be32(&regs->fir_mode_reg,
2688c2ecf20Sopenharmony_ci		in_be32(&regs->fir_mode_reg) |
2698c2ecf20Sopenharmony_ci		CBE_PMD_FIR_MODE_M8);
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	return 0;
2728c2ecf20Sopenharmony_ci}
2738c2ecf20Sopenharmony_cidevice_initcall(cbe_sysreset_init);
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ciint cbe_sysreset_hack(void)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	struct cbe_pmd_regs __iomem *regs;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	/*
2808c2ecf20Sopenharmony_ci	 * The BMC can inject user triggered system reset exceptions,
2818c2ecf20Sopenharmony_ci	 * but cannot set the system reset reason in srr1,
2828c2ecf20Sopenharmony_ci	 * so check an extra register here.
2838c2ecf20Sopenharmony_ci	 */
2848c2ecf20Sopenharmony_ci	if (sysreset_hack && (smp_processor_id() == 0)) {
2858c2ecf20Sopenharmony_ci		regs = cbe_get_cpu_pmd_regs(0);
2868c2ecf20Sopenharmony_ci		if (!regs)
2878c2ecf20Sopenharmony_ci			return 0;
2888c2ecf20Sopenharmony_ci		if (in_be64(&regs->ras_esc_0) & 0x0000ffff) {
2898c2ecf20Sopenharmony_ci			out_be64(&regs->ras_esc_0, 0);
2908c2ecf20Sopenharmony_ci			return 0;
2918c2ecf20Sopenharmony_ci		}
2928c2ecf20Sopenharmony_ci	}
2938c2ecf20Sopenharmony_ci	return 1;
2948c2ecf20Sopenharmony_ci}
2958c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_IBM_CELL_RESETBUTTON */
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_cistatic int __init cbe_ptcal_init(void)
2988c2ecf20Sopenharmony_ci{
2998c2ecf20Sopenharmony_ci	int ret;
3008c2ecf20Sopenharmony_ci	ptcal_start_tok = rtas_token("ibm,cbe-start-ptcal");
3018c2ecf20Sopenharmony_ci	ptcal_stop_tok = rtas_token("ibm,cbe-stop-ptcal");
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	if (ptcal_start_tok == RTAS_UNKNOWN_SERVICE
3048c2ecf20Sopenharmony_ci			|| ptcal_stop_tok == RTAS_UNKNOWN_SERVICE)
3058c2ecf20Sopenharmony_ci		return -ENODEV;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	ret = register_reboot_notifier(&cbe_ptcal_reboot_notifier);
3088c2ecf20Sopenharmony_ci	if (ret)
3098c2ecf20Sopenharmony_ci		goto out1;
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci	ret = crash_shutdown_register(&cbe_ptcal_crash_shutdown);
3128c2ecf20Sopenharmony_ci	if (ret)
3138c2ecf20Sopenharmony_ci		goto out2;
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	return cbe_ptcal_enable();
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ciout2:
3188c2ecf20Sopenharmony_ci	unregister_reboot_notifier(&cbe_ptcal_reboot_notifier);
3198c2ecf20Sopenharmony_ciout1:
3208c2ecf20Sopenharmony_ci	printk(KERN_ERR "Can't disable PTCAL, so not enabling\n");
3218c2ecf20Sopenharmony_ci	return ret;
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ciarch_initcall(cbe_ptcal_init);
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_civoid __init cbe_ras_init(void)
3278c2ecf20Sopenharmony_ci{
3288c2ecf20Sopenharmony_ci	unsigned long hid0;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	/*
3318c2ecf20Sopenharmony_ci	 * Enable System Error & thermal interrupts and wakeup conditions
3328c2ecf20Sopenharmony_ci	 */
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	hid0 = mfspr(SPRN_HID0);
3358c2ecf20Sopenharmony_ci	hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP |
3368c2ecf20Sopenharmony_ci		HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP;
3378c2ecf20Sopenharmony_ci	mtspr(SPRN_HID0, hid0);
3388c2ecf20Sopenharmony_ci	mb();
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	/*
3418c2ecf20Sopenharmony_ci	 * Install machine check handler. Leave setting of precise mode to
3428c2ecf20Sopenharmony_ci	 * what the firmware did for now
3438c2ecf20Sopenharmony_ci	 */
3448c2ecf20Sopenharmony_ci	ppc_md.machine_check_exception = cbe_machine_check_handler;
3458c2ecf20Sopenharmony_ci	mb();
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	/*
3488c2ecf20Sopenharmony_ci	 * For now, we assume that IOC_FIR is already set to forward some
3498c2ecf20Sopenharmony_ci	 * error conditions to the System Error handler. If that is not true
3508c2ecf20Sopenharmony_ci	 * then it will have to be fixed up here.
3518c2ecf20Sopenharmony_ci	 */
3528c2ecf20Sopenharmony_ci}
353