mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 20:36:31 +00:00
🔧 将enable msi的部分更新为使用msi_desc来完成
This commit is contained in:
@ -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)
|
||||
|
||||
// 先尝试获取msi-x,若不存在,则获取msi capability
|
||||
if (msi_desc->pci.msi_attribute.is_msix)
|
||||
{
|
||||
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;
|
||||
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,7 +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);
|
||||
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
|
||||
@ -65,48 +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 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);
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <common/kprint.h>
|
||||
#include <mm/slab.h>
|
||||
#include <debug/bug.h>
|
||||
#include <common/errno.h>
|
||||
|
||||
static uint count_device_list = 0;
|
||||
static void pci_checkBus(uint8_t bus);
|
||||
@ -257,7 +258,7 @@ void *pci_read_header(int *type, uchar bus, uchar slot, uchar func, bool add_to_
|
||||
void *ret;
|
||||
if (common_header->Vendor_ID == 0xffff)
|
||||
{
|
||||
*type = E_DEVICE_INVALID;
|
||||
*type = -ENXIO;
|
||||
kfree(common_header);
|
||||
return NULL;
|
||||
}
|
||||
@ -295,7 +296,7 @@ void *pci_read_header(int *type, uchar bus, uchar slot, uchar func, bool add_to_
|
||||
break;
|
||||
default: // 错误的头类型 这里不应该被执行
|
||||
// kerror("PCI->pci_read_header(): Invalid header type.");
|
||||
*type = E_WRONG_HEADER_TYPE;
|
||||
*type = -EINVAL;
|
||||
// kerror("vendor id=%#010lx", common_header->Vendor_ID);
|
||||
// kerror("header type = %d", common_header->HeaderType);
|
||||
kfree(common_header);
|
||||
@ -308,7 +309,7 @@ static void pci_checkFunction(uint8_t bus, uint8_t device, uint8_t function)
|
||||
int header_type;
|
||||
struct pci_device_structure_header_t *header = pci_read_header(&header_type, bus, device, function, true);
|
||||
|
||||
if (header_type == E_WRONG_HEADER_TYPE)
|
||||
if (header_type == -EINVAL)
|
||||
{
|
||||
// kerror("pci_checkFunction(): wrong header type!");
|
||||
// 此处内存已经在read header函数里面释放,不用重复释放
|
||||
@ -328,15 +329,15 @@ static int pci_checkDevice(uint8_t bus, uint8_t device)
|
||||
int header_type;
|
||||
|
||||
struct pci_device_structure_header_t *header = pci_read_header(&header_type, bus, device, 0, false);
|
||||
if (header_type == E_WRONG_HEADER_TYPE)
|
||||
if (header_type == -EINVAL)
|
||||
{
|
||||
// 此处内存已经在read header函数里面释放,不用重复释放
|
||||
return E_WRONG_HEADER_TYPE;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (header_type == E_DEVICE_INVALID)
|
||||
if (header_type == -ENXIO)
|
||||
{
|
||||
// kerror("DEVICE INVALID");
|
||||
return E_DEVICE_INVALID;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
uint16_t vendorID = header->Vendor_ID;
|
||||
@ -344,7 +345,7 @@ static int pci_checkDevice(uint8_t bus, uint8_t device)
|
||||
if (vendorID == 0xffff) // 设备不存在
|
||||
{
|
||||
kfree(header);
|
||||
return E_DEVICE_INVALID;
|
||||
return -ENXIO;
|
||||
}
|
||||
pci_checkFunction(bus, device, 0);
|
||||
|
||||
@ -388,7 +389,7 @@ void pci_checkAllBuses()
|
||||
int header_type;
|
||||
struct pci_device_structure_header_t *header = pci_read_header(&header_type, 0, 0, 0, false);
|
||||
|
||||
if (header_type == E_WRONG_HEADER_TYPE)
|
||||
if (header_type == EINVAL)
|
||||
{
|
||||
kBUG("pci_checkAllBuses(): wrong header type!");
|
||||
// 此处内存已经在read header函数里面释放,不用重复释放
|
||||
@ -493,4 +494,47 @@ void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_
|
||||
}
|
||||
ptr = container_of(list_next(&(ptr->list)), struct pci_device_structure_header_t, list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 寻找符合指定类型的capability list
|
||||
*
|
||||
* @param pci_dev pci设备header
|
||||
* @param cap_type c要寻找的capability类型
|
||||
* @return uint64_t cap list的偏移量
|
||||
*/
|
||||
uint32_t pci_enumerate_capability_list(struct pci_device_structure_header_t *pci_dev, int cap_type)
|
||||
{
|
||||
uint32_t cap_offset;
|
||||
switch (pci_dev->HeaderType)
|
||||
{
|
||||
case 0x00:
|
||||
|
||||
cap_offset = ((struct pci_device_structure_general_device_t *)pci_dev)->Capabilities_Pointer;
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
cap_offset = ((struct pci_device_structure_pci_to_pci_bridge_t *)pci_dev)->Capability_Pointer;
|
||||
break;
|
||||
default:
|
||||
// 不支持
|
||||
return -ENOSYS;
|
||||
}
|
||||
uint32_t tmp;
|
||||
while (1)
|
||||
{
|
||||
tmp = pci_read_config(pci_dev->bus, pci_dev->device, pci_dev->func, cap_offset);
|
||||
if (tmp & 0xff != cap_type)
|
||||
{
|
||||
if ((tmp & 0xff00) >> 8)
|
||||
{
|
||||
cap_offset = (tmp & 0xff00);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return cap_offset;
|
||||
}
|
||||
}
|
@ -6,9 +6,6 @@
|
||||
#define PORT_PCI_CONFIG_ADDRESS 0xcf8
|
||||
#define PORT_PCI_CONFIG_DATA 0xcfc
|
||||
|
||||
#define E_DEVICE_INVALID -1
|
||||
#define E_WRONG_HEADER_TYPE -2
|
||||
#define E_NOT_SUPPORT_MSI -3 // 设备不支持msi
|
||||
|
||||
// pci设备结构信息的链表
|
||||
struct List * pci_device_structure_list = NULL;
|
||||
@ -215,3 +212,12 @@ void pci_checkAllBuses();
|
||||
* @param res 返回的结果数组
|
||||
*/
|
||||
void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_device_structure_header_t* res[], uint32_t* count_res);
|
||||
|
||||
/**
|
||||
* @brief 寻找符合指定类型的capability list
|
||||
*
|
||||
* @param pci_dev pci设备header
|
||||
* @param cap_type c要寻找的capability类型
|
||||
* @return uint64_t cap list的偏移量
|
||||
*/
|
||||
uint32_t pci_enumerate_capability_list(struct pci_device_structure_header_t *pci_dev, int cap_type);
|
Reference in New Issue
Block a user