I'm bit stuck at programming device MSI(Message Signaled interrupt) and any pointers welcomed...(my environment is Watcom C + DOS/32a - dos extender, in flat mode...)
@ PIC(8259) mode is ok for me...
I list what I have done as below and maybe someone can help to clarify these...Thanks !
(1) Multiple Message Enable = 0( for single MSI set this field = 0; MMC = 100b)
(2) For MSI message address register in the MSI capability
- bit[31:20] = 0xFEE
- bit[19:12] = 0 (Destination ID, and found Local APIC ID = 0...)
- bit3 = 0 (Redirection hint = 0)
- bit2 = 0 (Destination Mode, don't care because of RH = 0)
(3) For MSI message data register in the MSI capability
- bit15 = 0 (trigger mode = edge)
- bit14 = 0 (trigger level, ignored if trigger mode = edge)
- bit[10:8] = 000 (delivery mode = fixed)
- bit[7:0] = 0x20 (vector, and I choose to use 0x20)
(4) Finally enable MSI by setting MSICAP.MC.MSIE = 1
- I have roughly read the doc(chapter 10) http://download.intel.com/products/processor/manual/253668.pdf
- I think there is no need to program IO APIC and Local APIC registers because MSI does not route to APIC system...!
Current status: I found system hang after enabling MSIE = 1 and device generates interrupt via MSI !
Note: In above sequence the service routine is NOT installed because I have no idea how to do it...( is this the reason why my app hang ? )
Thanks !
[20120822 updated] When setting the vector in Message Data field to 0x20, app hang...But if set to 0x76, I found app did not hang and then I can check if device generates interrupt and Local APIC receives this interrupt message as below:
For PCI device(AHCI controller):
- ID(Interrupt Disable) = 0
- IS(Interrupt Status) = 0
- MSI Cap = 09,FEE00000,00000076
For AHCI HBA registers:
- PxIS = 00000023
- PxIE = 7DC0007F
- IS = 00000001
- IE bit1 = 1
By 1 and 2 I think device successfully sends the message to request service because:
- IS bit0 = 1(Port 0 has pending interrupt status)
- IE(Interrupt Enable) = 1
- PCI Command register bit10(ID) = 0
- MSICAP.MC.MSIE = 1(to MSI engine)
Also I found the LAPIC receives this interrupt message because:
- Local APIC IRR(Interrupt Request Register) bit118(=0x76) = 1
- Local APIC ISR(In-Service register) bit118(=0x76) = 1
Thus it seems that device generates the interrupt and Local APIC receives this; even so, my service routine is NOT called !
To implement the MSI feature in DOS mode, you can reference below sequences:
Check if Local APIC is enabled
Initialize MSI capability registers
Install your own service routine
Notes:
Enable device to request service via MSI by
You can check if device generates request and LAPIC receives this
@ References:
Intel 64 and IA-32 Architectures Software Developer Manuals
APIC
PCI Local Bus Specification v2.2
Access CPU MSR
DOS/32 Advanced