diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2016-01-29 12:14:21 +0000 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2016-01-29 12:14:21 +0000 |
commit | b99fea78a6b0db9dcf7133c302991b8a7a8f8538 (patch) | |
tree | d92f89fbd5a03e9ce64ab74009687c1b8ec4f441 /ext/nomali/lib | |
parent | 1285d639eba6b95e31fb2b4aacae524d04ddf981 (diff) | |
download | gem5-b99fea78a6b0db9dcf7133c302991b8a7a8f8538.tar.xz |
ext: Update NoMali to external rev f08e0a5
Update NoMali from external revision 9adf9d6 to f08e0a5 and bring in
the following changes:
f08e0a5 Add support for tracking address space state
f11099e Fix job slot register handling when running new jobs
b28c98e api: Add a reset callback
29ac4c3 tests: Update gitignore to cover all future test cases
1c6b893 Propagate reset calls to all job slots
8f8ec15 Remove redundant reg vector in MMU
85d90d2 tests: Fix incorrect extern declaration
Diffstat (limited to 'ext/nomali/lib')
-rw-r--r-- | ext/nomali/lib/Rules.mk | 1 | ||||
-rw-r--r-- | ext/nomali/lib/addrspace.cc | 125 | ||||
-rw-r--r-- | ext/nomali/lib/addrspace.hh | 114 | ||||
-rw-r--r-- | ext/nomali/lib/jobcontrol.cc | 9 | ||||
-rw-r--r-- | ext/nomali/lib/jobcontrol.hh | 2 | ||||
-rw-r--r-- | ext/nomali/lib/jobslot.cc | 13 | ||||
-rw-r--r-- | ext/nomali/lib/mmu.cc | 52 | ||||
-rw-r--r-- | ext/nomali/lib/mmu.hh | 12 | ||||
-rw-r--r-- | ext/nomali/lib/nomali_api.cc | 17 | ||||
-rw-r--r-- | ext/nomali/lib/regutils.hh | 46 |
10 files changed, 377 insertions, 14 deletions
diff --git a/ext/nomali/lib/Rules.mk b/ext/nomali/lib/Rules.mk index 34fb6e32e..26ec4a9d4 100644 --- a/ext/nomali/lib/Rules.mk +++ b/ext/nomali/lib/Rules.mk @@ -26,6 +26,7 @@ NOMALI_OBJS := $(addprefix $(d)/, \ gpucontrol.o \ jobcontrol.o \ jobslot.o \ + addrspace.o \ mmu.o \ \ mali_midgard.o \ diff --git a/ext/nomali/lib/addrspace.cc b/ext/nomali/lib/addrspace.cc new file mode 100644 index 000000000..bbb6bce33 --- /dev/null +++ b/ext/nomali/lib/addrspace.cc @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#include "jobslot.hh" + +#include <cassert> +#include <cstdlib> + +#include "addrspace.hh" +#include "gpu.hh" +#include "regutils.hh" + +namespace NoMali { + +const std::vector<AddrSpace::cmd_t> AddrSpace::cmds { + &AddrSpace::cmdNop, // ASn_COMMAND_NOP + &AddrSpace::cmdUpdate, // ASn_COMMAND_UPDATE + &AddrSpace::cmdLock, // ASn_COMMAND_LOCK + &AddrSpace::cmdUnlock, // ASn_COMMAND_UNLOCK + &AddrSpace::cmdFlushPT, // ASn_COMMAND_FLUSH_PT + &AddrSpace::cmdFlushMem, // ASn_COMMAND_FLUSH_MEM +}; + +AddrSpace::AddrSpace(GPU &_gpu, MMU &_mmu, uint8_t _id) + : GPUBlock(_gpu, ASn_NO_REGS), + id(_id), + mmu(_mmu) +{ +} + +AddrSpace::AddrSpace(AddrSpace &&rhs) + : GPUBlock(std::move(rhs)), + id(std::move(rhs.id)), + mmu(rhs.mmu) +{ +} + +AddrSpace::~AddrSpace() +{ +} + +void +AddrSpace::writeReg(RegAddr addr, uint32_t value) +{ + switch (addr.value) { + case ASn_COMMAND: + asCommand(value); + break; + + case ASn_TRANSTAB_LO: + case ASn_TRANSTAB_HI: + case ASn_MEMATTR_LO: + case ASn_MEMATTR_HI: + case ASn_LOCKADDR_LO: + case ASn_LOCKADDR_HI: + GPUBlock::writeReg(addr, value); + break; + + default: + // Ignore writes by default + break; + }; +} + +void +AddrSpace::asCommand(uint32_t cmd) +{ + if (cmd < cmds.size()) + (this->*cmds[cmd])(cmd); +} + +void +AddrSpace::cmdNop(uint32_t cmd) +{ + assert(cmd == ASn_COMMAND_NOP); +} + + +void +AddrSpace::cmdUpdate(uint32_t cmd) +{ + assert(cmd == ASn_COMMAND_UPDATE); +} + +void +AddrSpace::cmdLock(uint32_t cmd) +{ + assert(cmd == ASn_COMMAND_LOCK); +} + +void +AddrSpace::cmdUnlock(uint32_t cmd) +{ + assert(cmd == ASn_COMMAND_UNLOCK); +} + +void +AddrSpace::cmdFlushPT(uint32_t cmd) +{ + assert(cmd == ASn_COMMAND_FLUSH_PT); +} + +void +AddrSpace::cmdFlushMem(uint32_t cmd) +{ + assert(cmd == ASn_COMMAND_FLUSH_MEM); +} + +} diff --git a/ext/nomali/lib/addrspace.hh b/ext/nomali/lib/addrspace.hh new file mode 100644 index 000000000..239c9d119 --- /dev/null +++ b/ext/nomali/lib/addrspace.hh @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016 ARM Limited + * All rights reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Authors: Andreas Sandberg + */ + +#ifndef _LIBNOMALIMODEL_ADDRSPACE_HH +#define _LIBNOMALIMODEL_ADDRSPACE_HH + +#include <vector> + +#include "gpublock.hh" +#include "types.hh" + +namespace NoMali { + +class GPU; + +class MMU; + +/** + * Midgard job slot implementation. + * + * A job slot is a part of a JobControl block that controls the state + * of one out of 16 active jobs. Each slot can contain one running job + * and a pending job. + */ +class AddrSpace + : public GPUBlock +{ + public: + AddrSpace(GPU &_gpu, MMU &_mmu, uint8_t slot_id); + AddrSpace(AddrSpace &&rhs); + virtual ~AddrSpace(); + + void writeReg(RegAddr idx, uint32_t value) override; + + protected: + /** + * @{ + * @name Address Space Control + */ + + + /** @} */ + + /** + * @{ + * @name Job slot commands + */ + + /** + * Address space command dispatcher. + * + * This method is called whenever there is a write to the + * ASn_COMMAND register. The method uses a lookup table to call + * the right command handling method. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void asCommand(uint32_t cmd); + + /** + * Command handler for No-ops. + * + * @param cmd Command number (see the Midgard architecture + * specification) + */ + void cmdNop(uint32_t cmd); + + void cmdUpdate(uint32_t cmd); + void cmdLock(uint32_t cmd); + void cmdUnlock(uint32_t cmd); + void cmdFlushPT(uint32_t cmd); + void cmdFlushMem(uint32_t cmd); + + /** @} */ + + /** Address space ID */ + const uint8_t id; + + /** Parent MMU block */ + MMU &mmu; + + private: + typedef void (AddrSpace::*cmd_t)(uint32_t); + + /** + * Mapping between command IDs and command handling methods. + * + * @note The order of this vector <i>MUST</i> correspond to the + * address space command IDs in the Midgard architecture + * specification. + */ + static const std::vector<cmd_t> cmds; +}; + +} + +#endif // _LIBNOMALIMODEL_ADDRSPACE_HH diff --git a/ext/nomali/lib/jobcontrol.cc b/ext/nomali/lib/jobcontrol.cc index ca4518c09..558cf3ad5 100644 --- a/ext/nomali/lib/jobcontrol.cc +++ b/ext/nomali/lib/jobcontrol.cc @@ -41,6 +41,15 @@ JobControl::~JobControl() { } +void +JobControl::reset() +{ + GPUBlockInt::reset(); + + for (auto &js : slots) + js.reset(); +} + uint32_t JobControl::readReg(RegAddr addr) { diff --git a/ext/nomali/lib/jobcontrol.hh b/ext/nomali/lib/jobcontrol.hh index e0efc04c9..d76a26937 100644 --- a/ext/nomali/lib/jobcontrol.hh +++ b/ext/nomali/lib/jobcontrol.hh @@ -47,6 +47,8 @@ class JobControl JobControl(GPU &_gpu); virtual ~JobControl(); + void reset() override; + uint32_t readReg(RegAddr idx) override; void writeReg(RegAddr idx, uint32_t value) override; diff --git a/ext/nomali/lib/jobslot.cc b/ext/nomali/lib/jobslot.cc index 8ad4fa1ec..2ce1e6260 100644 --- a/ext/nomali/lib/jobslot.cc +++ b/ext/nomali/lib/jobslot.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,10 @@ namespace NoMali { +static const Status STATUS_IDLE(Status::CLASS_NOFAULT, 0, 0); +static const Status STATUS_DONE(Status::CLASS_NOFAULT, 0, 1); +static const Status STATUS_ACTIVE(Status::CLASS_NOFAULT, 1, 0); + const std::vector<JobSlot::cmd_t> JobSlot::cmds { &JobSlot::cmdNop, // JSn_COMMAND_NOP &JobSlot::cmdStart, // JSn_COMMAND_START @@ -104,7 +108,7 @@ JobSlot::tryStart() return; // Reset the status register - regs[RegAddr(JSn_STATUS)] = 0; + regs[RegAddr(JSn_STATUS)] = STATUS_ACTIVE.value; // Transfer the next job configuration to the active job // configuration @@ -113,12 +117,9 @@ JobSlot::tryStart() regs.set64(RegAddr(JSn_AFFINITY_LO), regs.get64(RegAddr(JSn_AFFINITY_NEXT_LO))); regs[RegAddr(JSn_CONFIG)] = regs[RegAddr(JSn_CONFIG_NEXT)]; - regs[RegAddr(JSn_COMMAND)] = regs[RegAddr(JSn_COMMAND_NEXT)]; // Reset the next job configuration regs.set64(RegAddr(JSn_HEAD_NEXT_LO), 0); - regs.set64(RegAddr(JSn_AFFINITY_NEXT_LO), 0); - regs[RegAddr(JSn_CONFIG_NEXT)] = 0; regs[RegAddr(JSn_COMMAND_NEXT)] = 0; runJob(); @@ -127,7 +128,7 @@ JobSlot::tryStart() void JobSlot::runJob() { - exitJob(Status(Status::CLASS_NOFAULT, 0, 1), // JSn_STATUS_DONE + exitJob(STATUS_DONE, 0); // Time stamp counter value } diff --git a/ext/nomali/lib/mmu.cc b/ext/nomali/lib/mmu.cc index 2d166b5af..11978a26d 100644 --- a/ext/nomali/lib/mmu.cc +++ b/ext/nomali/lib/mmu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,9 +29,11 @@ MMU::MMU(GPU &_gpu) RegAddr(MMU_IRQ_RAWSTAT), RegAddr(MMU_IRQ_CLEAR), RegAddr(MMU_IRQ_MASK), - RegAddr(MMU_IRQ_STATUS)), - regs(BLOCK_NUM_REGS) + RegAddr(MMU_IRQ_STATUS)) { + spaces.reserve(16); + for (int i = 0; i < 16; ++i) + spaces.emplace_back(_gpu, *this, i); } MMU::~MMU() @@ -39,6 +41,25 @@ MMU::~MMU() } void +MMU::reset() +{ + GPUBlockInt::reset(); + + for (auto &as : spaces) + as.reset(); +} + +uint32_t +MMU::readReg(RegAddr addr) +{ + if (isAddrSpaceReg(addr)) { + return spaces[getAddrSpaceNo(addr)].readReg(getAddrSpaceAddr(addr)); + } else { + return GPUBlockInt::readReg(addr); + } +} + +void MMU::writeReg(RegAddr addr, uint32_t value) { switch (addr.value) { @@ -50,11 +71,34 @@ MMU::writeReg(RegAddr addr, uint32_t value) break; default: - // Ignore writes by default + if (isAddrSpaceReg(addr)) { + AddrSpace &as(spaces[getAddrSpaceNo(addr)]); + as.writeReg(getAddrSpaceAddr(addr), value); + } break; }; } +uint32_t +MMU::readRegRaw(RegAddr addr) +{ + if (isAddrSpaceReg(addr)) { + return spaces[getAddrSpaceNo(addr)].readRegRaw(getAddrSpaceAddr(addr)); + } else { + return GPUBlockInt::readRegRaw(addr); + } +} + +void +MMU::writeRegRaw(RegAddr addr, uint32_t value) +{ + if (isAddrSpaceReg(addr)) { + spaces[getAddrSpaceNo(addr)].writeRegRaw(getAddrSpaceAddr(addr), value); + } else { + GPUBlockInt::writeRegRaw(addr, value); + } +} + void MMU::onInterrupt(int set) { diff --git a/ext/nomali/lib/mmu.hh b/ext/nomali/lib/mmu.hh index 82864a6ff..f0381d442 100644 --- a/ext/nomali/lib/mmu.hh +++ b/ext/nomali/lib/mmu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +23,7 @@ #include <vector> #include "gpublock.hh" +#include "addrspace.hh" #include "types.hh" namespace NoMali { @@ -44,12 +45,19 @@ class MMU MMU(GPU &_gpu); virtual ~MMU(); + void reset() override; + + uint32_t readReg(RegAddr idx) override; void writeReg(RegAddr idx, uint32_t value) override; + uint32_t readRegRaw(RegAddr idx) override; + void writeRegRaw(RegAddr idx, uint32_t value) override; + protected: void onInterrupt(int set) override; - RegVector regs; + /** Address spaces belonging to this MMU block */ + std::vector<AddrSpace> spaces; }; } diff --git a/ext/nomali/lib/nomali_api.cc b/ext/nomali/lib/nomali_api.cc index 46f0e7fce..bd556f3c9 100644 --- a/ext/nomali/lib/nomali_api.cc +++ b/ext/nomali/lib/nomali_api.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -59,6 +59,7 @@ class NoMaliApi public: void callbackInt(nomali_int_t intno, int set); + void callbackReset(); private: nomali_callback_t callbacks[NOMALI_CALLBACK_NUM_CALLBACKS]; @@ -76,7 +77,12 @@ class NoMaliApiGpu : BaseGpu(std::forward<Args>(args)...), api(_api) { + reset(); + } + + void reset() override { BaseGpu::reset(); + api.callbackReset(); } public: @@ -205,6 +211,15 @@ NoMaliApi::callbackInt(nomali_int_t intno, int set) c.func.interrupt(static_cast<nomali_handle_t>(this), c.usr, intno, set); } +void +NoMaliApi::callbackReset() +{ + const nomali_callback_t &c(callbacks[NOMALI_CALLBACK_RESET]); + + if (c.func.reset) + c.func.reset(static_cast<nomali_handle_t>(this), c.usr); +} + static NoMaliApi * diff --git a/ext/nomali/lib/regutils.hh b/ext/nomali/lib/regutils.hh index 7957df2b7..841c684c5 100644 --- a/ext/nomali/lib/regutils.hh +++ b/ext/nomali/lib/regutils.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -95,9 +95,53 @@ getJobSlotAddr(const RegAddr &addr) return addr - slot_base; } + /** Number of registers per job slot */ static const unsigned JSn_NO_REGS = 0x20; +/** + * Does this MMU register belong to an address space block? + * + * @return 1 if the address maps to a valid address space block, 0 + * otherwise. + */ +static inline bool +isAddrSpaceReg(const RegAddr &addr) +{ + return addr.value >= MMU_AS0 && addr.value <= 0x7FF; +} + +/** + * Get the address space number owning an address within the MMU + * block. + * + * @param addr Address relative to the JobControl block. + */ +static inline unsigned +getAddrSpaceNo(const RegAddr &addr) +{ + assert(isAddrSpaceReg(addr)); + return (addr.value - MMU_AS0) >> 6; +} + +/** + * Get a AS-relative address from a MMU-relative + * address. + * + * @param addr Address relative to the MMU block. + * @return Address relative the start of the address space block. + */ +static inline RegAddr +getAddrSpaceAddr(const RegAddr &addr) +{ + const unsigned as_no(getAddrSpaceNo(addr)); + const RegAddr as_base(RegAddr(MMU_AS0 + as_no * 0x40)); + return addr - as_base; +} + +/** Number of registers per address space */ +static const unsigned ASn_NO_REGS = 0x10; + } #endif //_LIBNOMALIMODEL_REGUTILS_HH |