mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 13:16:31 +00:00
🔧 将enable msi的部分更新为使用msi_desc来完成
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -109,7 +109,8 @@
|
|||||||
"slab.h": "c",
|
"slab.h": "c",
|
||||||
"boot_info.h": "c",
|
"boot_info.h": "c",
|
||||||
"pci.h": "c",
|
"pci.h": "c",
|
||||||
"time.h": "c"
|
"time.h": "c",
|
||||||
|
"ia64_msi.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
CFLAGS += -I .
|
CFLAGS += -I .
|
||||||
|
|
||||||
all: x86_64_ipi.o
|
all: x86_64_ipi.o ia64_msi.o
|
||||||
|
|
||||||
x86_64_ipi.o: x86_64_ipi.c
|
x86_64_ipi.o: x86_64_ipi.c
|
||||||
gcc $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o
|
gcc $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o
|
||||||
|
|
||||||
|
ia64_msi.o: ia64_msi.c
|
||||||
|
gcc $(CFLAGS) -c ia64_msi.c -o ia64_msi.o
|
||||||
|
|
||||||
|
27
kernel/arch/x86_64/ia64_msi.c
Normal file
27
kernel/arch/x86_64/ia64_msi.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "ia64_msi.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 生成架构相关的msi的message address
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define ia64_pci_get_arch_msi_message_address(processor) ((0xfee00000UL | (processor << 12)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 生成架构相关的message data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define ia64_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))))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 生成msi消息
|
||||||
|
*
|
||||||
|
* @param msi_desc msi描述符
|
||||||
|
* @return struct msi_msg_t* msi消息指针(在描述符内)
|
||||||
|
*/
|
||||||
|
struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc)
|
||||||
|
{
|
||||||
|
msi_desc->msg.address_hi = 0;
|
||||||
|
msi_desc->msg.address_lo = ia64_pci_get_arch_msi_message_address(msi_desc->processor);
|
||||||
|
msi_desc->msg.data = ia64_pci_get_arch_msi_message_data(msi_desc->irq_num, msi_desc->processor, msi_desc->edge_trigger, msi_desc->assert);
|
||||||
|
return &(msi_desc->msg);
|
||||||
|
}
|
11
kernel/arch/x86_64/ia64_msi.h
Normal file
11
kernel/arch/x86_64/ia64_msi.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <driver/pci/msi.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 生成msi消息
|
||||||
|
*
|
||||||
|
* @param msi_desc msi描述符
|
||||||
|
* @return struct msi_msg_t* msi消息指针(在描述符内)
|
||||||
|
*/
|
||||||
|
struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc);
|
@ -1,17 +1,14 @@
|
|||||||
#include "msi.h"
|
#include "msi.h"
|
||||||
#include "pci.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)))
|
extern struct msi_msg_t *msi_arch_get_msg(struct msi_desc_t *msi_desc);
|
||||||
|
|
||||||
/**
|
|
||||||
* @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))))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 启用 Message Signaled Interrupts
|
* @brief 启用 Message Signaled Interrupts
|
||||||
@ -24,7 +21,6 @@
|
|||||||
*
|
*
|
||||||
* @return 返回码
|
* @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)
|
int pci_enable_msi(struct msi_desc_t *msi_desc)
|
||||||
{
|
{
|
||||||
struct pci_device_structure_header_t *ptr = msi_desc->pci_dev;
|
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;
|
uint32_t tmp;
|
||||||
uint16_t message_control;
|
uint16_t message_control;
|
||||||
uint64_t message_addr;
|
uint64_t message_addr;
|
||||||
switch (ptr->HeaderType)
|
|
||||||
|
// 先尝试获取msi-x,若不存在,则获取msi capability
|
||||||
|
if (msi_desc->pci.msi_attribute.is_msix)
|
||||||
{
|
{
|
||||||
case 0x00: // general device
|
cap_ptr = pci_enumerate_capability_list(ptr, 0x11);
|
||||||
if (!(ptr->Status & 0x10))
|
if (((int32_t)cap_ptr) < 0)
|
||||||
return E_NOT_SUPPORT_MSI;
|
{
|
||||||
|
cap_ptr = pci_enumerate_capability_list(ptr, 0x05);
|
||||||
cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
|
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处的值
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||||
message_control = (tmp >> 16) & 0xffff;
|
message_control = (tmp >> 16) & 0xffff;
|
||||||
|
|
||||||
if (tmp & 0xff != 0x5)
|
|
||||||
return E_NOT_SUPPORT_MSI;
|
|
||||||
|
|
||||||
// 写入message address
|
// 写入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));
|
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x4, (uint32_t)(message_addr & 0xffffffff));
|
||||||
|
|
||||||
if (message_control & (1 << 7)) // 64位
|
if (message_control & (1 << 7)) // 64位
|
||||||
@ -55,7 +68,7 @@ int pci_enable_msi(struct msi_desc_t *msi_desc)
|
|||||||
|
|
||||||
// 写入message data
|
// 写入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位
|
if (message_control & (1 << 7)) // 64位
|
||||||
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0xc, tmp);
|
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0xc, tmp);
|
||||||
else
|
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 = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||||
tmp |= (1 << 16);
|
tmp |= (1 << 16);
|
||||||
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp);
|
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;
|
return 0;
|
||||||
@ -128,13 +99,13 @@ int pci_start_msi(void *header)
|
|||||||
{
|
{
|
||||||
case 0x00: // general device
|
case 0x00: // general device
|
||||||
if (!(ptr->Status & 0x10))
|
if (!(ptr->Status & 0x10))
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
|
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处的值
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||||
|
|
||||||
if (tmp & 0xff != 0x5)
|
if (tmp & 0xff != 0x5)
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
|
|
||||||
// 使能msi
|
// 使能msi
|
||||||
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
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
|
case 0x01: // pci to pci bridge
|
||||||
if (!(ptr->Status & 0x10))
|
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;
|
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处的值
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||||
|
|
||||||
if (tmp & 0xff != 0x5)
|
if (tmp & 0xff != 0x5)
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
|
|
||||||
//使能msi
|
//使能msi
|
||||||
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
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;
|
break;
|
||||||
case 0x02: // pci to card bus bridge
|
case 0x02: // pci to card bus bridge
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // 不应该到达这里
|
default: // 不应该到达这里
|
||||||
return E_WRONG_HEADER_TYPE;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,13 +157,13 @@ int pci_disable_msi(void *header)
|
|||||||
{
|
{
|
||||||
case 0x00: // general device
|
case 0x00: // general device
|
||||||
if (!(ptr->Status & 0x10))
|
if (!(ptr->Status & 0x10))
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
|
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处的值
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||||
|
|
||||||
if (tmp & 0xff != 0x5)
|
if (tmp & 0xff != 0x5)
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
|
|
||||||
// 禁用msi
|
// 禁用msi
|
||||||
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
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
|
case 0x01: // pci to pci bridge
|
||||||
if (!(ptr->Status & 0x10))
|
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;
|
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处的值
|
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
||||||
|
|
||||||
if (tmp & 0xff != 0x5)
|
if (tmp & 0xff != 0x5)
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
|
|
||||||
//禁用msi
|
//禁用msi
|
||||||
tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
|
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;
|
break;
|
||||||
case 0x02: // pci to card bus bridge
|
case 0x02: // pci to card bus bridge
|
||||||
return E_NOT_SUPPORT_MSI;
|
return -ENOSYS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // 不应该到达这里
|
default: // 不应该到达这里
|
||||||
return E_WRONG_HEADER_TYPE;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <debug/bug.h>
|
#include <debug/bug.h>
|
||||||
|
#include <common/errno.h>
|
||||||
|
|
||||||
static uint count_device_list = 0;
|
static uint count_device_list = 0;
|
||||||
static void pci_checkBus(uint8_t bus);
|
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;
|
void *ret;
|
||||||
if (common_header->Vendor_ID == 0xffff)
|
if (common_header->Vendor_ID == 0xffff)
|
||||||
{
|
{
|
||||||
*type = E_DEVICE_INVALID;
|
*type = -ENXIO;
|
||||||
kfree(common_header);
|
kfree(common_header);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -295,7 +296,7 @@ void *pci_read_header(int *type, uchar bus, uchar slot, uchar func, bool add_to_
|
|||||||
break;
|
break;
|
||||||
default: // 错误的头类型 这里不应该被执行
|
default: // 错误的头类型 这里不应该被执行
|
||||||
// kerror("PCI->pci_read_header(): Invalid header type.");
|
// kerror("PCI->pci_read_header(): Invalid header type.");
|
||||||
*type = E_WRONG_HEADER_TYPE;
|
*type = -EINVAL;
|
||||||
// kerror("vendor id=%#010lx", common_header->Vendor_ID);
|
// kerror("vendor id=%#010lx", common_header->Vendor_ID);
|
||||||
// kerror("header type = %d", common_header->HeaderType);
|
// kerror("header type = %d", common_header->HeaderType);
|
||||||
kfree(common_header);
|
kfree(common_header);
|
||||||
@ -308,7 +309,7 @@ static void pci_checkFunction(uint8_t bus, uint8_t device, uint8_t function)
|
|||||||
int header_type;
|
int header_type;
|
||||||
struct pci_device_structure_header_t *header = pci_read_header(&header_type, bus, device, function, true);
|
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!");
|
// kerror("pci_checkFunction(): wrong header type!");
|
||||||
// 此处内存已经在read header函数里面释放,不用重复释放
|
// 此处内存已经在read header函数里面释放,不用重复释放
|
||||||
@ -328,15 +329,15 @@ static int pci_checkDevice(uint8_t bus, uint8_t device)
|
|||||||
int header_type;
|
int header_type;
|
||||||
|
|
||||||
struct pci_device_structure_header_t *header = pci_read_header(&header_type, bus, device, 0, false);
|
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函数里面释放,不用重复释放
|
// 此处内存已经在read header函数里面释放,不用重复释放
|
||||||
return E_WRONG_HEADER_TYPE;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (header_type == E_DEVICE_INVALID)
|
if (header_type == -ENXIO)
|
||||||
{
|
{
|
||||||
// kerror("DEVICE INVALID");
|
// kerror("DEVICE INVALID");
|
||||||
return E_DEVICE_INVALID;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t vendorID = header->Vendor_ID;
|
uint16_t vendorID = header->Vendor_ID;
|
||||||
@ -344,7 +345,7 @@ static int pci_checkDevice(uint8_t bus, uint8_t device)
|
|||||||
if (vendorID == 0xffff) // 设备不存在
|
if (vendorID == 0xffff) // 设备不存在
|
||||||
{
|
{
|
||||||
kfree(header);
|
kfree(header);
|
||||||
return E_DEVICE_INVALID;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
pci_checkFunction(bus, device, 0);
|
pci_checkFunction(bus, device, 0);
|
||||||
|
|
||||||
@ -388,7 +389,7 @@ void pci_checkAllBuses()
|
|||||||
int header_type;
|
int header_type;
|
||||||
struct pci_device_structure_header_t *header = pci_read_header(&header_type, 0, 0, 0, false);
|
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!");
|
kBUG("pci_checkAllBuses(): wrong header type!");
|
||||||
// 此处内存已经在read header函数里面释放,不用重复释放
|
// 此处内存已经在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);
|
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_ADDRESS 0xcf8
|
||||||
#define PORT_PCI_CONFIG_DATA 0xcfc
|
#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设备结构信息的链表
|
// pci设备结构信息的链表
|
||||||
struct List * pci_device_structure_list = NULL;
|
struct List * pci_device_structure_list = NULL;
|
||||||
@ -215,3 +212,12 @@ void pci_checkAllBuses();
|
|||||||
* @param res 返回的结果数组
|
* @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);
|
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);
|
@ -565,7 +565,7 @@ uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
|
|||||||
msi_desc.edge_trigger = info->edge_trigger;
|
msi_desc.edge_trigger = info->edge_trigger;
|
||||||
msi_desc.processor = info->processor;
|
msi_desc.processor = info->processor;
|
||||||
msi_desc.pci.msi_attribute.is_64 = 1;
|
msi_desc.pci.msi_attribute.is_64 = 1;
|
||||||
// todo: QEMU是使用msix的,因此要先在pci中实现msix
|
// todo: QEMU是使用msix的,因此要先在pci中实现msix
|
||||||
int retval = pci_enable_msi(&msi_desc);
|
int retval = pci_enable_msi(&msi_desc);
|
||||||
kdebug("pci retval = %d", retval);
|
kdebug("pci retval = %d", retval);
|
||||||
kdebug("xhci irq %d installed.", irq_num);
|
kdebug("xhci irq %d installed.", irq_num);
|
||||||
|
Reference in New Issue
Block a user