From: Gabe Black Date: Thu, 12 Jun 2008 04:46:22 +0000 (-0400) Subject: X86: Remove enforcement of APIC register access alignment. Panic if more than one... X-Git-Tag: m5_2.0_beta6~165 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b3e55339f90dbf7f719e8f8348356e1ad03d74bb;p=gem5.git X86: Remove enforcement of APIC register access alignment. Panic if more than one register is accessed at a time. --- diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh index eda85c084..cf3eba5e9 100644 --- a/src/arch/x86/mmaped_ipr.hh +++ b/src/arch/x86/mmaped_ipr.hh @@ -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())); - } else { - xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg), - gtoh(pkt->get())); - } + 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); } diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 3e720c9ae..cbd59c19e 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -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;