diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-05-18 11:49:26 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-06-02 09:54:48 -0500 |
commit | 83e18669b6c2322c8eb5f8632ac823877d765e0d (patch) | |
tree | 780c62fbc578e5a3b6c362db40b84e468611dd13 /src/include/usr/devicefw | |
parent | 40d7b75141080adb8b42cc5ea058c91944e7621e (diff) | |
download | blackbird-hostboot-83e18669b6c2322c8eb5f8632ac823877d765e0d.tar.gz blackbird-hostboot-83e18669b6c2322c8eb5f8632ac823877d765e0d.zip |
Device Framework support.
Change-Id: I133f58df309c7fc3a7faa261699eba66a6bae4be
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/98
Tested-by: Jenkins Server
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Diffstat (limited to 'src/include/usr/devicefw')
-rw-r--r-- | src/include/usr/devicefw/driverif.H | 250 | ||||
-rw-r--r-- | src/include/usr/devicefw/userif.H | 108 |
2 files changed, 358 insertions, 0 deletions
diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H new file mode 100644 index 000000000..ceff91c59 --- /dev/null +++ b/src/include/usr/devicefw/driverif.H @@ -0,0 +1,250 @@ +/** @file driverif.H + * @brief Provides the device driver interfaces for performing device access + * and enabling routing registration. + * + * @note These interfaces should only be used by device drivers. User code + * wanting to perform device operations should use userif.H instead. + */ +#ifndef __DEVICEFW_DRIVERIF +#define __DEVICEFW_DRIVERIF + +#include <devicefw/userif.H> +#include <stdarg.h> +#include <builtins.h> + +namespace DeviceFW +{ + /** TODO: Update these to real target handle type once that piece of + * code is complete */ + enum TargetType_t + { + PROCESSOR = 0, + + LAST_TARGET_TYPE + }; + + /** @enum AccessType_DriverOnly + * @brief Access types to be used internally by drivers for routing + * requests to other drivers. + */ + enum AccessType_DriverOnly + { + XSCOM = LAST_ACCESS_TYPE, + FSISCOM, + + LAST_DRIVER_ACCESS_TYPE + }; + + /** @enum OperationType + * @brief Set of operations which can be registered for. + */ + enum OperationType + { + READ = 0, + WRITE, + + LAST_OP_TYPE + + }; + + /** @enum DriverSpecial + * @brief Special Wildcard enum that can be used for drivers to do + * routing registrations. + */ + enum DriverSpecial + { + WILDCARD = -1, + }; + + /** @class InvalidParameterType + * @brief Unused type to cause compiler fails for invalid template types. + * + * Forward Declaration of type that is never actually used anywhere. + * + * Assists in making more developer friendly compiler fails when a + * template function is called for which there is no specialization and + * the default template function should never be used. This is used for + * allowing function calls that take multiple enum types but still provide + * type-safety above a int-parameter. + */ + class InvalidParameterType; + + /** @typedef deviceOp_t + * @brief Function prototype for registered device-driver operations. + */ + typedef ErrorHandle_t(*deviceOp_t)(OperationType, + TargetHandle_t, + void*, size_t&, + int64_t, va_list); + + /** + * @brief Register a device driver routing function with the framework. + * + * @param[in] i_opType - Enumeration specifying the operation this + * driver performs. (Read, Write, Wildcard) + * @param[in] i_accessType - Enumeration specifying the access type this + * driver performs. (SCOM, XSCOM, PNOR, etc.) + * @param[in] i_targetType - Enumeration specifying the target type this + * driver performs. (Proc, MC, Wildcard, etc.) + * @param[in] i_regRoute - The function being registered. + * + * This function call be called to register a device driver routing + * function with the framework. If it is desired to always register a + * device driver when the module associated with that driver is loaded, + * the DEVICE_REGISTER_ROUTE macro can be used. + * + * <PRE> + * Example usage: + * // High-level address manipulation routing function. + * deviceRegisterRoute(WILDCARD, + * SCOM, + * MEMORY_CONTROLLER, + * &scomAdjustMCAddresses); + * + * // Low-level (internal) XSCOM read operation. + * deviceRegisterRoute(READ, + * XSCOM, + * PROCESSOR, + * &xscomPerformRead); + * </PRE> + * + * @note Valid OpType are OperatorType enum or WILDCARD. + * @note Valid TargType are TargetType enum or WILDCARD. + * @note Valid AccType are AccessType or AccessType_DriverOnly; WILDCARD is + * not permitted. + * + * @note Any unsupported enumeration type will result in a compile error + * referencing a InvalidParameterType class. + */ + template <typename OpType, typename AccType, typename TargType> + void deviceRegisterRoute(OpType i_opType, + AccType i_accessType, + TargType i_targetType, + deviceOp_t i_regRoute) + { + return InvalidParameterType(); // Cause a compile fail if not one of + // the explicit template specializations. + } + + /** Assistance macro for stringification. */ + #define __DEVICE_REGISTER_ROUTE_XY(X,Y) X##Y + /** Assistance macro for stringification. */ + #define __DEVICE_REGISTER_ROUTE_MAKENAME(X,Y) __DEVICE_REGISTER_ROUTE_XY(X,Y) + + /** + * @brief Create a static constructed registration of a device driver + * function when a module is loaded. + * + * Parameters are the same as DeviceFW::deviceRegisterRoute, except the + * route function should be passed by name as opposed to pointer. + * + * If the route function is in a namespace, then this definition must + * also be placed into that namespace. + */ + #define DEVICE_REGISTER_ROUTE(i_opType, i_accessType, \ + i_targetType, i_regRoute) \ + class __DEVICE_REGISTER_ROUTE_MAKENAME(DeviceRouteRegistrator_, \ + i_regRoute) \ + { \ + public: \ + __DEVICE_REGISTER_ROUTE_MAKENAME(DeviceRouteRegistrator_, \ + i_regRoute)() \ + { \ + DeviceFW::deviceRegisterRoute(i_opType, i_accessType, \ + i_targetType, &i_regRoute); \ + } \ + }; \ + __DEVICE_REGISTER_ROUTE_MAKENAME(DeviceRouteRegistrator_, i_regRoute) \ + __DEVICE_REGISTER_ROUTE_MAKENAME(DeviceRouteRegistrator_instance_, \ + i_regRoute); + + /** + * @brief Perform a device operation by routing through the framework and + * calling the appropriate registered operation. + * + * @param[in] i_opType - Operation request (READ vs WRITE). + * @param[in] i_target - Target to perform operation on. + * @param[in,out] io_buffer - Data buffer for operation. + * @param[in,out] io_buflen - Length of buffer / result size. + * @param[in] i_accessType - Type of hardware access method to perform. + * + * This function has similar behavior as the user-visible deviceRead and + * deviceWrite functions and is meant as a method for device drivers to + * perform accesses which may be only visible to internal drivers. + */ + template <typename AccType> + ErrorHandle_t deviceOp(OperationType i_opType, + TargetHandle_t i_target, + void* io_buffer, size_t& io_buflen, + AccType i_accessType, ...) + { + return InvalidParameterType(); // Cause a compile fail if not one of + // the explicit template specializations. + } + + // --- Below are template specializations to aid in type-safety. --- + + // deviceRegisterRoute: + // OpType - OperationType or WILDCARD + // TargType - TargetType or WILDCARD + // AccType - AccessType, AccessType_DriverOnly (no WILDCARD). + + template <> + void deviceRegisterRoute<>(OperationType i_opType, + AccessType i_accessType, + TargetType_t i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(OperationType i_opType, + AccessType_DriverOnly i_accessType, + TargetType_t i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(OperationType i_opType, + AccessType i_accessType, + DriverSpecial i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(OperationType i_opType, + AccessType_DriverOnly i_accessType, + DriverSpecial i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(DriverSpecial i_opType, + AccessType i_accessType, + TargetType_t i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(DriverSpecial i_opType, + AccessType_DriverOnly i_accessType, + TargetType_t i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(DriverSpecial i_opType, + AccessType i_accessType, + DriverSpecial i_targetType, + deviceOp_t i_regRoute); + template <> + void deviceRegisterRoute<>(DriverSpecial i_opType, + AccessType_DriverOnly i_accessType, + DriverSpecial i_targetType, + deviceOp_t i_regRoute); + + // deviceOp: + // OpType - OperationType only. + // TargType - TargetType only. + // AccType - AccessType, AccessType_DriverOnly (no WILDCARD). + template <> + ErrorHandle_t deviceOp<>(OperationType i_opType, + TargetHandle_t i_target, + void* io_buffer, size_t& io_buflen, + AccessType i_accessType, ...); + template <> + ErrorHandle_t deviceOp<>(OperationType i_opType, + TargetHandle_t i_target, + void* io_buffer, size_t& io_buflen, + AccessType_DriverOnly i_accessType, ...); + +}; + +#endif diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H new file mode 100644 index 000000000..dc4cbd4c7 --- /dev/null +++ b/src/include/usr/devicefw/userif.H @@ -0,0 +1,108 @@ +/** @file userif.H + * @brief Provides the user application interfaces for performing device + * access. + * + * @note These interfaces should not be used directly by device drivers. + * Use driverif.H instead. + */ + +#ifndef __DEVICEFW_USERIF +#define __DEVICEFW_USERIF + +#include <stdint.h> + +namespace DeviceFW +{ + /* TODO: Update these to real error log / target handle type once those + * pieces of code are complete. */ + typedef void* ErrorHandle_t; + typedef int TargetHandle_t; + + /** @enum AccessType + * @brief Access types for accessing a hardware device. + */ + enum AccessType + { + SCOM = 0, + PNOR, + MAILBOX, + PRESENT, + + LAST_ACCESS_TYPE, + }; + + /** Construct the device addressing parameters for SCOM device ops. + * @param[in] i_address - Scom address to operate on. + */ + #define DEVICE_SCOM_ADDRESS(i_address) \ + DeviceFW::SCOM, static_cast<uint64_t>((i_address)) + + /** Construct the device addressing parameters for the PRESENT device ops. + */ + #define DEVICE_PRESENT_ADDRESS() \ + DeviceFW::PRESENT + + /** + * @brief Perform a hardware read operation. + * + * @param[in] i_target Device target to operate on. + * @param[out] o_buffer Buffer to put result data into. + * @param[in,out] io_buflen Length of the buffer on input, length of + * data on output (in bytes). + * @param[in] i_accessType Operation to perform on target. + * @param[in] ... Operation specific addressing parameters. + * + * @return NULL - No error. + * @return Non-NULL - An error handle when error has occured, typically + * passed directly from device driver but potentially + * created by the device framework as in the case of + * not finding an installed driver for the desired + * operation. + * + * It is expected that the callers will use operation specific macros to + * assist in the AccessType parameter and variable arguments. + * + * <PRE> + * Example usage: + * errl = deviceRead(chip, buf, bufsize, DEVICE_SCOM_ADDRESS(0x42)); + * </PRE> + * + */ + ErrorHandle_t deviceRead(TargetHandle_t i_target, + void* o_buffer, size_t& io_buflen, + AccessType i_accessType, ...); + + /** + * @brief Perform a hardware write operation. + * + * @param[in] i_target Device target to operate on. + * @param[in] i_buffer Buffer to get write data from. + * @param[in,out] io_buflen Length of the buffer on input, length of + * data on output (in bytes). + * @param[in] i_accessType Operation to perform on target. + * @param[in] ... Operation specific addressing parameters. + * + * @return NULL - No error. + * @return Non-NULL - An error handle when error has occured, typically + * passed directly from device driver but potentially + * created by the device framework as in the case of + * not finding an installed driver for the desired + * operation. + * + * It is expected that the callers will use operation specific macros to + * assist in the AccessType parameter and variable arguments. + * + * <PRE> + * Example usage: + * errl = deviceWrite(chip, buf, bufsize, DEVICE_SCOM_ADDRESS(0x42)); + * </PRE> + * + */ + ErrorHandle_t deviceWrite(TargetHandle_t i_target, + void* i_buffer, size_t& io_buflen, + AccessType i_accessType, ...); + +}; + + +#endif |