generated from riscv/docs-spec-template
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MSI stay pending when masked and are released when unmasked
- Loading branch information
Showing
3 changed files
with
40 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,14 +4,29 @@ | |
// Author: [email protected] | ||
|
||
#include "iommu.h" | ||
// MSI pending bit array. | ||
uint8_t msi_pending[16] = {0}; | ||
static void | ||
do_msi( | ||
uint32_t msi_data, uint64_t msi_addr) { | ||
uint8_t status; | ||
status = write_memory((char *)&msi_data, msi_addr, 4); | ||
if ( status & ACCESS_FAULT ) { | ||
// If an access fault is detected on a MSI write using msi_addr_x, | ||
// then the IOMMU reports a "IOMMU MSI write access fault" (cause 273) fault, | ||
// with TTYP set to 0 and iotval set to the value of msi_addr_x. | ||
report_fault(273, msi_addr, 0, TTYPE_NONE, 0, 0, 0, 0, 0); | ||
} | ||
return; | ||
} | ||
void | ||
generate_interrupt( | ||
uint8_t unit) { | ||
|
||
msi_addr_t msi_addr; | ||
uint32_t msi_data; | ||
msi_vec_ctrl_t msi_vec_ctrl; | ||
uint8_t vec, status; | ||
uint8_t vec; | ||
|
||
// Interrupt pending status register (ipsr) | ||
// This 32-bits register (RW1C) reports the pending interrupts | ||
|
@@ -74,15 +89,27 @@ generate_interrupt( | |
// When the mask bit M is 1, the corresponding interrupt vector is | ||
// masked and the IOMMU is prohibited from sending the associated | ||
// message. | ||
if ( msi_vec_ctrl.m == 1 ) | ||
if ( msi_vec_ctrl.m == 1 ) { | ||
// Pending messages for that vector are later generated if the | ||
// corresponding mask bit is cleared to 0. | ||
msi_pending[vec] = 1; | ||
return; | ||
status = write_memory((char *)&msi_data, msi_addr.raw, 4); | ||
if ( status & ACCESS_FAULT ) { | ||
// If an access fault is detected on a MSI write using msi_addr_x, | ||
// then the IOMMU reports a "IOMMU MSI write access fault" (cause 273) fault, | ||
// with TTYP set to 0 and iotval set to the value of msi_addr_x. | ||
report_fault(273, msi_addr.raw, 0, TTYPE_NONE, 0, 0, 0, 0, 0); | ||
} | ||
do_msi(msi_data, msi_addr.raw); | ||
} | ||
return; | ||
} | ||
void | ||
release_pending_interrupt( | ||
uint8_t vec) { | ||
msi_addr_t msi_addr; | ||
uint32_t msi_data; | ||
|
||
if ( msi_pending[vec] == 1 ) { | ||
msi_addr.raw = g_reg_file.msi_cfg_tbl[vec].msi_addr.raw; | ||
msi_data = g_reg_file.msi_cfg_tbl[vec].msi_data; | ||
do_msi(msi_data, msi_addr.raw); | ||
msi_pending[vec] = 0; | ||
} | ||
return; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters