diff options
| author | Matt Spinler <spinler@us.ibm.com> | 2017-02-28 10:06:56 -0600 |
|---|---|---|
| committer | Matt Spinler <spinler@us.ibm.com> | 2017-03-14 13:21:34 -0500 |
| commit | 0c0eeff6e991077f6a4570880b01396ac1b9e2e5 (patch) | |
| tree | ce2025957a718053673c0e7ab7318cc6f31dcbad | |
| parent | 4e97ebea445eb89280f9c2745ccc87d0857f00c0 (diff) | |
| download | openpower-proc-control-0c0eeff6e991077f6a4570880b01396ac1b9e2e5.tar.gz openpower-proc-control-0c0eeff6e991077f6a4570880b01396ac1b9e2e5.zip | |
Add code to access P9 CFAM registers
Change-Id: Idd98d016f0d6a246b516b4850e887991c771ae16
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
| -rw-r--r-- | Makefile.am | 1 | ||||
| -rw-r--r-- | cfam_access.cpp | 121 | ||||
| -rw-r--r-- | cfam_access.hpp | 65 | ||||
| -rw-r--r-- | p9_cfam.hpp | 20 |
4 files changed, 207 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index cc2374a..73ea204 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,7 @@ sbin_PROGRAMS = \ openpower_proc_control_SOURCES = \ proc_control.cpp \ + cfam_access.cpp \ p9_procedures.cpp \ filedescriptor.cpp \ targeting.cpp diff --git a/cfam_access.cpp b/cfam_access.cpp new file mode 100644 index 0000000..2762e80 --- /dev/null +++ b/cfam_access.cpp @@ -0,0 +1,121 @@ +/** + * Copyright © 2017 IBM Corporation + * + * 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. + */ +#include <unistd.h> +#include "filedescriptor.hpp" +#include "cfam_access.hpp" +#include "targeting.hpp" + +namespace openpower +{ +namespace cfam +{ +namespace access +{ + +constexpr auto cfamRegSize = 4; + +using namespace openpower::targeting; +using namespace openpower::p9_util; + +/** + * Converts the CFAM register address used by the calling + * code (because that's how it is in the spec) to the address + * required by the device driver. + */ +static inline cfam_address_t makeOffset(cfam_address_t address) +{ + return (address & 0xFC00) | ((address & 0x03FF) << 2); +} + + +void writeReg(const std::unique_ptr<Target>& target, + cfam_address_t address, + cfam_data_t data) +{ + FileDescriptor fd(target->getPath()); + + int rc = lseek(fd(), makeOffset(address), SEEK_SET); + if (rc < 0) + { + //Future: use a different exception to create an error log + char msg[100]; + sprintf(msg, "writeCFAMReg: Failed seek for address 0x%X, " + "processor %d. errno = %d", + address, target->getPos(), errno); + throw std::runtime_error(msg); + } + + rc = write(fd(), &data, cfamRegSize); + if (rc < 0) + { + //Future: use a different exception to create an error log + char msg[100]; + sprintf(msg, "writeCFAMReg: Failed write to address 0x%X, " + "processor %d. errno = %d", + address, target->getPos(), errno); + throw std::runtime_error(msg); + } +} + + +cfam_data_t readReg(const std::unique_ptr<Target>& target, + cfam_address_t address) +{ + FileDescriptor fd(target->getPath()); + cfam_data_t data = 0; + + int rc = lseek(fd(), makeOffset(address), SEEK_SET); + if (rc < 0) + { + //Future: use a different exception to create an error log + char msg[100]; + sprintf(msg, "readCFAMReg: Failed seek for address 0x%X, " + "processor %d. errno = %d", + address, target->getPos(), errno); + throw std::runtime_error(msg); + } + + rc = read(fd(), &data, cfamRegSize); + if (rc < 0) + { + //Future: use a different exception to create an error log + char msg[100]; + sprintf(msg, "readCFAMReg: Failed read for address 0x%X, " + "processor %d. errno = %d", + address, target->getPos(), errno); + throw std::runtime_error(msg); + } + + return data; +} + + +void writeRegWithMask(const std::unique_ptr<Target>& target, + cfam_address_t address, + cfam_data_t data, + cfam_mask_t mask) +{ + cfam_data_t readData = readReg(target, address); + + readData &= ~mask; + readData |= (data & mask); + + writeReg(target, address, readData); +} + +} +} +} diff --git a/cfam_access.hpp b/cfam_access.hpp new file mode 100644 index 0000000..88dcc77 --- /dev/null +++ b/cfam_access.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include <memory> +#include "targeting.hpp" + +namespace openpower +{ +namespace cfam +{ +namespace access +{ + +using cfam_address_t = uint16_t; +using cfam_data_t = uint32_t; +using cfam_mask_t = uint32_t; + +/** + * @brief Writes a CFAM (Common FRU Access Macro) register in a P9. + * + * Throws an exception on error. + * + * @param[in] target - The Target to perform the operation on + * @param[in] address - The register address to write to + * @param[in] data - The data to write + */ +void writeReg(const std::unique_ptr<openpower::targeting::Target>& target, + cfam_address_t address, + cfam_data_t data); + + +/** + * @brief Reads a CFAM (Common FRU Access Macro) register in a P9. + * + * Throws an exception on error. + * + * @param[in] target - The Target to perform the operation on + * @param[in] address - The register address to read + * @return - The register data + */ +cfam_data_t readReg( + const std::unique_ptr<openpower::targeting::Target>& target, + cfam_address_t address); + + +/** + * @brief Writes a CFAM (Common FRU Access Macro) register in a P9 + * using a mask to specify the bits the modify. + * + * Only bits that are set in the mask parameter will be modified. + * + * Throws an exception on error. + * + * @param[in] target - The Target to perform the operation on + * @param[in] address - The register address to write to + * @param[in] data - The data to write + * @param[in] mask - The mask + */ +void writeRegWithMask( + const std::unique_ptr<openpower::targeting::Target>& target, + cfam_address_t address, + cfam_data_t data, + cfam_mask_t mask); +} +} +} diff --git a/p9_cfam.hpp b/p9_cfam.hpp new file mode 100644 index 0000000..d8fa5ff --- /dev/null +++ b/p9_cfam.hpp @@ -0,0 +1,20 @@ +#pragma once + +namespace openpower +{ +namespace cfam +{ +namespace p9 +{ +static constexpr uint16_t P9_FSI_A_SI1S = 0x081C; +static constexpr uint16_t P9_LL_MODE_REG = 0x0840; +static constexpr uint16_t P9_FSI2PIB_INTERRUPT = 0x100B; +static constexpr uint16_t P9_FSI2PIB_TRUE_MASK = 0x100D; +static constexpr uint16_t P9_CBS_CS = 0x2801; +static constexpr uint16_t P9_ROOT_CTRL0 = 0x2810; +static constexpr uint16_t P9_PERV_CTRL0 = 0x281A; +static constexpr uint16_t P9_SCRATCH_REGISTER_8 = 0x283F; +static constexpr uint16_t P9_ROOT_CTRL8 = 0x2918; +} +} +} |

