🔧 将enable msi的部分更新为使用msi_desc来完成

This commit is contained in:
fslongjin
2022-07-25 13:50:03 +08:00
parent 7ca8f42c17
commit 2b0b727893
8 changed files with 152 additions and 89 deletions

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);