X86: Remove enforcement of APIC register access alignment. Panic if more than one register is accessed at a time.
This commit is contained in:
parent
561a541797
commit
b3e55339f9
2 changed files with 25 additions and 19 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue