Change GDT code to enforce correct CS

This commit is contained in:
Justin C. Miller
2018-05-14 22:52:28 -07:00
parent 09f72f5ac6
commit 0fc369789e
3 changed files with 80 additions and 20 deletions

View File

@@ -3,20 +3,29 @@
#include "interrupts.h"
#include "pci.h"
struct pci_cap_msi :
public pci_cap
struct pci_cap_msi
{
pci_cap::type id;
uint8_t next;
uint16_t control;
uint64_t address;
} __attribute__ ((packed));
struct pci_cap_msi32
{
pci_cap::type id;
uint8_t next;
uint16_t control;
uint32_t address;
uint16_t data;
uint16_t reserved;
uint32_t mask;
uint32_t pending;
} __attribute__ ((packed));
struct pci_cap_msix :
public pci_cap
struct pci_cap_msi64
{
pci_cap::type id;
uint8_t next;
uint16_t control;
uint64_t address;
uint16_t data;
@@ -68,11 +77,13 @@ pci_device::pci_device(pci_group &group, uint8_t bus, uint8_t device, uint8_t fu
while (next) {
pci_cap *cap = reinterpret_cast<pci_cap *>(kutil::offset_pointer(m_base, next));
next = cap->next;
log::debug(logs::device, " - found PCI cap type %02x", cap->id);
if (cap->id == pci_cap::type::msi) {
m_msi = cap;
pci_cap_msi *mcap = reinterpret_cast<pci_cap_msi *>(cap);
mcap->control |= ~0x1; // Mask interrupts
log::debug(logs::device, " - MSI control %08x", mcap->control);
}
}
}
@@ -111,9 +122,24 @@ pci_device::write_msi_regs(addr_t address, uint16_t data)
kassert(m_msi, "Tried to write MSI for a device without that cap");
if (m_msi->id == pci_cap::type::msi) {
pci_cap_msi *mcap = reinterpret_cast<pci_cap_msi *>(m_msi);
mcap->address = address;
mcap->data = data;
mcap->control |= 1;
if (mcap->control & 0x0080) {
pci_cap_msi64 *mcap64 = reinterpret_cast<pci_cap_msi64 *>(m_msi);
mcap64->address = address;
mcap64->data = data;
if (mcap64->control & 0x0100)
log::debug(logs::device, " - MSI mask %08x pending %08x", mcap64->mask, mcap64->pending);
} else {
pci_cap_msi32 *mcap32 = reinterpret_cast<pci_cap_msi32 *>(m_msi);
mcap32->address = address;
mcap32->data = data;
if (mcap32->control & 0x0100)
log::debug(logs::device, " - MSI mask %08x pending %08x", mcap32->mask, mcap32->pending);
}
uint16_t control = mcap->control;
control &= 0xff8f; // We're allocating one vector, clear 6::4
control |= 0x0001; // Enable MSI
mcap->control = control;
} else {
kassert(0, "MIS-X is NYI");
}