fix: incorrect settings of msi registers.
authorMinep <zelong56@gmail.com>
Tue, 9 Aug 2022 14:25:19 +0000 (15:25 +0100)
committerMinep <zelong56@gmail.com>
Tue, 9 Aug 2022 14:25:19 +0000 (15:25 +0100)
fix: enable correct hba interrupt for indicating end of transfer.

lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/pci.c
lunaix-os/includes/hal/ahci/hba.h
lunaix-os/includes/hal/pci.h

index 133513b049e096d74542c7f2ce9a20cff4cf4d17..aadb41b2aaf8ca294ec80d78b86799ffafa71e9c 100644 (file)
@@ -160,7 +160,7 @@ ahci_init()
         // 需要通过全部置位去清空这些寄存器(相当的奇怪……)
         port_regs[HBA_RPxSERR] = -1;
 
         // 需要通过全部置位去清空这些寄存器(相当的奇怪……)
         port_regs[HBA_RPxSERR] = -1;
 
-        port_regs[HBA_RPxIE] |= (HBA_PxINTR_D2HR);
+        port_regs[HBA_RPxIE] |= (HBA_PxINTR_DPS);
 
         hba.ports[i] = port;
 
 
         hba.ports[i] = port;
 
@@ -290,7 +290,7 @@ hba_prepare_cmd(struct hba_port* port,
         cmd_header->prdt_len = 1;
         cmd_table->entries[0] =
           (struct hba_prdte){ .data_base = vmm_v2p(buffer),
         cmd_header->prdt_len = 1;
         cmd_table->entries[0] =
           (struct hba_prdte){ .data_base = vmm_v2p(buffer),
-                              .byte_count = size - 1 };
+                              .byte_count = (size - 1) | (0x80000000) };
     }
 
     *cmdh = cmd_header;
     }
 
     *cmdh = cmd_header;
index 4bf4c56863dac16b6fa4b16e483ea97557199376..8c397b031b85f739b2331aeb2b512cb3931756b9 100644 (file)
@@ -181,13 +181,22 @@ pci_setup_msi(struct pci_device* device, int vector)
 
     pci_write_cspace(
       device->cspace_base, PCI_MSI_ADDR(device->msi_loc), msi_addr);
 
     pci_write_cspace(
       device->cspace_base, PCI_MSI_ADDR(device->msi_loc), msi_addr);
-    pci_write_cspace(
-      device->cspace_base, PCI_MSI_DATA(device->msi_loc), msi_data & 0xffff);
 
     pci_reg_t reg1 = pci_read_cspace(device->cspace_base, device->msi_loc);
 
     pci_reg_t reg1 = pci_read_cspace(device->cspace_base, device->msi_loc);
+    pci_reg_t msg_ctl = reg1 >> 16;
+
+    int offset = !!(msg_ctl & MSI_CAP_64BIT) * 4;
+    pci_write_cspace(device->cspace_base,
+                     PCI_MSI_DATA(device->msi_loc, offset),
+                     msi_data & 0xffff);
+
+    if ((msg_ctl & MSI_CAP_MASK)) {
+        pci_write_cspace(
+          device->cspace_base, PCI_MSI_MASK(device->msi_loc, offset), 0);
+    }
 
     // manipulate the MSI_CTRL to allow device using MSI to request service.
 
     // manipulate the MSI_CTRL to allow device using MSI to request service.
-    reg1 = ((((reg1 >> 16) & ~0x70) | 0x1) << 16) | (reg1 & 0xffff);
+    reg1 = ((((reg1 >> 16) & ~0x70) | MSI_CAP_ENABLE) << 16) | (reg1 & 0xffff);
     pci_write_cspace(device->cspace_base, device->msi_loc, reg1);
 }
 
     pci_write_cspace(device->cspace_base, device->msi_loc, reg1);
 }
 
index e7f8d01f7cfe5f0d04d8c4ff63879f94ac31e682..f65a93d460563202679337bf66d8706dda49eb69 100644 (file)
@@ -32,6 +32,7 @@
 #define HBA_PxCMD_ST (1)
 #define HBA_PxINTR_DMA (1 << 2)
 #define HBA_PxINTR_D2HR (1)
 #define HBA_PxCMD_ST (1)
 #define HBA_PxINTR_DMA (1 << 2)
 #define HBA_PxINTR_D2HR (1)
+#define HBA_PxINTR_DPS (1 << 5)
 #define HBA_PxTFD_ERR (1)
 #define HBA_PxTFD_BSY (1 << 7)
 #define HBA_PxTFD_DRQ (1 << 3)
 #define HBA_PxTFD_ERR (1)
 #define HBA_PxTFD_BSY (1 << 7)
 #define HBA_PxTFD_DRQ (1 << 3)
index b31352b3428bec4653cd6e89f0d79a5c07f9d242..d622acbfe32a6ddd8438a0c0fd0b1ff34eb096e6 100644 (file)
 #define PCI_BAR_ADDR_IO(x) ((x) & ~0x3)
 
 #define PCI_MSI_ADDR(msi_base) ((msi_base) + 4)
 #define PCI_BAR_ADDR_IO(x) ((x) & ~0x3)
 
 #define PCI_MSI_ADDR(msi_base) ((msi_base) + 4)
-#define PCI_MSI_DATA(msi_base) ((msi_base) + 8)
+#define PCI_MSI_DATA(msi_base, offset) ((msi_base) + 8 + offset)
+#define PCI_MSI_MASK(msi_base, offset) ((msi_base) + 0xc + offset)
+
+#define MSI_CAP_64BIT 0x80
+#define MSI_CAP_MASK 0x100
+#define MSI_CAP_ENABLE 0x1
 
 #define PCI_RCMD_DISABLE_INTR (1 << 10)
 #define PCI_RCMD_FAST_B2B (1 << 9)
 
 #define PCI_RCMD_DISABLE_INTR (1 << 10)
 #define PCI_RCMD_FAST_B2B (1 << 9)