4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Implements DSP MMU fault handling functions.
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 /* ----------------------------------- DSP/BIOS Bridge */
20 #include <dspbridge/std.h>
21 #include <dspbridge/dbdefs.h>
23 /* ----------------------------------- Trace & Debug */
24 #include <dspbridge/host_os.h>
25 #include <dspbridge/dbc.h>
27 /* ----------------------------------- OS Adaptation Layer */
28 #include <dspbridge/drv.h>
30 /* ----------------------------------- Link Driver */
31 #include <dspbridge/dspdeh.h>
33 /* ------------------------------------ Hardware Abstraction Layer */
37 /* ----------------------------------- This */
39 #include <dspbridge/cfg.h>
41 #include "mmu_fault.h"
43 static u32 dmmu_event_mask
;
46 static bool mmu_check_if_fault(struct bridge_dev_context
*dev_context
);
49 * ======== mmu_fault_dpc ========
50 * Deferred procedure call to handle DSP MMU fault.
52 void mmu_fault_dpc(IN
unsigned long pRefData
)
54 struct deh_mgr
*hdeh_mgr
= (struct deh_mgr
*)pRefData
;
57 bridge_deh_notify(hdeh_mgr
, DSP_MMUFAULT
, 0L);
62 * ======== mmu_fault_isr ========
63 * ISR to be triggered by a DSP MMU fault interrupt.
65 irqreturn_t
mmu_fault_isr(int irq
, IN
void *pRefData
)
67 struct deh_mgr
*deh_mgr_obj
= (struct deh_mgr
*)pRefData
;
68 struct bridge_dev_context
*dev_context
;
69 struct cfg_hostres
*resources
;
71 DBC_REQUIRE(irq
== INT_DSP_MMU_IRQ
);
72 DBC_REQUIRE(deh_mgr_obj
);
77 (struct bridge_dev_context
*)deh_mgr_obj
->hbridge_context
;
79 resources
= dev_context
->resources
;
82 dev_dbg(bridge
, "%s: Failed to get Host Resources\n",
86 if (mmu_check_if_fault(dev_context
)) {
87 printk(KERN_INFO
"***** DSPMMU FAULT ***** IRQStatus "
88 "0x%x\n", dmmu_event_mask
);
89 printk(KERN_INFO
"***** DSPMMU FAULT ***** fault_addr "
90 "0x%x\n", fault_addr
);
92 * Schedule a DPC directly. In the future, it may be
93 * necessary to check if DSP MMU fault is intended for
96 tasklet_schedule(&deh_mgr_obj
->dpc_tasklet
);
98 /* Reset err_info structure before use. */
99 deh_mgr_obj
->err_info
.dw_err_mask
= DSP_MMUFAULT
;
100 deh_mgr_obj
->err_info
.dw_val1
= fault_addr
>> 16;
101 deh_mgr_obj
->err_info
.dw_val2
= fault_addr
& 0xFFFF;
102 deh_mgr_obj
->err_info
.dw_val3
= 0L;
103 /* Disable the MMU events, else once we clear it will
104 * start to raise INTs again */
105 hw_mmu_event_disable(resources
->dw_dmmu_base
,
106 HW_MMU_TRANSLATION_FAULT
);
108 hw_mmu_event_disable(resources
->dw_dmmu_base
,
109 HW_MMU_ALL_INTERRUPTS
);
116 * ======== mmu_check_if_fault ========
117 * Check to see if MMU Fault is valid TLB miss from DSP
118 * Note: This function is called from an ISR
120 static bool mmu_check_if_fault(struct bridge_dev_context
*dev_context
)
124 hw_status hw_status_obj
;
125 struct cfg_hostres
*resources
= dev_context
->resources
;
128 dev_dbg(bridge
, "%s: Failed to get Host Resources in\n",
133 hw_mmu_event_status(resources
->dw_dmmu_base
, &dmmu_event_mask
);
134 if (dmmu_event_mask
== HW_MMU_TRANSLATION_FAULT
) {
135 hw_mmu_fault_addr_read(resources
->dw_dmmu_base
, &fault_addr
);