X86: Remove enforcement of APIC register access alignment. Panic if more than one register is accessed at a time.

This commit is contained in:
Gabe Black 2008-06-12 00:46:22 -04:00
parent 561a541797
commit b3e55339f9
2 changed files with 25 additions and 19 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@ -78,15 +78,12 @@ namespace X86ISA
#if !FULL_SYSTEM
panic("Shouldn't have a memory mapped register in SE\n");
#else
Addr offset = pkt->getAddr() & mask(3);
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
if (index == MISCREG_PCI_CONFIG_ADDRESS ||
(index >= MISCREG_APIC_START &&
index <= MISCREG_APIC_END)) {
pkt->set((uint32_t)(xc->readMiscReg(pkt->getAddr() /
sizeof(MiscReg))));
} else {
pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg)));
}
MiscReg data = htog(xc->readMiscReg(index));
// Make sure we don't trot off the end of data.
assert(offset + pkt->getSize() <= sizeof(MiscReg));
pkt->setData(((uint8_t *)&data) + offset);
#endif
return xc->getCpuPtr()->ticks(1);
}
@ -97,15 +94,13 @@ namespace X86ISA
#if !FULL_SYSTEM
panic("Shouldn't have a memory mapped register in SE\n");
#else
Addr offset = pkt->getAddr() & mask(3);
MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg));
if (index == MISCREG_PCI_CONFIG_ADDRESS ||
(index >= MISCREG_APIC_START &&
index <= MISCREG_APIC_END)) {
xc->setMiscReg(index, gtoh(pkt->get<uint32_t>()));
} else {
xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg),
gtoh(pkt->get<uint64_t>()));
}
MiscReg data = htog(xc->readMiscRegNoEffect(index));
// Make sure we don't trot off the end of data.
assert(offset + pkt->getSize() <= sizeof(MiscReg));
pkt->writeData(((uint8_t *)&data) + offset);
xc->setMiscReg(index, gtoh(data));
#endif
return xc->getCpuPtr()->ticks(1);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007 The Hewlett-Packard Development Company
* Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@ -598,13 +598,24 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
Addr paddr = req->getPaddr();
if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) {
req->setMmapedIpr(true);
// The Intel developer's manuals say the below restrictions apply,
// but the linux kernel, because of a compiler optimization, breaks
// them.
/*
// Check alignment
if (paddr & ((32/8) - 1))
return new GeneralProtection(0);
// Check access size
if (req->getSize() != (32/8))
return new GeneralProtection(0);
*/
//Make sure we're at least only accessing one register.
if ((paddr & ~mask(3)) != ((paddr + req->getSize()) & ~mask(3)))
panic("Accessed more than one register at a time in the APIC!\n");
MiscReg regNum;
Addr offset = paddr & mask(3);
paddr &= ~mask(3);
switch (paddr - baseAddr)
{
case 0x20:
@ -732,7 +743,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
return new GeneralProtection(0);
break;
}
req->setPaddr(regNum * sizeof(MiscReg));
req->setPaddr(regNum * sizeof(MiscReg) + offset);
}
#endif
return NoFault;