|
@@ -1,17 +1,14 @@
|
|
|
#include "msi.h"
|
|
|
#include "pci.h"
|
|
|
+#include <common/errno.h>
|
|
|
|
|
|
/**
|
|
|
- * @brief 生成架构相关的msi的message address
|
|
|
+ * @brief 生成msi消息
|
|
|
*
|
|
|
+ * @param msi_desc msi描述符
|
|
|
+ * @return struct msi_msg_t* msi消息指针(在描述符内)
|
|
|
*/
|
|
|
-#define pci_get_arch_msi_message_address(processor) ((uint64_t)(0xfee00000UL | (processor << 12)))
|
|
|
-
|
|
|
-/**
|
|
|
- * @brief 生成架构相关的message data
|
|
|
- *
|
|
|
- */
|
|
|
-#define pci_get_arch_msi_message_data(vector, processor, edge_trigger, assert) ((uint32_t)((vector & 0xff) | (edge_trigger == 1 ? 0 : (1 << 15)) | ((assert == 0) ? 0 : (1 << 14))))
|
|
|
+extern struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc);
|
|
|
|
|
|
/**
|
|
|
* @brief 启用 Message Signaled Interrupts
|
|
@@ -24,7 +21,6 @@
|
|
|
*
|
|
|
* @return 返回码
|
|
|
*/
|
|
|
-// int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edge_trigger, uint8_t assert)
|
|
|
int pci_enable_msi(struct msi_desc_t *msi_desc)
|
|
|
{
|
|
|
struct pci_device_structure_header_t *ptr = msi_desc->pci_dev;
|
|
@@ -32,22 +28,39 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
|
|
|
uint32_t tmp;
|
|
|
uint16_t message_control;
|
|
|
uint64_t message_addr;
|
|
|
- switch (ptr->HeaderType)
|
|
|
- {
|
|
|
- case 0x00: // general device
|
|
|
- if (!(ptr->Status & 0x10))
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
|
|
|
- cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
|
|
|
+ // 先尝试获取msi-x,若不存在,则获取msi capability
|
|
|
+ if (msi_desc->pci.msi_attribute.is_msix)
|
|
|
+ {
|
|
|
+ cap_ptr = pci_enumerate_capability_list(ptr, 0x11);
|
|
|
+ if (((int32_t)cap_ptr) < 0)
|
|
|
+ {
|
|
|
+ cap_ptr = pci_enumerate_capability_list(ptr, 0x05);
|
|
|
+ if (((int32_t)cap_ptr) < 0)
|
|
|
+ return -ENOSYS;
|
|
|
+ msi_desc->pci.msi_attribute.is_msix = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ cap_ptr = pci_enumerate_capability_list(ptr, 0x05);
|
|
|
+ if (((int32_t)cap_ptr) < 0)
|
|
|
+ return -ENOSYS;
|
|
|
+ msi_desc->pci.msi_attribute.is_msix = 0;
|
|
|
+ }
|
|
|
+ // 获取msi消息
|
|
|
+ msi_arch_get_msg(msi_desc);
|
|
|
|
|
|
+ if (msi_desc->pci.msi_attribute.is_msix)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
message_control = (tmp >> 16) & 0xffff;
|
|
|
|
|
|
- if (tmp & 0xff != 0x5)
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
-
|
|
|
// 写入message address
|
|
|
- message_addr = pci_get_arch_msi_message_address(msi_desc->processor); // 获取message address
|
|
|
+ message_addr = ((((uint64_t)msi_desc->msg.address_hi) << 32) | msi_desc->msg.address_lo); // 获取message address
|
|
|
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x4, (uint32_t)(message_addr & 0xffffffff));
|
|
|
|
|
|
if (message_control & (1 << 7)) // 64位
|
|
@@ -55,40 +68,7 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
|
|
|
|
|
|
// 写入message data
|
|
|
|
|
|
- tmp = pci_get_arch_msi_message_data(msi_desc->irq_num, msi_desc->processor, msi_desc->edge_trigger, msi_desc->assert);
|
|
|
- if (message_control & (1 << 7)) // 64位
|
|
|
- pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0xc, tmp);
|
|
|
- else
|
|
|
- pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, tmp);
|
|
|
-
|
|
|
- // 使能msi
|
|
|
- tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
- tmp |= (1 << 16);
|
|
|
- pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp);
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- case 0x01: // pci to pci bridge
|
|
|
- if (!(ptr->Status & 0x10))
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
- cap_ptr = ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer;
|
|
|
-
|
|
|
- tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
-
|
|
|
- message_control = (tmp >> 16) & 0xffff;
|
|
|
-
|
|
|
- if (tmp & 0xff != 0x5)
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
-
|
|
|
- // 写入message address
|
|
|
- message_addr = pci_get_arch_msi_message_address(msi_desc->processor); // 获取message address
|
|
|
- pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x4, (uint32_t)(message_addr & 0xffffffff));
|
|
|
-
|
|
|
- if (message_control & (1 << 7)) // 64位
|
|
|
- pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, (uint32_t)((message_addr >> 32) & 0xffffffff));
|
|
|
-
|
|
|
- // 写入message data
|
|
|
- tmp = pci_get_arch_msi_message_data(msi_desc->irq_num, msi_desc->processor, msi_desc->edge_trigger, msi_desc->assert);
|
|
|
+ tmp = msi_desc->msg.data;
|
|
|
if (message_control & (1 << 7)) // 64位
|
|
|
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0xc, tmp);
|
|
|
else
|
|
@@ -98,15 +78,6 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
tmp |= (1 << 16);
|
|
|
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp);
|
|
|
-
|
|
|
- break;
|
|
|
- case 0x02: // pci to card bus bridge
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
- break;
|
|
|
-
|
|
|
- default: // 不应该到达这里
|
|
|
- return E_WRONG_HEADER_TYPE;
|
|
|
- break;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -128,13 +99,13 @@ int pci_start_msi(void *header)
|
|
|
{
|
|
|
case 0x00: // general device
|
|
|
if (!(ptr->Status & 0x10))
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
|
|
|
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
|
|
|
if (tmp & 0xff != 0x5)
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
|
|
|
// 使能msi
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
@@ -145,13 +116,13 @@ int pci_start_msi(void *header)
|
|
|
|
|
|
case 0x01: // pci to pci bridge
|
|
|
if (!(ptr->Status & 0x10))
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
cap_ptr = ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer;
|
|
|
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
|
|
|
if (tmp & 0xff != 0x5)
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
|
|
|
//使能msi
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
@@ -160,11 +131,11 @@ int pci_start_msi(void *header)
|
|
|
|
|
|
break;
|
|
|
case 0x02: // pci to card bus bridge
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
break;
|
|
|
|
|
|
default: // 不应该到达这里
|
|
|
- return E_WRONG_HEADER_TYPE;
|
|
|
+ return -EINVAL;
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -186,13 +157,13 @@ int pci_disable_msi(void *header)
|
|
|
{
|
|
|
case 0x00: // general device
|
|
|
if (!(ptr->Status & 0x10))
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
|
|
|
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
|
|
|
if (tmp & 0xff != 0x5)
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
|
|
|
// 禁用msi
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
@@ -203,13 +174,13 @@ int pci_disable_msi(void *header)
|
|
|
|
|
|
case 0x01: // pci to pci bridge
|
|
|
if (!(ptr->Status & 0x10))
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
cap_ptr = ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer;
|
|
|
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
|
|
|
|
if (tmp & 0xff != 0x5)
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
|
|
|
//禁用msi
|
|
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
|
@@ -218,11 +189,11 @@ int pci_disable_msi(void *header)
|
|
|
|
|
|
break;
|
|
|
case 0x02: // pci to card bus bridge
|
|
|
- return E_NOT_SUPPORT_MSI;
|
|
|
+ return -ENOSYS;
|
|
|
break;
|
|
|
|
|
|
default: // 不应该到达这里
|
|
|
- return E_WRONG_HEADER_TYPE;
|
|
|
+ return -EINVAL;
|
|
|
break;
|
|
|
}
|
|
|
|