new: msi_desc

This commit is contained in:
fslongjin 2022-07-25 11:50:15 +08:00
parent a3b5102a36
commit 7ca8f42c17
4 changed files with 63 additions and 15 deletions

View File

@ -64,8 +64,6 @@ kernel: head.o main.o $(OBJ_LIST)
done done
clean: clean:
rm -rf $(GARBAGE) rm -rf $(GARBAGE)
@list='$(kernel_subdirs)'; for subdir in $$list; do \ @list='$(kernel_subdirs)'; for subdir in $$list; do \

View File

@ -13,7 +13,6 @@
*/ */
#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)))) #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
* *
@ -25,9 +24,10 @@
* *
* @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(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 = (struct pci_device_structure_header_t *)header; struct pci_device_structure_header_t *ptr = msi_desc->pci_dev;
uint32_t cap_ptr; uint32_t cap_ptr;
uint32_t tmp; uint32_t tmp;
uint16_t message_control; uint16_t message_control;
@ -47,14 +47,15 @@ int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edg
return E_NOT_SUPPORT_MSI; return E_NOT_SUPPORT_MSI;
// 写入message address // 写入message address
message_addr = pci_get_arch_msi_message_address(processor); // 获取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)); 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位
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, (uint32_t)((message_addr >> 32) & 0xffffffff)); pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, (uint32_t)((message_addr >> 32) & 0xffffffff));
// 写入message data // 写入message data
tmp = pci_get_arch_msi_message_data(vector, processor, edge_trigger, assert);
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位 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
@ -80,14 +81,14 @@ int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edg
return E_NOT_SUPPORT_MSI; return E_NOT_SUPPORT_MSI;
// 写入message address // 写入message address
message_addr = pci_get_arch_msi_message_address(processor); // 获取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)); 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位
pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, (uint32_t)((message_addr >> 32) & 0xffffffff)); pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr + 0x8, (uint32_t)((message_addr >> 32) & 0xffffffff));
// 写入message data // 写入message data
tmp = pci_get_arch_msi_message_data(vector, processor, edge_trigger, assert); 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位 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

View File

@ -1,6 +1,47 @@
#pragma once #pragma once
#include <common/glib.h> #include <common/glib.h>
/**
* @brief msi消息内容结构体
*
*/
struct msi_msg_t
{
uint32_t address_lo;
uint32_t address_hi;
uint32_t data;
};
struct pci_msi_desc_t
{
union
{
uint32_t msi_mask; // [PCI MSI] MSI cached mask bits
uint32_t msix_ctrl; // [PCI MSI-X] MSI-X cached per vector control bits
};
struct
{
uint8_t is_msix : 1; // [PCI MSI/X] True if MSI-X
uint8_t can_mask : 1; // [PCI MSI/X] Masking supported?
uint8_t is_64 : 1; // [PCI MSI/X] Address size: 0=32bit 1=64bit
} msi_attribute;
};
/**
* @brief msi描述符
*
*/
struct msi_desc_t
{
uint16_t irq_num; // 中断向量号
uint16_t processor; // 定向投递的处理器
uint16_t edge_trigger; // 是否边缘触发
uint16_t assert; // 是否高电平触发
struct pci_device_structure_header_t *pci_dev; // 对应的pci设备的结构体
struct msi_msg_t msg; // msi消息
uint16_t msi_index; // msi描述符的index
struct pci_msi_desc_t pci; // 与pci相关的msi描述符数据
};
/** /**
* @brief Message Signaled Interrupts * @brief Message Signaled Interrupts
@ -13,7 +54,7 @@
* *
* @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);
/** /**
* @brief msi * @brief msi

View File

@ -557,8 +557,16 @@ uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
return -EINVAL; return -EINVAL;
struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg; struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg;
struct msi_desc_t msi_desc;
memset(&msi_desc, 0, sizeof(struct msi_desc_t));
msi_desc.pci_dev = (struct pci_device_structure_header_t*)xhci_hc[cid].pci_dev_hdr;
msi_desc.assert = info->assert;
msi_desc.edge_trigger = info->edge_trigger;
msi_desc.processor = info->processor;
msi_desc.pci.msi_attribute.is_64 = 1;
// todo: QEMU是使用msix的因此要先在pci中实现msix // todo: QEMU是使用msix的因此要先在pci中实现msix
int retval = pci_enable_msi(xhci_hc[cid].pci_dev_hdr, irq_num, info->processor, info->edge_trigger, info->assert); 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);
return 0; return 0;