├── LICENSE ├── Makefile ├── README.md ├── linux_port.h ├── mxc_scc2_driver.h ├── portable_os.h ├── scc2_aes_dev.c ├── scc2_aes_test.c ├── scc2_driver.c ├── scc2_internals.h └── scc2_test /LICENSE: -------------------------------------------------------------------------------- 1 | NXP Security Controller (SCCv2) - Linux driver 2 | https://github.com/usbarmory/mxc-scc2 3 | 4 | Copyright (c) WithSecure Corporation 5 | Copyright (c) Inverse Path S.r.l. 6 | Copyright (c) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. 7 | 8 | This program is free software: you can redistribute it and/or modify it under 9 | the terms of the GNU General Public License as published by the Free Software 10 | Foundation under version 3 of the License. 11 | 12 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 14 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | KERNEL_SRC = /lib/modules/$(shell uname -r)/build 2 | 3 | obj-m += scc2.o scc2_aes.o 4 | scc2-y := scc2_driver.o 5 | scc2_aes-y := scc2_aes_dev.o 6 | 7 | ccflags-y := -march=armv7-a 8 | 9 | all: 10 | make -C ${KERNEL_SRC} M=$(CURDIR) modules 11 | 12 | modules_install: 13 | make -C ${KERNEL_SRC} M=$(CURDIR) modules_install 14 | 15 | clean: 16 | make -C ${KERNEL_SRC} M=$(CURDIR) clean 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NXP Security Controller (SCCv2) - Linux driver 2 | ============================================== 3 | 4 | The SCCv2 is a built-in hardware module for the NXP i.MX53 SoC that implements 5 | secure RAM and a dedicated AES cryptographic engine for encryption/decryption 6 | operations. 7 | 8 | A device specific random 256-bit SCC key is fused in each SoC at manufacturing 9 | time, this key is unreadable and can only be used with the SCCv2 for AES 10 | encryption/decryption of user data. 11 | 12 | This directory contains a Linux kernel driver for the SCCv2 and an additional 13 | interfacing module, which allocates character device `/dev/scc2_aes` for 14 | userspace encryption and decryption operations. 15 | 16 | The kernel driver is a port of the original Freescale one for Linux 3.x with 17 | assorted bugfixes and the addition of a new separate character device driver. 18 | 19 | Authors 20 | ======= 21 | 22 | Andrea Barisani 23 | andrea@inversepath.com 24 | 25 | Andrej Rosano 26 | andrej@inversepath.com 27 | 28 | Based on a driver from Freescale Semiconductor, Inc., additional thanks to 29 | Julian Horsch for its contribution to the 30 | port. 31 | 32 | Compiling 33 | ========= 34 | 35 | *NOTE*: USB armory users can automate Linux kernel compilation, along with the 36 | mxc-scc2 driver, using the Makefile (`mxc-scc2` target) from its Debian base image 37 | [repository](https://github.com/usbarmory/usbarmory-debian-base_image). 38 | 39 | The following instructions assume compilation on a native armv7 architecture, 40 | when cross compiling adjust `ARCH` and `CROSS_COMPILE` variables accordingly. 41 | 42 | ``` 43 | # the Makefile attempts to locate your Linux kernel source tree, if this fails 44 | # it can be passed with a Makefile variable (e.g. `make KERNEL_SRC=path`) 45 | git clone https://github.com/usbarmory/mxc-scc2 46 | cd mxc-scc2 47 | make 48 | make modules_install 49 | ``` 50 | 51 | Once installed the two resulting modules can be loaded in the traditional 52 | manner: 53 | 54 | ``` 55 | modprobe scc2 # SCCv2 driver 56 | modprobe scc2_aes # character device driver for userspace access 57 | ``` 58 | 59 | The probing of the SCCv2 module depends on its Device Tree (dts) inclusion in 60 | running Linux kernel. The following example is taken from the USB armory 61 | [dts](https://github.com/usbarmory/usbarmory/blob/master/software/kernel_conf/mark-one/imx53-usbarmory-scc2.dts) 62 | which includes the SCCv2 device for its i.MX53 SoC: 63 | 64 | ``` 65 | soc { 66 | aips@60000000 { 67 | scc2: scc2@63fb4000 { 68 | compatible = "fsl,imx53-scc2"; 69 | reg = <0x63fb4000 0x4000>, 70 | <0x07000000 0x4000>; 71 | interrupts = <21 23>; 72 | }; 73 | }; 74 | }; 75 | ``` 76 | 77 | Operation 78 | ========= 79 | 80 | **IMPORTANT**: the SCCv2 internal key is available only when Secure Boot (HAB) 81 | is enabled, otherwise the AES-256 NIST standard test key is set. The secure 82 | operation of the SCCv2, in production deployments, should always be paired with 83 | Secure Boot activation. 84 | 85 | The `scc2_aes` module, when not in Secure State, issues the following warning 86 | at load time: 87 | 88 | ``` 89 | scc2_aes: WARNING - not in Secure State, NIST test key in effect 90 | ``` 91 | 92 | When Secure State is correctly detected the module issues following message at 93 | load time: 94 | 95 | ``` 96 | scc2_aes: Secure State detected 97 | ``` 98 | 99 | 100 | The following IOCTLs are defined for character device `/dev/scc2_aes`: 101 | 102 | ``` 103 | ioctl(file, SET_MODE, ENCRYPT_CBC) 104 | Sets AES-256 encryption with Cipher Block Chaining (CBC) 105 | 106 | ioctl(file, SET_MODE, DECRYPT_CBC) 107 | Sets AES-256 decryption with Cipher Block Chaining (CBC) 108 | 109 | ioctl(file, SET_IV, (char *) iv) 110 | Sets the Initialization Vector (IV), this is required only once before 111 | encryption/decryption. After the first block ciphersing the SCCv2 112 | internally updates the IV in CBC mode. 113 | ``` 114 | 115 | Once the mode and IV are set, plaintext/ciphertext can be sent to the SCCv2 for 116 | encryption/decryption by issuing a `write()` operation of 16-bytes blocks on 117 | `/dev/scc2_aes`, up to 256 blocks (4096 bytes) can be sent at once. 118 | 119 | Each `write()` operation must be followed by a `read()` of the same size to 120 | read back the results, inconsistent operations will cause errors. 121 | 122 | Example (psuedocode): 123 | ``` 124 | fd = open("/dev/scc2_aes", O_RDWR) 125 | 126 | ioctl(fd, SET_IV, iv) 127 | 128 | ioctl(fd, SET_MODE, ENCRYPT_CBC) 129 | write(fd, plaintext, 4096) 130 | read(fd, ciphertext, 4096) 131 | 132 | ioctl(fd, SET_MODE, DECRYPT_CBC) 133 | write(fd, ciphertext, 4096) 134 | read(fd, plaintext, 4096) 135 | ``` 136 | 137 | The [INTERLOCK](https://github.com/usbarmory/interlock) file encryption 138 | front-end supports the SCCv2 through this driver, providing a Go userspace 139 | implementation reference. 140 | 141 | Another userspace example usage, with OpenSSL test comparison, is provided in 142 | the [scc2_test](https://github.com/usbarmory/mxc-scc2/blob/master/scc2_test) 143 | Ruby script. The following reference output illustrates a test run on a 144 | [USB armory](https://github.com/usbarmory/usbarmory) without Secure Boot enabled. 145 | The OpenSSL and SCCv2 output comparison of the `scc2_test` script can only 146 | match on units that do not have HAB enabled. 147 | 148 | ``` 149 | NIST test AES-256 key: 603deb1015ca71be2b73aef0857d7781 150 | 1f352c073b6108d72d9810a30914dff4 151 | initialization vector: 000102030405060708090a0b0c0d0e0f 152 | plaintext: 6bc1bee22e409f96e93d7e117393172a 153 | 154 | ciphertext block 1 (OpenSSL): f58c4c04d6e5f1ba779eabfb5f7bfbd6 155 | ciphertext block 1 (SCCv2): f58c4c04d6e5f1ba779eabfb5f7bfbd6 156 | ciphertext block 2 (OpenSSL): eb2d9e942831bd84dff00db9776b8088 157 | ciphertext block 2 (SCCv2): eb2d9e942831bd84dff00db9776b8088 158 | match! 159 | 160 | plaintext block 1 (OpenSSL): 6bc1bee22e409f96e93d7e117393172a 161 | plaintext block 1 (SCCv2): 6bc1bee22e409f96e93d7e117393172a 162 | plaintext block 2 (OpenSSL): 6bc1bee22e409f96e93d7e117393172a 163 | plaintext block 2 (SCCv2): 6bc1bee22e409f96e93d7e117393172a 164 | match! 165 | ``` 166 | 167 | License 168 | ======= 169 | 170 | NXP Security Controller (SCCv2) - Linux driver 171 | https://github.com/usbarmory/mxc-scc2 172 | 173 | Copyright (c) WithSecure Corporation 174 | Copyright (c) Inverse Path S.r.l. 175 | Copyright (c) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. 176 | 177 | This program is free software: you can redistribute it and/or modify it under 178 | the terms of the GNU General Public License as published by the Free Software 179 | Foundation under version 3 of the License. 180 | 181 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 182 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 183 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 184 | 185 | Permission to use, copy, modify, and distribute this software for any purpose 186 | with or without fee is hereby granted, provided that the above copyright notice 187 | and this permission notice appear in all copies. 188 | -------------------------------------------------------------------------------- /linux_port.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. 3 | */ 4 | 5 | /* 6 | * The code contained herein is licensed under the GNU General Public 7 | * License. You may obtain a copy of the GNU General Public License 8 | * Version 2 or later at the following locations: 9 | * 10 | * http://www.opensource.org/licenses/gpl-license.html 11 | * http://www.gnu.org/copyleft/gpl.html 12 | */ 13 | 14 | /*! 15 | * @file linux_port.h 16 | * 17 | * OS_PORT ported to Linux (2.6.9+ for now) 18 | * 19 | */ 20 | 21 | /*! 22 | * @if USE_MAINPAGE 23 | * @mainpage ==Linux version of== Generic OS API for STC Drivers 24 | * @endif 25 | * 26 | * @section intro_sec Introduction 27 | * 28 | * This API / kernel programming environment blah blah. 29 | * 30 | * See @ref dkops "Driver-to-Kernel Operations" as a good place to start. 31 | */ 32 | 33 | #ifndef LINUX_PORT_H 34 | #define LINUX_PORT_H 35 | 36 | #define PORTABLE_OS_VERSION 101 37 | 38 | /* Linux Kernel Includes */ 39 | #include /* Current version Linux kernel */ 40 | 41 | #if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS) 42 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 43 | #include 44 | #endif 45 | #define MODVERSIONS 46 | #endif 47 | /*! 48 | * __NO_VERSION__ defined due to Kernel module possibly spanning multiple 49 | * files. 50 | */ 51 | #define __NO_VERSION__ 52 | 53 | #include /* Basic support for loadable modules, 54 | printk */ 55 | #include /* module_init, module_exit */ 56 | #include /* General kernel system calls */ 57 | #include /* for interrupt.h */ 58 | #include /* for inode */ 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include /* kmalloc */ 64 | 65 | #include 66 | 67 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 68 | #include /* used in dynamic power management */ 69 | #else 70 | #include /* used in dynamic power management */ 71 | #endif 72 | 73 | #include 74 | #include 75 | 76 | #include /* clock en/disable for DPM */ 77 | 78 | #include 79 | #include 80 | 81 | #include /* copy_to_user(), copy_from_user() */ 82 | #include /* ioremap() */ 83 | #include 84 | #include 85 | 86 | #ifndef TRUE 87 | /*! Useful symbol for unsigned values used as flags. */ 88 | #define TRUE 1 89 | #endif 90 | 91 | #ifndef FALSE 92 | /*! Useful symbol for unsigned values used as flags. */ 93 | #define FALSE 0 94 | #endif 95 | 96 | /* These symbols are defined in Linux 2.6 and later. Include here for minimal 97 | * support of 2.4 kernel. 98 | **/ 99 | #if !defined(LINUX_VERSION_CODE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 100 | /*! 101 | * Symbol defined somewhere in 2.5/2.6. It is the return signature of an ISR. 102 | */ 103 | #define irqreturn_t void 104 | /*! Possible return value of 'modern' ISR routine. */ 105 | #define IRQ_HANDLED 106 | /*! Method of generating value of 'modern' ISR routine. */ 107 | #define IRQ_RETVAL(x) 108 | #endif 109 | 110 | /*! 111 | * Type used for registering and deregistering interrupts. 112 | */ 113 | typedef int os_interrupt_id_t; 114 | 115 | /*! 116 | * Type used as handle for a process 117 | * 118 | * See #os_get_process_handle() and #os_send_signal(). 119 | */ 120 | /* 121 | * The following should be defined this way, but it gets compiler errors 122 | * on the current tool chain. 123 | * 124 | * typedef task_t *os_process_handle_t; 125 | */ 126 | 127 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 128 | typedef task_t *os_process_handle_t; 129 | #else 130 | typedef struct task_struct *os_process_handle_t; 131 | #endif 132 | 133 | /*! 134 | * Generic return code for functions which need such a thing. 135 | * 136 | * No knowledge should be assumed of the value of any of these symbols except 137 | * that @c OS_ERROR_OK_S is guaranteed to be zero. 138 | */ 139 | typedef enum { 140 | OS_ERROR_OK_S = 0, /*!< Success */ 141 | OS_ERROR_FAIL_S = -EIO, /*!< Generic driver failure */ 142 | OS_ERROR_NO_MEMORY_S = -ENOMEM, /*!< Failure to acquire/use memory */ 143 | OS_ERROR_BAD_ADDRESS_S = -EFAULT, /*!< Bad address */ 144 | OS_ERROR_BAD_ARG_S = -EINVAL, /*!< Bad input argument */ 145 | } os_error_code; 146 | 147 | /*! 148 | * Handle to a lock. 149 | */ 150 | #ifdef CONFIG_PREEMPT_RT 151 | typedef raw_spinlock_t *os_lock_t; 152 | #else 153 | typedef spinlock_t *os_lock_t; 154 | #endif 155 | 156 | /*! 157 | * Context while locking. 158 | */ 159 | typedef unsigned long os_lock_context_t; 160 | 161 | /*! 162 | * Declare a wait object for sleeping/waking processes. 163 | */ 164 | #define OS_WAIT_OBJECT(name) \ 165 | DECLARE_WAIT_QUEUE_HEAD(name##_qh) 166 | 167 | /*! 168 | * Driver registration handle 169 | * 170 | * Used with #os_driver_init_registration(), #os_driver_add_registration(), 171 | * and #os_driver_complete_registration(). 172 | */ 173 | typedef struct { 174 | unsigned reg_complete; /*!< TRUE if next inits succeeded. */ 175 | dev_t dev; /*!< dev_t for register_chrdev() */ 176 | struct file_operations fops; /*!< struct for register_chrdev() */ 177 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) 178 | struct class_simple *cs; /*!< results of class_simple_create() */ 179 | #else 180 | struct class *cs; /*!< results of class_create() */ 181 | #endif 182 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) 183 | struct class_device *cd; /*!< Result of class_device_create() */ 184 | #else 185 | struct device *cd; /*!< Result of device_create() */ 186 | #endif 187 | unsigned power_complete; /*!< TRUE if next inits succeeded */ 188 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 189 | struct device_driver dd; /*!< struct for register_driver() */ 190 | #else 191 | struct platform_driver dd; /*!< struct for register_driver() */ 192 | #endif 193 | struct platform_device pd; /*!< struct for platform_register_device() */ 194 | } os_driver_reg_t; 195 | 196 | /* 197 | * Function types which can be associated with driver entry points. 198 | * 199 | * Note that init and shutdown are absent. 200 | */ 201 | /*! @{ */ 202 | /*! Keyword for registering open() operation handler. */ 203 | #define OS_FN_OPEN open 204 | /*! Keyword for registering close() operation handler. */ 205 | #define OS_FN_CLOSE release 206 | /*! Keyword for registering read() operation handler. */ 207 | #define OS_FN_READ read 208 | /*! Keyword for registering write() operation handler. */ 209 | #define OS_FN_WRITE write 210 | /*! Keyword for registering ioctl() operation handler. */ 211 | #define OS_FN_IOCTL unlocked_ioctl 212 | /*! Keyword for registering mmap() operation handler. */ 213 | #define OS_FN_MMAP mmap 214 | /*! @} */ 215 | 216 | /*! 217 | * Function signature for the portable interrupt handler 218 | * 219 | * While it would be nice to know which interrupt is being serviced, the 220 | * Least Common Denominator rule says that no arguments get passed in. 221 | * 222 | * @return Zero if not handled, non-zero if handled. 223 | */ 224 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 225 | typedef int (*os_interrupt_handler_t) (int, void *, struct pt_regs *); 226 | #else 227 | typedef int (*os_interrupt_handler_t) (int, void *); 228 | #endif 229 | 230 | /*! 231 | * @defgroup dkops Driver-to-Kernel Operations 232 | * 233 | * These are the operations which drivers should call to get the OS to perform 234 | * services. 235 | */ 236 | 237 | /*! @addtogroup dkops */ 238 | /*! @{ */ 239 | 240 | /*! 241 | * Register an interrupt handler. 242 | * 243 | * @param driver_name The name of the driver 244 | * @param interrupt_id The interrupt line to monitor (type 245 | * #os_interrupt_id_t) 246 | * @param function The function to be called to handle an interrupt 247 | * 248 | * @return #os_error_code 249 | */ 250 | #define os_register_interrupt(driver_name, interrupt_id, function) \ 251 | request_irq(interrupt_id, function, 0, driver_name, NULL) 252 | 253 | /*! 254 | * Deregister an interrupt handler. 255 | * 256 | * @param interrupt_id The interrupt line to stop monitoring 257 | * 258 | * @return #os_error_code 259 | */ 260 | #define os_deregister_interrupt(interrupt_id) \ 261 | free_irq(interrupt_id, NULL) 262 | 263 | /*! 264 | * INTERNAL implementation of os_driver_init_registration() 265 | * 266 | * @return An os error code. 267 | */ 268 | inline static int os_drv_do_init_reg(os_driver_reg_t * handle) 269 | { 270 | memset(handle, 0, sizeof(*handle)); 271 | handle->fops.owner = THIS_MODULE; 272 | handle->power_complete = FALSE; 273 | handle->reg_complete = FALSE; 274 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 275 | handle->dd.name = NULL; 276 | #else 277 | handle->dd.driver.name = NULL; 278 | #endif 279 | 280 | return OS_ERROR_OK_S; 281 | } 282 | 283 | /*! 284 | * Initialize driver registration. 285 | * 286 | * If the driver handles open(), close(), ioctl(), read(), write(), or mmap() 287 | * calls, then it needs to register their location with the kernel so that they 288 | * get associated with the device. 289 | * 290 | * @param handle The handle object to be used with this registration. The 291 | * object must live (be in memory somewhere) at least until 292 | * os_driver_remove_registration() is called. 293 | * 294 | * @return A handle for further driver registration, or NULL if failed. 295 | */ 296 | #define os_driver_init_registration(handle) \ 297 | os_drv_do_init_reg(&handle) 298 | 299 | /*! 300 | * Add a function registration to driver registration. 301 | * 302 | * @param handle A handle initialized by #os_driver_init_registration(). 303 | * @param name Which function is being supported. 304 | * @param function The result of a call to a @c _REF version of one of the 305 | * driver function signature macros 306 | * @return void 307 | */ 308 | #define os_driver_add_registration(handle, name, function) \ 309 | do {handle.fops.name = (void*)(function); } while (0) 310 | 311 | /*! 312 | * Record 'power suspend' function for the device. 313 | * 314 | * @param handle A handle initialized by #os_driver_init_registration(). 315 | * @param function Name of function to call on power suspend request 316 | * 317 | * Status: Provisional 318 | * 319 | * @return void 320 | */ 321 | #define os_driver_register_power_suspend(handle, function) \ 322 | handle.dd.suspend = function 323 | 324 | /*! 325 | * Record 'power resume' function for the device. 326 | * 327 | * @param handle A handle initialized by #os_driver_init_registration(). 328 | * @param function Name of function to call on power resume request 329 | * 330 | * Status: Provisional 331 | * 332 | * @return void 333 | */ 334 | #define os_driver_register_resume(handle, function) \ 335 | handle.dd.resume = function 336 | 337 | /*! 338 | * INTERNAL function of the Linux port of the OS API. Implements the 339 | * os_driver_complete_registration() function. 340 | * 341 | * @param handle The handle used with #os_driver_init_registration(). 342 | * @param major The major device number to be associated with the driver. 343 | * If this value is zero, a major number may be assigned. 344 | * See #os_driver_get_major() to determine final value. 345 | * #os_driver_remove_registration(). 346 | * @param driver_name The driver name. Can be used as part of 'device node' 347 | * name on platforms which support such a feature. 348 | * 349 | * @return An error code 350 | */ 351 | inline static int os_drv_do_reg(os_driver_reg_t * handle, 352 | unsigned major, char *driver_name) 353 | { 354 | os_error_code code = OS_ERROR_NO_MEMORY_S; 355 | char *name = kmalloc(strlen(driver_name) + 1, 0); 356 | 357 | if (name != NULL) { 358 | memcpy(name, driver_name, strlen(driver_name) + 1); 359 | code = OS_ERROR_OK_S; /* OK so far */ 360 | /* If any chardev/POSIX routines were added, then do chrdev part */ 361 | if (handle->fops.open || handle->fops.release 362 | || handle->fops.read || handle->fops.write 363 | || handle->fops.unlocked_ioctl || handle->fops.mmap) { 364 | 365 | printk("ioctl pointer: %p. mmap pointer: %p\n", 366 | handle->fops.unlocked_ioctl, handle->fops.mmap); 367 | 368 | /* this method is depricated, see: 369 | * http://lwn.net/Articles/126808/ 370 | */ 371 | code = 372 | register_chrdev(major, driver_name, &handle->fops); 373 | 374 | /* instead something like this: */ 375 | #if 0 376 | handle->dev = MKDEV(major, 0); 377 | code = 378 | register_chrdev_region(handle->dev, 1, driver_name); 379 | if (code < 0) { 380 | code = OS_ERROR_FAIL_S; 381 | } else { 382 | cdev_init(&handle->cdev, &handle->fops); 383 | code = cdev_add(&handle->cdev, major, 1); 384 | } 385 | #endif 386 | 387 | if (code < 0) { 388 | code = OS_ERROR_FAIL_S; 389 | } else { 390 | if (code != 0) { 391 | /* Zero was passed in for major; code is actual value */ 392 | handle->dev = MKDEV(code, 0); 393 | } else { 394 | handle->dev = MKDEV(major, 0); 395 | } 396 | code = OS_ERROR_OK_S; 397 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) 398 | handle->cs = 399 | class_simple_create(THIS_MODULE, 400 | driver_name); 401 | if (IS_ERR(handle->cs)) { 402 | code = (os_error_code) handle->cs; 403 | handle->cs = NULL; 404 | } else { 405 | handle->cd = 406 | class_simple_device_add(handle->cs, 407 | handle->dev, 408 | NULL, 409 | driver_name); 410 | if (IS_ERR(handle->cd)) { 411 | class_simple_device_remove 412 | (handle->dev); 413 | unregister_chrdev(MAJOR 414 | (handle->dev), 415 | driver_name); 416 | code = 417 | (os_error_code) handle->cs; 418 | handle->cs = NULL; 419 | } else { 420 | handle->reg_complete = TRUE; 421 | } 422 | } 423 | #else 424 | handle->cs = 425 | #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) 426 | class_create(THIS_MODULE, driver_name); 427 | #else 428 | class_create(driver_name); 429 | #endif 430 | if (IS_ERR(handle->cs)) { 431 | code = (os_error_code) handle->cs; 432 | handle->cs = NULL; 433 | } else { 434 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) 435 | handle->cd = 436 | class_device_create(handle->cs, 437 | NULL, 438 | handle->dev, 439 | NULL, 440 | driver_name); 441 | #else 442 | handle->cd = 443 | device_create(handle->cs, NULL, 444 | handle->dev, NULL, 445 | driver_name); 446 | #endif 447 | if (IS_ERR(handle->cd)) { 448 | class_destroy(handle->cs); 449 | unregister_chrdev(MAJOR 450 | (handle->dev), 451 | driver_name); 452 | code = 453 | (os_error_code) handle->cs; 454 | handle->cs = NULL; 455 | } else { 456 | handle->reg_complete = TRUE; 457 | } 458 | } 459 | #endif 460 | } 461 | } 462 | /* ... fops routine registered */ 463 | /* Handle power management fns through separate interface */ 464 | if ((code == OS_ERROR_OK_S) && 465 | (handle->dd.suspend || handle->dd.resume)) { 466 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 467 | handle->dd.name = name; 468 | handle->dd.bus = &platform_bus_type; 469 | code = driver_register(&handle->dd); 470 | #else 471 | handle->dd.driver.name = name; 472 | handle->dd.driver.bus = &platform_bus_type; 473 | code = driver_register(&handle->dd.driver); 474 | #endif 475 | if (code == OS_ERROR_OK_S) { 476 | handle->pd.name = name; 477 | handle->pd.id = 0; 478 | code = platform_device_register(&handle->pd); 479 | if (code != OS_ERROR_OK_S) { 480 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 481 | driver_unregister(&handle->dd); 482 | #else 483 | driver_unregister(&handle->dd.driver); 484 | #endif 485 | } else { 486 | handle->power_complete = TRUE; 487 | } 488 | } 489 | } /* ... suspend or resume */ 490 | } /* name != NULL */ 491 | return code; 492 | } 493 | 494 | /*! 495 | * Finalize the driver registration with the kernel. 496 | * 497 | * Upon return from this call, the driver may begin receiving calls at the 498 | * defined entry points. 499 | * 500 | * @param handle The handle used with #os_driver_init_registration(). 501 | * @param major The major device number to be associated with the driver. 502 | * If this value is zero, a major number may be assigned. 503 | * See #os_driver_get_major() to determine final value. 504 | * #os_driver_remove_registration(). 505 | * @param driver_name The driver name. Can be used as part of 'device node' 506 | * name on platforms which support such a feature. 507 | * 508 | * @return An error code 509 | */ 510 | #define os_driver_complete_registration(handle, major, driver_name) \ 511 | os_drv_do_reg(&handle, major, driver_name) 512 | 513 | /*! 514 | * Get driver Major Number from handle after a successful registration. 515 | * 516 | * @param handle A handle which has completed registration. 517 | * 518 | * @return The major number (if any) associated with the handle. 519 | */ 520 | #define os_driver_get_major(handle) \ 521 | (handle.reg_complete ? MAJOR(handle.dev) : -1) 522 | 523 | /*! 524 | * INTERNAL implemention of os_driver_remove_registration. 525 | * 526 | * @param handle A handle initialized by #os_driver_init_registration(). 527 | * 528 | * @return An error code. 529 | */ 530 | inline static int os_drv_rmv_reg(os_driver_reg_t * handle) 531 | { 532 | if (handle->reg_complete) { 533 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) 534 | if (handle->cd != NULL) { 535 | class_simple_device_remove(handle->dev); 536 | handle->cd = NULL; 537 | } 538 | if (handle->cs != NULL) { 539 | class_simple_destroy(handle->cs); 540 | handle->cs = NULL; 541 | } 542 | unregister_chrdev(MAJOR(handle->dev), handle->dd.name); 543 | #else 544 | if (handle->cd != NULL) { 545 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) 546 | class_device_destroy(handle->cs, handle->dev); 547 | #else 548 | device_destroy(handle->cs, handle->dev); 549 | #endif 550 | handle->cd = NULL; 551 | } 552 | if (handle->cs != NULL) { 553 | class_destroy(handle->cs); 554 | handle->cs = NULL; 555 | } 556 | unregister_chrdev(MAJOR(handle->dev), handle->dd.driver.name); 557 | #endif 558 | handle->reg_complete = FALSE; 559 | } 560 | if (handle->power_complete) { 561 | platform_device_unregister(&handle->pd); 562 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 563 | driver_unregister(&handle->dd); 564 | #else 565 | driver_unregister(&handle->dd.driver); 566 | #endif 567 | handle->power_complete = FALSE; 568 | } 569 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 570 | if (handle->dd.name != NULL) { 571 | kfree(handle->dd.name); 572 | handle->dd.name = NULL; 573 | } 574 | #else 575 | if (handle->dd.driver.name != NULL) { 576 | kfree(handle->dd.driver.name); 577 | handle->dd.driver.name = NULL; 578 | } 579 | #endif 580 | return OS_ERROR_OK_S; 581 | } 582 | 583 | /*! 584 | * Remove the driver's registration with the kernel. 585 | * 586 | * Upon return from this call, the driver not receive any more calls at the 587 | * defined entry points (other than ISR and shutdown). 588 | * 589 | * @param handle A handle initialized by #os_driver_init_registration(). 590 | * 591 | * @return An error code. 592 | */ 593 | #define os_driver_remove_registration(handle) \ 594 | os_drv_rmv_reg(&handle) 595 | 596 | /*! 597 | * Register a driver with the Linux Device Model. 598 | * 599 | * @param driver_information The device_driver structure information 600 | * 601 | * @return An error code. 602 | * 603 | * Status: denigrated in favor of #os_driver_complete_registration() 604 | */ 605 | #define os_register_to_driver(driver_information) \ 606 | driver_register(driver_information) 607 | 608 | /*! 609 | * Unregister a driver from the Linux Device Model 610 | * 611 | * this routine unregisters from the Linux Device Model 612 | * 613 | * @param driver_information The device_driver structure information 614 | * 615 | * @return An error code. 616 | * 617 | * Status: Denigrated. See #os_register_to_driver(). 618 | */ 619 | #define os_unregister_from_driver(driver_information) \ 620 | driver_unregister(driver_information) 621 | 622 | /*! 623 | * register a device to a driver 624 | * 625 | * this routine registers a drivers devices to the Linux Device Model 626 | * 627 | * @param device_information The platform_device structure information 628 | * 629 | * @return An error code. 630 | * 631 | * Status: denigrated in favor of #os_driver_complete_registration() 632 | */ 633 | #define os_register_a_device(device_information) \ 634 | platform_device_register(device_information) 635 | 636 | /*! 637 | * unregister a device from a driver 638 | * 639 | * this routine unregisters a drivers devices from the Linux Device Model 640 | * 641 | * @param device_information The platform_device structure information 642 | * 643 | * @return An error code. 644 | * 645 | * Status: Denigrated. See #os_register_a_device(). 646 | */ 647 | #define os_unregister_a_device(device_information) \ 648 | platform_device_unregister(device_information) 649 | 650 | /*! 651 | * Print a message to console / into log file. After the @c msg argument a 652 | * number of printf-style arguments may be added. Types should be limited to 653 | * printf string, char, octal, decimal, and hexadecimal types. (This excludes 654 | * pointers, and floating point). 655 | * 656 | * @param msg The main text of the message to be logged 657 | * @param s The printf-style arguments which go with msg, if any 658 | * 659 | * @return (void) 660 | */ 661 | #define os_printk(...) \ 662 | (void) printk(__VA_ARGS__) 663 | 664 | /*! 665 | * Prepare a task to execute the given function. This should only be done once 666 | * per function,, during the driver's initialization routine. 667 | * 668 | * @param task_fn Name of the OS_DEV_TASK() function to be created. 669 | * 670 | * @return an OS ERROR code. 671 | */ 672 | #define os_create_task(function_name) \ 673 | OS_ERROR_OK_S 674 | 675 | /*! 676 | * Schedule execution of a task. 677 | * 678 | * @param function_name The function associated with the task. 679 | * 680 | * @return (void) 681 | */ 682 | #define os_dev_schedule_task(function_name) \ 683 | tasklet_schedule(&(function_name ## let)) 684 | 685 | /*! 686 | * Make sure that task is no longer running and will no longer run. 687 | * 688 | * This function will not return until both are true. This is useful when 689 | * shutting down a driver. 690 | */ 691 | #define os_dev_stop_task(function_name) \ 692 | do { \ 693 | tasklet_disable(&(function_name ## let)); \ 694 | tasklet_kill(&(function_name ## let)); \ 695 | } while (0) 696 | 697 | /*! 698 | * Allocate some kernel memory 699 | * 700 | * @param amount Number of 8-bit bytes to allocate 701 | * @param flags Some indication of purpose of memory (needs definition) 702 | * 703 | * @return Pointer to allocated memory, or NULL if failed. 704 | */ 705 | #define os_alloc_memory(amount, flags) \ 706 | (void*)kmalloc(amount, flags) 707 | 708 | /*! 709 | * Free some kernel memory 710 | * 711 | * @param location The beginning of the region to be freed. 712 | * 713 | * Do some OSes have separate free() functions which should be 714 | * distinguished by passing in @c flags here, too? Don't some also require the 715 | * size of the buffer being freed? 716 | */ 717 | #define os_free_memory(location) \ 718 | kfree(location) 719 | 720 | /*! 721 | * Allocate cache-coherent memory 722 | * 723 | * @param amount Number of bytes to allocate 724 | * @param[out] dma_addrp Location to store physical address of allocated 725 | * memory. 726 | * @param flags Some indication of purpose of memory (needs 727 | * definition). 728 | * 729 | * @return (virtual space) pointer to allocated memory, or NULL if failed. 730 | * 731 | */ 732 | #define os_alloc_coherent(amount, dma_addrp, flags) \ 733 | (void*)dma_alloc_coherent(NULL, amount, dma_addrp, flags) 734 | 735 | /*! 736 | * Free cache-coherent memory 737 | * 738 | * @param size Number of bytes which were allocated. 739 | * @param virt_addr Virtual(kernel) address of memory.to be freed, as 740 | * returned by #os_alloc_coherent(). 741 | * @param dma_addr Physical address of memory.to be freed, as returned 742 | * by #os_alloc_coherent(). 743 | * 744 | * @return void 745 | * 746 | */ 747 | #define os_free_coherent(size, virt_addr, dma_addr) \ 748 | dma_free_coherent(NULL, size, virt_addr, dma_addr 749 | 750 | /*! 751 | * Map an I/O space into kernel memory space 752 | * 753 | * @param start The starting address of the (physical / io space) region 754 | * @param range_bytes The number of bytes to map 755 | * 756 | * @return A pointer to the mapped area, or NULL on failure 757 | */ 758 | #define os_map_device(start, range_bytes) \ 759 | (void*)ioremap_nocache((start), range_bytes) 760 | 761 | /*! 762 | * Unmap an I/O space from kernel memory space 763 | * 764 | * @param start The starting address of the (virtual) region 765 | * @param range_bytes The number of bytes to unmap 766 | * 767 | * @return None 768 | */ 769 | #define os_unmap_device(start, range_bytes) \ 770 | iounmap((void*)(start)) 771 | 772 | /*! 773 | * Copy data from Kernel space to User space 774 | * 775 | * @param to The target location in user memory 776 | * @param from The source location in kernel memory 777 | * @param size The number of bytes to be copied 778 | * 779 | * @return #os_error_code 780 | */ 781 | #define os_copy_to_user(to, from, size) \ 782 | ((copy_to_user(to, from, size) == 0) ? 0 : OS_ERROR_BAD_ADDRESS_S) 783 | 784 | /*! 785 | * Copy data from User space to Kernel space 786 | * 787 | * @param to The target location in kernel memory 788 | * @param from The source location in user memory 789 | * @param size The number of bytes to be copied 790 | * 791 | * @return #os_error_code 792 | */ 793 | #define os_copy_from_user(to, from, size) \ 794 | ((copy_from_user(to, from, size) == 0) ? 0 : OS_ERROR_BAD_ADDRESS_S) 795 | 796 | /*! 797 | * Read a 8-bit device register 798 | * 799 | * @param register_address The (bus) address of the register to write to 800 | * @return The value in the register 801 | */ 802 | #define os_read8(register_address) \ 803 | __raw_readb(register_address) 804 | 805 | /*! 806 | * Write a 8-bit device register 807 | * 808 | * @param register_address The (bus) address of the register to write to 809 | * @param value The value to write into the register 810 | */ 811 | #define os_write8(register_address, value) \ 812 | __raw_writeb(value, register_address) 813 | 814 | /*! 815 | * Read a 16-bit device register 816 | * 817 | * @param register_address The (bus) address of the register to write to 818 | * @return The value in the register 819 | */ 820 | #define os_read16(register_address) \ 821 | __raw_readw(register_address) 822 | 823 | /*! 824 | * Write a 16-bit device register 825 | * 826 | * @param register_address The (bus) address of the register to write to 827 | * @param value The value to write into the register 828 | */ 829 | #define os_write16(register_address, value) \ 830 | __raw_writew(value, (uint32_t*)(register_address)) 831 | 832 | /*! 833 | * Read a 32-bit device register 834 | * 835 | * @param register_address The (bus) address of the register to write to 836 | * @return The value in the register 837 | */ 838 | #define os_read32(register_address) \ 839 | __raw_readl((uint32_t*)(register_address)) 840 | 841 | /*! 842 | * Write a 32-bit device register 843 | * 844 | * @param register_address The (bus) address of the register to write to 845 | * @param value The value to write into the register 846 | */ 847 | #define os_write32(register_address, value) \ 848 | __raw_writel(value, register_address) 849 | 850 | /*! 851 | * Read a 64-bit device register 852 | * 853 | * @param register_address The (bus) address of the register to write to 854 | * @return The value in the register 855 | */ 856 | #define os_read64(register_address) \ 857 | ERROR_UNIMPLEMENTED 858 | 859 | /*! 860 | * Write a 64-bit device register 861 | * 862 | * @param register_address The (bus) address of the register to write to 863 | * @param value The value to write into the register 864 | */ 865 | #define os_write64(register_address, value) \ 866 | ERROR_UNIMPLEMENTED 867 | 868 | /*! 869 | * Delay some number of microseconds 870 | * 871 | * Note that this is a busy-loop, not a suspension of the task/process. 872 | * 873 | * @param msecs The number of microseconds to delay 874 | * 875 | * @return void 876 | */ 877 | #define os_mdelay mdelay 878 | 879 | /*! 880 | * Calculate virtual address from physical address 881 | * 882 | * @param pa Physical address 883 | * 884 | * @return virtual address 885 | * 886 | * @note this assumes that addresses are 32 bits wide 887 | */ 888 | #define os_va __va 889 | 890 | /*! 891 | * Calculate physical address from virtual address 892 | * 893 | * 894 | * @param va Virtual address 895 | * 896 | * @return physical address 897 | * 898 | * @note this assumes that addresses are 32 bits wide 899 | */ 900 | #define os_pa __pa 901 | 902 | #ifdef CONFIG_PREEMPT_RT 903 | /*! 904 | * Allocate and initialize a lock, returning a lock handle. 905 | * 906 | * The lock state will be initialized to 'unlocked'. 907 | * 908 | * @return A lock handle, or NULL if an error occurred. 909 | */ 910 | inline static os_lock_t os_lock_alloc_init(void) 911 | { 912 | raw_spinlock_t *lockp; 913 | lockp = (raw_spinlock_t *) kmalloc(sizeof(raw_spinlock_t), 0); 914 | if (lockp) { 915 | _raw_spin_lock_init(lockp); 916 | } else { 917 | printk("OS: lock init failed\n"); 918 | } 919 | 920 | return lockp; 921 | } 922 | #else 923 | /*! 924 | * Allocate and initialize a lock, returning a lock handle. 925 | * 926 | * The lock state will be initialized to 'unlocked'. 927 | * 928 | * @return A lock handle, or NULL if an error occurred. 929 | */ 930 | inline static os_lock_t os_lock_alloc_init(void) 931 | { 932 | spinlock_t *lockp; 933 | lockp = (spinlock_t *) kmalloc(sizeof(spinlock_t), 0); 934 | if (lockp) { 935 | spin_lock_init(lockp); 936 | } else { 937 | printk("OS: lock init failed\n"); 938 | } 939 | 940 | return lockp; 941 | } 942 | #endif /* CONFIG_PREEMPT_RT */ 943 | 944 | /*! 945 | * Acquire a lock. 946 | * 947 | * This function should only be called from an interrupt service routine. 948 | * 949 | * @param lock_handle A handle to the lock to acquire. 950 | * 951 | * @return void 952 | */ 953 | #define os_lock(lock_handle) \ 954 | spin_lock(lock_handle) 955 | 956 | /*! 957 | * Unlock a lock. Lock must have been acquired by #os_lock(). 958 | * 959 | * @param lock_handle A handle to the lock to unlock. 960 | * 961 | * @return void 962 | */ 963 | #define os_unlock(lock_handle) \ 964 | spin_unlock(lock_handle) 965 | 966 | /*! 967 | * Acquire a lock in non-ISR context 968 | * 969 | * This function will spin until the lock is available. 970 | * 971 | * @param lock_handle A handle of the lock to acquire. 972 | * @param context Place to save the before-lock context 973 | * 974 | * @return void 975 | */ 976 | #define os_lock_save_context(lock_handle, context) \ 977 | spin_lock_irqsave(lock_handle, context) 978 | 979 | /*! 980 | * Release a lock in non-ISR context 981 | * 982 | * @param lock_handle A handle of the lock to release. 983 | * @param context Place where before-lock context was saved. 984 | * 985 | * @return void 986 | */ 987 | #define os_unlock_restore_context(lock_handle, context) \ 988 | spin_unlock_irqrestore(lock_handle, context) 989 | 990 | /*! 991 | * Deallocate a lock handle. 992 | * 993 | * @param lock_handle An #os_lock_t that has been allocated. 994 | * 995 | * @return void 996 | */ 997 | #define os_lock_deallocate(lock_handle) \ 998 | kfree(lock_handle) 999 | 1000 | /*! 1001 | * Determine process handle 1002 | * 1003 | * The process handle of the current user is returned. 1004 | * 1005 | * @return A handle on the current process. 1006 | */ 1007 | #define os_get_process_handle() \ 1008 | current 1009 | 1010 | /*! 1011 | * Send a signal to a process 1012 | * 1013 | * @param proc A handle to the target process. 1014 | * @param sig The POSIX signal to send to that process. 1015 | */ 1016 | #define os_send_signal(proc, sig) \ 1017 | send_sig(sig, proc, 0); 1018 | 1019 | /*! 1020 | * Get some random bytes 1021 | * 1022 | * @param buf The location to store the random data. 1023 | * @param count The number of bytes to store. 1024 | * 1025 | * @return void 1026 | */ 1027 | #define os_get_random_bytes(buf, count) \ 1028 | get_random_bytes(buf, count) 1029 | 1030 | /*! 1031 | * Go to sleep on an object. 1032 | * 1033 | * @param object The object on which to sleep 1034 | * @param condition An expression to check for sleep completion. Must be 1035 | * coded so that it can be referenced more than once inside 1036 | * macro, i.e., no ++ or other modifying expressions. 1037 | * @param atomic Non-zero if sleep must not return until condition. 1038 | * 1039 | * @return error code -- OK or sleep interrupted?? 1040 | */ 1041 | #define os_sleep(object, condition, atomic) \ 1042 | ({ \ 1043 | DEFINE_WAIT(_waitentry_); \ 1044 | os_error_code code = OS_ERROR_OK_S; \ 1045 | \ 1046 | while (!(condition)) { \ 1047 | prepare_to_wait(&(object##_qh), &_waitentry_, \ 1048 | atomic ? 0 : TASK_INTERRUPTIBLE); \ 1049 | if (!(condition)) { \ 1050 | schedule(); \ 1051 | } \ 1052 | \ 1053 | finish_wait(&(object##_qh), &_waitentry_); \ 1054 | \ 1055 | if (!atomic && signal_pending(current)) { \ 1056 | code = OS_ERROR_FAIL_S; /* NEED SOMETHING BETTER */ \ 1057 | break; \ 1058 | } \ 1059 | }; \ 1060 | \ 1061 | code; \ 1062 | }) 1063 | 1064 | /*! 1065 | * Wake up whatever is sleeping on sleep object 1066 | * 1067 | * @param object The object on which things might be sleeping 1068 | * 1069 | * @return none 1070 | */ 1071 | #define os_wake_sleepers(object) \ 1072 | wake_up_interruptible(&(object##_qh)); 1073 | 1074 | /*! @} *//* dkops */ 1075 | 1076 | /****************************************************************************** 1077 | * Function signature-generating macros 1078 | *****************************************************************************/ 1079 | 1080 | /*! 1081 | * @defgroup drsigs Driver Signatures 1082 | * 1083 | * These macros will define the entry point signatures for interrupt handlers; 1084 | * driver initialization and shutdown; device open/close; etc. 1085 | * 1086 | * There are two versions of each macro for a given Driver Entry Point. The 1087 | * first version is used to define a function and its implementation in the 1088 | * driver.c file, e.g. #OS_DEV_INIT(). 1089 | * 1090 | * The second form is used whenever a forward declaration (prototype) is 1091 | * needed. It has the letters @c _DCL appended to the name of the defintion 1092 | * function, and takes only the first two arguments (driver_name and 1093 | * function_name). These are not otherwise mentioned in this documenation. 1094 | * 1095 | * There is a third form used when a reference to a function is required, for 1096 | * instance when passing the routine as a pointer to a function. It has the 1097 | * letters @c _REF appended to it, and takes only the first two arguments 1098 | * (driver_name and function_name). These functions are not otherwise 1099 | * mentioned in this documentation. 1100 | * 1101 | * (Note that these two extra forms are required because of the 1102 | * possibility/likelihood of having a 'wrapper function' which invokes the 1103 | * generic function with expected arguments. An alternative would be to have a 1104 | * generic function which isn't able to get at any arguments directly, but 1105 | * would be equipped with macros which could get at information passed in. 1106 | * 1107 | * Example: 1108 | * 1109 | * (in a header file) 1110 | * @code 1111 | * OS_DEV_INIT_DCL(widget, widget_init); 1112 | * @endcode 1113 | * 1114 | * (in an implementation file) 1115 | * @code 1116 | * OS_DEV_INIT(widget, widget_init) 1117 | * { 1118 | * os_dev_init_return(TRUE); 1119 | * } 1120 | * @endcode 1121 | * 1122 | */ 1123 | 1124 | /*! @addtogroup drsigs */ 1125 | /*! @{ */ 1126 | 1127 | /*! 1128 | * Define a function which will handle device initialization 1129 | * 1130 | * This is tne driver initialization routine. This is normally where the 1131 | * part would be initialized; queues, locks, interrupts handlers defined; 1132 | * long-term dynamic memory allocated for driver use; etc. 1133 | * 1134 | * @param function_name The name of the portable initialization function. 1135 | * 1136 | * @return A call to #os_dev_init_return() 1137 | * 1138 | */ 1139 | #define OS_DEV_INIT(function_name) \ 1140 | module_init(function_name); \ 1141 | static int __init function_name (void) 1142 | 1143 | /*! Make declaration for driver init function. 1144 | * @param function_name foo 1145 | */ 1146 | #define OS_DEV_INIT_DCL(function_name) \ 1147 | static int __init function_name (void); 1148 | 1149 | /*! 1150 | * Generate a function reference to the driver's init function. 1151 | * @param function_name Name of the OS_DEV_INIT() function. 1152 | * 1153 | * @return A function pointer. 1154 | */ 1155 | #define OS_DEV_INIT_REF(function_name) \ 1156 | function_name 1157 | 1158 | /*! 1159 | * Define a function which will handle device shutdown 1160 | * 1161 | * This is the inverse of the #OS_DEV_INIT() routine. 1162 | * 1163 | * @param function_name The name of the portable driver shutdown routine. 1164 | * 1165 | * @return A call to #os_dev_shutdown_return() 1166 | * 1167 | */ 1168 | #define OS_DEV_SHUTDOWN(function_name) \ 1169 | module_exit(function_name); \ 1170 | static void function_name(void) 1171 | 1172 | /*! 1173 | * Generate a function reference to the driver's shutdown function. 1174 | * @param function_name Name of the OS_DEV_HUSTDOWN() function. 1175 | * 1176 | * @return A function pointer. 1177 | */ 1178 | #define OS_DEV_SHUTDOWN_DCL(function_name) \ 1179 | static void function_name(void); 1180 | 1181 | /*! 1182 | * Generate a reference to driver's shutdown function 1183 | * @param function_name Name of the OS_DEV_HUSTDOWN() function. 1184 | */ 1185 | 1186 | #define OS_DEV_SHUTDOWN_REF(function_name) \ 1187 | function_name 1188 | 1189 | /*! 1190 | * Define a function which will open the device for a user. 1191 | * 1192 | * @param function_name The name of the driver open() function 1193 | * 1194 | * @return A call to #os_dev_open_return() 1195 | */ 1196 | #define OS_DEV_OPEN(function_name) \ 1197 | static int function_name(struct inode* inode_p_, struct file* file_p_) 1198 | 1199 | /*! 1200 | * Declare prototype for an open() function. 1201 | * 1202 | * @param function_name The name of the OS_DEV_OPEN() function. 1203 | */ 1204 | #define OS_DEV_OPEN_DCL(function_name) \ 1205 | OS_DEV_OPEN(function_name); 1206 | 1207 | /*! 1208 | * Generate a function reference to the driver's open() function. 1209 | * @param function_name Name of the OS_DEV_OPEN() function. 1210 | * 1211 | * @return A function pointer. 1212 | */ 1213 | #define OS_DEV_OPEN_REF(function_name) \ 1214 | function_name 1215 | 1216 | /*! 1217 | * Define a function which will handle a user's ioctl() request 1218 | * 1219 | * @param function_name The name of the driver ioctl() function 1220 | * 1221 | * @return A call to #os_dev_ioctl_return() 1222 | */ 1223 | #define OS_DEV_IOCTL(function_name) \ 1224 | static int function_name(struct file *file_p_, \ 1225 | unsigned int cmd_, unsigned long data_) 1226 | 1227 | /*! Boo. */ 1228 | #define OS_DEV_IOCTL_DCL(function_name) \ 1229 | OS_DEV_IOCTL(function_name); 1230 | 1231 | /*! 1232 | * Generate a function reference to the driver's ioctl() function. 1233 | * @param function_name Name of the OS_DEV_IOCTL() function. 1234 | * 1235 | * @return A function pointer. 1236 | */ 1237 | #define OS_DEV_IOCTL_REF(function_name) \ 1238 | function_name 1239 | 1240 | /*! 1241 | * Define a function which will handle a user's mmap() request 1242 | * 1243 | * @param function_name The name of the driver mmap() function 1244 | * 1245 | * @return A call to #os_dev_ioctl_return() 1246 | */ 1247 | #define OS_DEV_MMAP(function_name) \ 1248 | int function_name(struct file* file_p_, struct vm_area_struct* vma_) 1249 | 1250 | #define OS_DEV_MMAP_DCL(function_name) \ 1251 | OS_DEV_MMAP(function_name); 1252 | 1253 | #define OS_DEV_MMAP_REF(function_name) \ 1254 | function_name 1255 | 1256 | /* Retrieve the context to the memory structure that is to be MMAPed */ 1257 | #define os_mmap_memory_ctx() (vma_) 1258 | 1259 | /* Determine the size of the requested MMAP region*/ 1260 | #define os_mmap_memory_size() (vma_->vm_end - vma_->vm_start) 1261 | 1262 | /* Determine the base address of the requested MMAP region*/ 1263 | #define os_mmap_user_base() (vma_->vm_start) 1264 | 1265 | /*! 1266 | * Declare prototype for an read() function. 1267 | * 1268 | * @param function_name The name of the driver read function. 1269 | */ 1270 | #define OS_DEV_READ_DCL(function_name) \ 1271 | OS_DEV_READ(function_name); 1272 | 1273 | /*! 1274 | * Generate a function reference to the driver's read() routine 1275 | * @param function_name Name of the OS_DEV_READ() function. 1276 | * 1277 | * @return A function pointer. 1278 | */ 1279 | #define OS_DEV_READ_REF(function_name) \ 1280 | function_name 1281 | 1282 | /*! 1283 | * Define a function which will handle a user's write() request 1284 | * 1285 | * @param function_name The name of the driver write() function 1286 | * 1287 | * @return A call to #os_dev_write_return() 1288 | */ 1289 | #define OS_DEV_WRITE(function_name) \ 1290 | static ssize_t function_name(struct file* file_p_, char* user_buffer_, \ 1291 | size_t count_bytes_, loff_t* file_position_) 1292 | 1293 | /*! 1294 | * Declare prototype for an write() function. 1295 | * 1296 | * @param function_name The name of the driver write function. 1297 | */ 1298 | #define OS_DEV_WRITE_DCL(function_name) \ 1299 | OS_DEV_WRITE(function_name); 1300 | 1301 | /*! 1302 | * Generate a function reference to the driver's write() routine 1303 | * @param function_name Name of the OS_DEV_WRITE() function. 1304 | * 1305 | * @return A function pointer. 1306 | */ 1307 | #define OS_DEV_WRITE_REF(function_name) \ 1308 | function_name 1309 | 1310 | /*! 1311 | * Define a function which will close the device - opposite of OS_DEV_OPEN() 1312 | * 1313 | * @param function_name The name of the driver close() function 1314 | * 1315 | * @return A call to #os_dev_close_return() 1316 | */ 1317 | #define OS_DEV_CLOSE(function_name) \ 1318 | static int function_name(struct inode* inode_p_, struct file* file_p_) 1319 | 1320 | /*! 1321 | * Declare prototype for an close() function 1322 | * 1323 | * @param function_name The name of the driver close() function. 1324 | */ 1325 | #define OS_DEV_CLOSE_DCL(function_name) \ 1326 | OS_DEV_CLOSE(function_name); 1327 | 1328 | /*! 1329 | * Generate a function reference to the driver's close function. 1330 | * @param function_name Name of the OS_DEV_CLOSE() function. 1331 | * 1332 | * @return A function pointer. 1333 | */ 1334 | #define OS_DEV_CLOSE_REF(function_name) \ 1335 | function_name 1336 | 1337 | /*! 1338 | * Define a function which will handle an interrupt 1339 | * 1340 | * No arguments are available to the generic function. It must not invoke any 1341 | * OS functions which are illegal in a ISR. It gets no parameters, and must 1342 | * have a call to #os_dev_isr_return() instead of any/all return statements. 1343 | * 1344 | * Example: 1345 | * @code 1346 | * OS_DEV_ISR(widget) 1347 | * { 1348 | * os_dev_isr_return(1); 1349 | * } 1350 | * @endcode 1351 | * 1352 | * @param function_name The name of the driver ISR function 1353 | * 1354 | * @return A call to #os_dev_isr_return() 1355 | */ 1356 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 1357 | #define OS_DEV_ISR(function_name) \ 1358 | static irqreturn_t function_name(int N1_, void* N2_, struct pt_regs* N3_) 1359 | #else 1360 | #define OS_DEV_ISR(function_name) \ 1361 | static irqreturn_t function_name(int N1_, void* N2_) 1362 | #endif 1363 | 1364 | /*! 1365 | * Declare prototype for an ISR function. 1366 | * 1367 | * @param function_name The name of the driver ISR function. 1368 | */ 1369 | #define OS_DEV_ISR_DCL(function_name) \ 1370 | OS_DEV_ISR(function_name); 1371 | 1372 | /*! 1373 | * Generate a function reference to the driver's interrupt service routine 1374 | * @param function_name Name of the OS_DEV_ISR() function. 1375 | * 1376 | * @return A function pointer. 1377 | */ 1378 | #define OS_DEV_ISR_REF(function_name) \ 1379 | function_name 1380 | 1381 | /*! 1382 | * Define a function which will operate as a background task / bottom half. 1383 | * 1384 | * Tasklet stuff isn't strictly limited to 'Device drivers', but leave it 1385 | * this namespace anyway. 1386 | * 1387 | * @param function_name The name of this background task function 1388 | * 1389 | * @return A call to #os_dev_task_return() 1390 | */ 1391 | #define OS_DEV_TASK(function_name) \ 1392 | static void function_name(unsigned long data_) 1393 | 1394 | /*! 1395 | * Declare prototype for a background task / bottom half function 1396 | * 1397 | * @param function_name The name of this background task function 1398 | */ 1399 | #define OS_DEV_TASK_DCL(function_name) \ 1400 | OS_DEV_TASK(function_name); \ 1401 | DECLARE_TASKLET(function_name ## let, function_name, 0); 1402 | 1403 | /*! 1404 | * Generate a reference to an #OS_DEV_TASK() function 1405 | * 1406 | * @param function_name The name of the task being referenced. 1407 | */ 1408 | #define OS_DEV_TASK_REF(function_name) \ 1409 | (function_name ## let) 1410 | 1411 | /*! @} *//* drsigs */ 1412 | 1413 | /***************************************************************************** 1414 | * Functions/Macros for returning values from Driver Signature routines 1415 | *****************************************************************************/ 1416 | 1417 | /*! 1418 | * Return from the #OS_DEV_INIT() function 1419 | * 1420 | * @param code An error code to report success or failure. 1421 | * 1422 | */ 1423 | #define os_dev_init_return(code) \ 1424 | return code 1425 | 1426 | /*! 1427 | * Return from the #OS_DEV_SHUTDOWN() function 1428 | * 1429 | * @param code An error code to report success or failure. 1430 | * 1431 | */ 1432 | #define os_dev_shutdown_return(code) \ 1433 | return 1434 | 1435 | /*! 1436 | * Return from the #OS_DEV_ISR() function 1437 | * 1438 | * The function should verify that it really was supposed to be called, 1439 | * and that its device needed attention, in order to properly set the 1440 | * return code. 1441 | * 1442 | * @param code non-zero if interrupt handled, zero otherwise. 1443 | * 1444 | */ 1445 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 1446 | #define os_dev_isr_return(code) \ 1447 | do { \ 1448 | /* Unused warnings */ \ 1449 | (void)N1_; \ 1450 | (void)N2_; \ 1451 | (void)N3_; \ 1452 | \ 1453 | return IRQ_RETVAL(code); \ 1454 | } while (0) 1455 | #else 1456 | #define os_dev_isr_return(code) \ 1457 | do { \ 1458 | /* Unused warnings */ \ 1459 | (void)N1_; \ 1460 | (void)N2_; \ 1461 | \ 1462 | return IRQ_RETVAL(code); \ 1463 | } while (0) 1464 | #endif 1465 | 1466 | /*! 1467 | * Return from the #OS_DEV_OPEN() function 1468 | * 1469 | * @param code An error code to report success or failure. 1470 | * 1471 | */ 1472 | #define os_dev_open_return(code) \ 1473 | do { \ 1474 | int retcode = code; \ 1475 | \ 1476 | /* get rid of 'unused parameter' warnings */ \ 1477 | (void)inode_p_; \ 1478 | (void)file_p_; \ 1479 | \ 1480 | return retcode; \ 1481 | } while (0) 1482 | 1483 | /*! 1484 | * Return from the #OS_DEV_IOCTL() function 1485 | * 1486 | * @param code An error code to report success or failure. 1487 | * 1488 | */ 1489 | #define os_dev_ioctl_return(code) \ 1490 | do { \ 1491 | int retcode = code; \ 1492 | \ 1493 | /* get rid of 'unused parameter' warnings */ \ 1494 | (void)file_p_; \ 1495 | (void)cmd_; \ 1496 | (void)data_; \ 1497 | \ 1498 | return retcode; \ 1499 | } while (0) 1500 | 1501 | /*! 1502 | * Return from the #OS_DEV_READ() function 1503 | * 1504 | * @param code Number of bytes read, or an error code to report failure. 1505 | * 1506 | */ 1507 | #define os_dev_read_return(code) \ 1508 | do { \ 1509 | ssize_t retcode = code; \ 1510 | \ 1511 | /* get rid of 'unused parameter' warnings */ \ 1512 | (void)file_p_; \ 1513 | (void)user_buffer_; \ 1514 | (void)count_bytes_; \ 1515 | (void)file_position_; \ 1516 | \ 1517 | return retcode; \ 1518 | } while (0) 1519 | 1520 | /*! 1521 | * Return from the #OS_DEV_WRITE() function 1522 | * 1523 | * @param code Number of bytes written, or an error code to report failure. 1524 | * 1525 | */ 1526 | #define os_dev_write_return(code) \ 1527 | do { \ 1528 | ssize_t retcode = code; \ 1529 | \ 1530 | /* get rid of 'unused parameter' warnings */ \ 1531 | (void)file_p_; \ 1532 | (void)user_buffer_; \ 1533 | (void)count_bytes_; \ 1534 | (void)file_position_; \ 1535 | \ 1536 | return retcode; \ 1537 | } while (0) 1538 | 1539 | /*! 1540 | * Return from the #OS_DEV_CLOSE() function 1541 | * 1542 | * @param code An error code to report success or failure. 1543 | * 1544 | */ 1545 | #define os_dev_close_return(code) \ 1546 | do { \ 1547 | ssize_t retcode = code; \ 1548 | \ 1549 | /* get rid of 'unused parameter' warnings */ \ 1550 | (void)inode_p_; \ 1551 | (void)file_p_; \ 1552 | \ 1553 | return retcode; \ 1554 | } while (0) 1555 | 1556 | /*! 1557 | * Start the #OS_DEV_TASK() function 1558 | * 1559 | * In some implementations, this could be turned into a label for 1560 | * the os_dev_task_return() call. 1561 | * 1562 | * @return none 1563 | */ 1564 | #define os_dev_task_begin() 1565 | 1566 | /*! 1567 | * Return from the #OS_DEV_TASK() function 1568 | * 1569 | * In some implementations, this could be turned into a sleep followed 1570 | * by a jump back to the os_dev_task_begin() call. 1571 | * 1572 | * @param code An error code to report success or failure. 1573 | * 1574 | */ 1575 | #define os_dev_task_return(code) \ 1576 | do { \ 1577 | /* Unused warnings */ \ 1578 | (void)data_; \ 1579 | \ 1580 | return; \ 1581 | } while (0) 1582 | 1583 | /***************************************************************************** 1584 | * Functions/Macros for accessing arguments from Driver Signature routines 1585 | *****************************************************************************/ 1586 | 1587 | /*! @defgroup drsigargs Functions for Getting Arguments in Signature functions 1588 | * 1589 | */ 1590 | /* @addtogroup @drsigargs */ 1591 | /*! @{ */ 1592 | /*! 1593 | * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and 1594 | * #OS_DEV_WRITE() routines to check whether user is requesting read 1595 | * (permission) 1596 | */ 1597 | #define os_dev_is_flag_read() \ 1598 | (file_p_->f_mode & FMODE_READ) 1599 | 1600 | /*! 1601 | * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and 1602 | * #OS_DEV_WRITE() routines to check whether user is requesting write 1603 | * (permission) 1604 | */ 1605 | #define os_dev_is_flag_write() \ 1606 | (file_p_->f_mode & FMODE_WRITE) 1607 | 1608 | /*! 1609 | * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and 1610 | * #OS_DEV_WRITE() routines to check whether user is requesting non-blocking 1611 | * I/O. 1612 | */ 1613 | #define os_dev_is_flag_nonblock() \ 1614 | (file_p_->f_flags & (O_NONBLOCK | O_NDELAY)) 1615 | 1616 | /*! 1617 | * Used in #OS_DEV_OPEN() and #OS_DEV_CLOSE() to determine major device being 1618 | * accessed. 1619 | */ 1620 | #define os_dev_get_major() \ 1621 | (imajor(inode_p_)) 1622 | 1623 | /*! 1624 | * Used in #OS_DEV_OPEN() and #OS_DEV_CLOSE() to determine minor device being 1625 | * accessed. 1626 | */ 1627 | #define os_dev_get_minor() \ 1628 | (iminor(inode_p_)) 1629 | 1630 | /*! 1631 | * Used in #OS_DEV_IOCTL() to determine which operation the user wants 1632 | * performed. 1633 | * 1634 | * @return Value of the operation. 1635 | */ 1636 | #define os_dev_get_ioctl_op() \ 1637 | (cmd_) 1638 | 1639 | /*! 1640 | * Used in #OS_DEV_IOCTL() to return the associated argument for the desired 1641 | * operation. 1642 | * 1643 | * @return A value which can be cast to a struct pointer or used as 1644 | * int/long. 1645 | */ 1646 | #define os_dev_get_ioctl_arg() \ 1647 | (data_) 1648 | 1649 | /*! 1650 | * Used in OS_DEV_READ() and OS_DEV_WRITE() routines to access the requested 1651 | * byte count. 1652 | * 1653 | * @return (unsigned) a count of bytes 1654 | */ 1655 | #define os_dev_get_count() \ 1656 | ((unsigned)count_bytes_) 1657 | 1658 | /*! 1659 | * Used in OS_DEV_READ() and OS_DEV_WRITE() routines to return the pointer 1660 | * byte count. 1661 | * 1662 | * @return char* pointer to user buffer 1663 | */ 1664 | #define os_dev_get_user_buffer() \ 1665 | ((void*)user_buffer_) 1666 | 1667 | /*! 1668 | * Used in OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines to 1669 | * get the POSIX flags field for the associated open file). 1670 | * 1671 | * @return The flags associated with the file. 1672 | */ 1673 | #define os_dev_get_file_flags() \ 1674 | (file_p_->f_flags) 1675 | 1676 | /*! 1677 | * Set the driver's private structure associated with this file/open. 1678 | * 1679 | * Generally used during #OS_DEV_OPEN(). See #os_dev_get_user_private(). 1680 | * 1681 | * @param struct_p The driver data structure to associate with this user. 1682 | */ 1683 | #define os_dev_set_user_private(struct_p) \ 1684 | file_p_->private_data = (void*)(struct_p) 1685 | 1686 | /*! 1687 | * Get the driver's private structure associated with this file. 1688 | * 1689 | * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(), 1690 | * #OS_DEV_IOCTL(), and #OS_DEV_CLOSE(). See #os_dev_set_user_private(). 1691 | * 1692 | * @return The driver data structure to associate with this user. 1693 | */ 1694 | #define os_dev_get_user_private() \ 1695 | ((void*)file_p_->private_data) 1696 | 1697 | /*! 1698 | * Get the IRQ associated with this call to the #OS_DEV_ISR() function. 1699 | * 1700 | * @return The IRQ (integer) interrupt number. 1701 | */ 1702 | #define os_dev_get_irq() \ 1703 | N1_ 1704 | 1705 | /*! @} *//* drsigargs */ 1706 | 1707 | /*! 1708 | * @defgroup cacheops Cache Operations 1709 | * 1710 | * These functions are for synchronizing processor cache with RAM. 1711 | */ 1712 | /*! @addtogroup cacheops */ 1713 | /*! @{ */ 1714 | 1715 | /*! 1716 | * Flush and invalidate all cache lines. 1717 | */ 1718 | #if 0 1719 | #define os_flush_cache_all() \ 1720 | flush_cache_all() 1721 | #else 1722 | /* Call ARM fn directly, in case L2cache=on3 not set */ 1723 | #define os_flush_cache_all() \ 1724 | v6_flush_kern_cache_all_L2() 1725 | 1726 | /*! 1727 | * ARM-routine to flush all cache. Defined here, because it exists in no 1728 | * easy-access header file. ARM-11 with L210 cache only! 1729 | */ 1730 | extern void v6_flush_kern_cache_all_L2(void); 1731 | #endif 1732 | 1733 | /* 1734 | * These macros are using part of the Linux DMA API. They rely on the 1735 | * map function to do nothing more than the equivalent clean/inv/flush 1736 | * operation at the time of the mapping, and do nothing at an unmapping 1737 | * call, which the Sahara driver code will never invoke. 1738 | */ 1739 | 1740 | /*! 1741 | * Clean a range of addresses from the cache. That is, write updates back 1742 | * to (RAM, next layer). 1743 | * 1744 | * @param start Starting virtual address 1745 | * @param len Number of bytes to flush 1746 | * 1747 | * @return void 1748 | */ 1749 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) 1750 | #define os_cache_clean_range(start,len) \ 1751 | dma_map_single(NULL, (void*)start, len, DMA_TO_DEVICE) 1752 | #else 1753 | #define os_cache_clean_range(start,len) \ 1754 | { \ 1755 | void *s = (void*)start; \ 1756 | void *e = s + len; \ 1757 | dmac_map_area(s, len, DMA_TO_DEVICE); \ 1758 | outer_clean_range(__pa(s), __pa(e)); \ 1759 | } 1760 | #endif 1761 | 1762 | /*! 1763 | * Invalidate a range of addresses in the cache 1764 | * 1765 | * @param start Starting virtual address 1766 | * @param len Number of bytes to flush 1767 | * 1768 | * @return void 1769 | */ 1770 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) 1771 | #define os_cache_inv_range(start,len) \ 1772 | dma_map_single(NULL, (void*)start, len, DMA_FROM_DEVICE) 1773 | #else 1774 | #define os_cache_inv_range(start,len) \ 1775 | { \ 1776 | void *s = (void*)start; \ 1777 | void *e = s + len; \ 1778 | dmac_unmap_area(s, len, DMA_FROM_DEVICE); \ 1779 | outer_inv_range(__pa(s), __pa(e)); \ 1780 | } 1781 | #endif 1782 | 1783 | /*! 1784 | * Flush a range of addresses from the cache. That is, perform clean 1785 | * and invalidate 1786 | * 1787 | * @param start Starting virtual address 1788 | * @param len Number of bytes to flush 1789 | * 1790 | * @return void 1791 | */ 1792 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) 1793 | #define os_cache_flush_range(start,len) \ 1794 | dma_map_single(NULL, (void*)start, len, DMA_BIDIRECTIONAL) 1795 | #else 1796 | #define os_cache_flush_range(start,len) \ 1797 | { \ 1798 | void *s = (void*)start; \ 1799 | void *e = s + len; \ 1800 | dmac_flush_range(s, e); \ 1801 | outer_flush_range(__pa(s), __pa(e)); \ 1802 | } 1803 | #endif 1804 | 1805 | /*! @} *//* cacheops */ 1806 | 1807 | #endif /* LINUX_PORT_H */ 1808 | -------------------------------------------------------------------------------- /mxc_scc2_driver.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. 4 | */ 5 | 6 | /* 7 | * The code contained herein is licensed under the GNU General Public 8 | * License. You may obtain a copy of the GNU General Public License 9 | * Version 2 or later at the following locations: 10 | * 11 | * http://www.opensource.org/licenses/gpl-license.html 12 | * http://www.gnu.org/copyleft/gpl.html 13 | */ 14 | 15 | #ifndef SCC_DRIVER_H 16 | #define SCC_DRIVER_H 17 | 18 | /* 19 | * NAMING CONVENTIONS 20 | * ================== 21 | * (A note to maintainers and other interested parties) 22 | * 23 | * Use scc_ or SCC_ prefix for 'high-level' interface routines and the types 24 | * passed to those routines. Try to avoid #defines in these interfaces. 25 | * 26 | * Use SMN_ or SCM_ prefix for the #defines used with scc_read_register() and 27 | * scc_write_register, or values passed/retrieved from those routines. 28 | */ 29 | 30 | /*! @file mxc_scc2_driver.h 31 | * 32 | * @brief (Header file to use the SCC2 driver.) 33 | * 34 | * The SCC2 driver is available to other kernel modules directly. Secure 35 | * Partition functionality is extended to users through the SHW API. Other 36 | * functionality of the SCC2 is limited to kernel-space users. 37 | * 38 | * With the exception of #scc_monitor_security_failure(), all routines are 39 | * 'synchronous', i.e. they will not return to their caller until the requested 40 | * action is complete, or fails to complete. Some of these functions could 41 | * take quite a while to perform, depending upon the request. 42 | * 43 | * Routines are provided to: 44 | * @li trigger a security-violation alarm - #scc_set_sw_alarm() 45 | * @li get configuration and version information - #scc_get_configuration() 46 | * @li zeroize memory - #scc_zeroize_memories() 47 | * @li Work with secure partitions: #scc_allocate_partition() 48 | * #scc_engage_partition() #scc_diminish_permissions() 49 | * #scc_release_partition() 50 | * @li Encrypt or decrypt regions of data: #scc_encrypt_region() 51 | * #scc_decrypt_region() 52 | * @li monitor the Security Failure alarm - #scc_monitor_security_failure() 53 | * @li stop monitoring Security Failure alarm - 54 | * #scc_stop_monitoring_security_failure() 55 | * @li write registers of the SCC - #scc_write_register() 56 | * @li read registers of the SCC - #scc_read_register() 57 | * 58 | * The SCC2 encrypts and decrypts using Triple DES with an internally stored 59 | * key. When the SCC2 is in Secure mode, it uses its secret, unique-per-chip 60 | * key. When it is in Non-Secure mode, it uses a default key. This ensures 61 | * that secrets stay secret if the SCC2 is not in Secure mode. 62 | * 63 | * Not all functions that could be provided in a 'high level' manner have been 64 | * implemented. Among the missing are interfaces to the ASC/AIC components and 65 | * the timer functions. These and other features must be accessed through 66 | * #scc_read_register() and #scc_write_register(), using the @c \#define values 67 | * provided. 68 | * 69 | * Here is a glossary of acronyms used in the SCC2 driver documentation: 70 | * - CBC - Cipher Block Chaining. A method of performing a block cipher. 71 | * Each block is encrypted using some part of the result of the previous 72 | * block's encryption. It needs an 'initialization vector' to seed the 73 | * operation. 74 | * - ECB - Electronic Code Book. A method of performing a block cipher. 75 | * With a given key, a given block will always encrypt to the same value. 76 | * - DES - Data Encryption Standard. (8-byte) Block cipher algorithm which 77 | * uses 56-bit keys. In SCC2, this key is constant and unique to the device. 78 | * SCC uses the "triple DES" form of this algorithm. 79 | * - AIC - Algorithm Integrity Checker. 80 | * - ASC - Algorithm Sequence Checker. 81 | * - SMN - Security Monitor. The part of the SCC2 responsible for monitoring 82 | * for security problems and notifying the CPU and other PISA components. 83 | * - SCM - Secure Memory. The part of the SCC2 which handles the cryptography. 84 | * - SCC - Security Controller. Central security mechanism for PISA. 85 | * - PISA - Platform-Independent Security Architecture. 86 | */ 87 | 88 | /* Temporarily define compile-time flags to make Doxygen happy. */ 89 | #ifdef DOXYGEN_HACK 90 | /** @defgroup scccompileflags SCC Driver compile-time flags 91 | * 92 | * These preprocessor flags should be set, if desired, in a makefile so 93 | * that they show up on the compiler command line. 94 | */ 95 | /** @addtogroup scccompileflags */ 96 | 97 | /** @{ */ 98 | /** 99 | * Compile-time flag to change @ref smnregs and @ref scmregs 100 | * offset values for the SCC's implementation on the MX.21 board. 101 | * 102 | * This must also be set properly for any code which calls the 103 | * scc_read_register() or scc_write_register() functions or references the 104 | * register offsets. 105 | */ 106 | #define TAHITI 107 | /** @} */ 108 | #undef TAHITI 109 | 110 | #endif /* DOXYGEN_HACK */ 111 | 112 | /*! Major Version of the driver. Used for 113 | scc_configuration->driver_major_version */ 114 | #define SCC_DRIVER_MAJOR_VERSION 2 115 | /*! Old Minor Version of the driver. */ 116 | #define SCC_DRIVER_MINOR_VERSION_0 0 117 | /*! Minor Version of the driver. Used for 118 | scc_configuration->driver_minor_version */ 119 | #define SCC_DRIVER_MINOR_VERSION_2 2 120 | 121 | 122 | /** 123 | * @typedef scc_return_t 124 | */ 125 | /** Common status return values from SCC driver functions. */ 126 | typedef enum scc_return_t { 127 | SCC_RET_OK = 0, /**< Function succeeded */ 128 | SCC_RET_FAIL, /**< Non-specific failure */ 129 | SCC_RET_VERIFICATION_FAILED, 130 | /**< Decrypt validation failed */ 131 | SCC_RET_TOO_MANY_FUNCTIONS, 132 | /**< At maximum registered functions */ 133 | SCC_RET_BUSY, /**< SCC is busy and cannot handle request */ 134 | /**< Encryption or decryption failed because@c count_out_bytes 135 | says that @c data_out is too small to hold the value. */ 136 | SCC_RET_INSUFFICIENT_SPACE, 137 | } scc_return_t; 138 | 139 | /** 140 | * @typedef scc_partition_status_t 141 | */ 142 | /** Partition status information. */ 143 | typedef enum scc_partition_status_t { 144 | SCC_PART_S_UNUSABLE, 145 | /**< Partition not implemented */ 146 | SCC_PART_S_UNAVAILABLE, 147 | /**< Partition owned by other host */ 148 | SCC_PART_S_AVAILABLE, 149 | /**< Partition available */ 150 | SCC_PART_S_ALLOCATED, 151 | /**< Partition owned by host but not engaged*/ 152 | SCC_PART_S_ENGAGED, 153 | /**< Partition owned by host and engaged */ 154 | } scc_partition_status_t; 155 | 156 | /** 157 | * Configuration information about SCC and the driver. 158 | * 159 | * This struct/typedef contains information from the SCC and the driver to 160 | * allow the user of the driver to determine the size of the SCC's memories and 161 | * the version of the SCC and the driver. 162 | */ 163 | typedef struct scc_config_t { 164 | int driver_major_version; 165 | /**< Major version of the SCC driver code */ 166 | int driver_minor_version; 167 | /**< Minor version of the SCC driver code */ 168 | int scm_version; /**< Version from SCM Configuration register */ 169 | int smn_version; /**< Version from SMN Status register */ 170 | /**< Number of bytes per block of RAM; also 171 | block size of the crypto algorithm. */ 172 | int block_size_bytes; 173 | int partition_size_bytes; 174 | /**< Number of bytes in each partition */ 175 | int partition_count; 176 | /**< Number of partitions on this platform */ 177 | } scc_config_t; 178 | 179 | /** 180 | * @typedef scc_enc_dec_t 181 | */ 182 | /** 183 | * Determine whether SCC will run its cryptographic 184 | * function as an encryption or decryption. 185 | */ 186 | typedef enum scc_enc_dec_t { 187 | SCC_ENCRYPT, /**< Encrypt (from Red to Black) */ 188 | SCC_DECRYPT /**< Decrypt (from Black to Red) */ 189 | } scc_enc_dec_t; 190 | 191 | /** 192 | * @typedef scc_verify_t 193 | */ 194 | /** 195 | * Tell the driver whether it is responsible for verifying the integrity of a 196 | * secret. During an encryption, using other than #SCC_VERIFY_MODE_NONE will 197 | * cause a check value to be generated and appended to the plaintext before 198 | * encryption. During decryption, the check value will be verified after 199 | * decryption, and then stripped from the message. 200 | */ 201 | typedef enum scc_verify_t { 202 | /** No verification value added or checked. Input plaintext data must be 203 | * be a multiple of the blocksize (#scc_get_configuration()). */ 204 | SCC_VERIFY_MODE_NONE, 205 | /** Driver will generate/validate a 2-byte CCITT CRC. Input plaintext 206 | will be padded to a multiple of the blocksize, adding 3-10 bytes 207 | to the resulting output ciphertext. Upon decryption, this padding 208 | will be stripped, and the CRC will be verified. */ 209 | SCC_VERIFY_MODE_CCITT_CRC 210 | } scc_verify_t; 211 | 212 | /** 213 | * @typedef scc_cypher_mode_t 214 | */ 215 | /** 216 | * Select the cypher mode to use for partition cover/uncover operations. 217 | */ 218 | 219 | typedef enum scc_cypher_mode_t { 220 | SCC_CYPHER_MODE_ECB = 1, 221 | /**< ECB mode */ 222 | SCC_CYPHER_MODE_CBC = 2, 223 | /**< CBC mode */ 224 | } scc_cypher_mode_t; 225 | 226 | /** 227 | * Allocate a partition of secure memory 228 | * 229 | * @param smid_value Value to use for the SMID register. Must be 0 for 230 | * kernel mode ownership. 231 | * @param[out] part_no (If successful) Assigned partition number. 232 | * @param[out] part_base Kernel virtual address of the partition. 233 | * @param[out] part_phys Physical address of the partition. 234 | * 235 | * @return SCC_RET_OK if successful. 236 | */ 237 | extern scc_return_t 238 | scc_allocate_partition(uint32_t smid_value, 239 | int *part_no, 240 | void **part_base, uint32_t *part_phys); 241 | 242 | /* Note: This function has to be run in the same context (userspace or kernel 243 | * mode) as the process that will be using the partition. Because the SCC2 API 244 | * is not accessible in user mode, this function is also provided as a macro in 245 | * in fsl_shw.h. Kernel-mode users that include this file are able to use this 246 | * version of the function without having to include the whole SHW API. If the 247 | * macro definition was defined before we got here, un-define it so this 248 | * version will be used instead. 249 | */ 250 | 251 | #ifdef scc_engage_partition 252 | #undef scc_engage_partition 253 | #endif 254 | 255 | /** 256 | * Engage partition of secure memory 257 | * 258 | * @param part_base (kernel) Virtual 259 | * @param UMID NULL, or 16-byte UMID for partition security 260 | * @param permissions ORed values of the type SCM_PERM_* which will be used as 261 | * initial partition permissions. SHW API users should use 262 | * the FSL_PERM_* definitions instead. 263 | * 264 | * @return SCC_RET_OK if successful. 265 | */ 266 | extern scc_return_t 267 | scc_engage_partition(void *part_base, 268 | const uint8_t *UMID, uint32_t permissions); 269 | 270 | /** 271 | * Release a partition of secure memory 272 | * 273 | * @param part_base Kernel virtual address of the partition to be released. 274 | * 275 | * @return SCC_RET_OK if successful. 276 | */ 277 | extern scc_return_t scc_release_partition(void *part_base); 278 | 279 | /** 280 | * Diminish the permissions on a partition of secure memory 281 | * 282 | * @param part_base Kernel virtual address of the partition. 283 | * 284 | * @param permissions ORed values of the type SCM_PERM_* which will be used as 285 | * initial partition permissions. SHW API users should use 286 | * the FSL_PERM_* definitions instead. 287 | * 288 | * @return SCC_RET_OK if successful. 289 | */ 290 | extern scc_return_t 291 | scc_diminish_permissions(void *part_base, uint32_t permissions); 292 | 293 | /** 294 | * Query the status of a partition of secure memory 295 | * 296 | * @param part_base Kernel virtual address of the partition. 297 | * 298 | * @return SCC_RET_OK if successful. 299 | */ 300 | extern scc_partition_status_t scc_partition_status(void *part_base); 301 | 302 | /** 303 | * Calculate the physical address from the kernel virtual address. 304 | */ 305 | extern uint32_t scc_virt_to_phys(void *address); 306 | /*scc_return_t 307 | scc_verify_slot_access(uint64_t owner_id, uint32_t slot, uint32_t access_len);*/ 308 | 309 | 310 | /** 311 | * Encrypt a region of secure memory. 312 | * 313 | * @param part_base Kernel virtual address of the partition. 314 | * @param offset_bytes Offset from the start of the partition to the plaintext 315 | * data. 316 | * @param byte_count Length of the region (octets). 317 | * @param black_data Physical location to store the encrypted data. 318 | * @param IV Value to use for the Initialization Vector. 319 | * @param cypher_mode Cyphering mode to use, specified by type 320 | * #scc_cypher_mode_t 321 | * 322 | * @return SCC_RET_OK if successful. 323 | */ 324 | extern scc_return_t 325 | scc_encrypt_region(uint32_t part_base, uint32_t offset_bytes, 326 | uint32_t byte_count, uint8_t *black_data, 327 | uint32_t *IV, scc_cypher_mode_t cypher_mode); 328 | 329 | /** 330 | * Decrypt a region into secure memory 331 | * 332 | * @param part_base Kernel virtual address of the partition. 333 | * @param offset_bytes Offset from the start of the partition to store the 334 | * plaintext data. 335 | * @param byte_count Length of the region (octets). 336 | * @param black_data Physical location of the encrypted data. 337 | * @param IV Value to use for the Initialization Vector. 338 | * @param cypher_mode Cyphering mode to use, specified by type 339 | * #scc_cypher_mode_t 340 | * 341 | * @return SCC_RET_OK if successful. 342 | */ 343 | extern scc_return_t 344 | scc_decrypt_region(uint32_t part_base, uint32_t offset_bytes, 345 | uint32_t byte_count, uint8_t *black_data, 346 | uint32_t *IV, scc_cypher_mode_t cypher_mode); 347 | 348 | /** 349 | * Retrieve configuration information from the SCC. 350 | * 351 | * This function always succeeds. 352 | * 353 | * @return A pointer to the configuration information. This is a pointer to 354 | * static memory and must not be freed. The values never change, and 355 | * the return value will never be null. 356 | */ 357 | extern scc_config_t *scc_get_configuration(void); 358 | 359 | /** 360 | * Zeroize Red and Black memories of the SCC. This will start the Zeroizing 361 | * process. The routine will return when the memories have zeroized or failed 362 | * to do so. The driver will poll waiting for this to occur, so this 363 | * routine must not be called from interrupt level. Some future version of 364 | * driver may elect instead to sleep. 365 | * 366 | * @return 0 or error if initialization fails. 367 | */ 368 | extern scc_return_t scc_zeroize_memories(void); 369 | 370 | /** 371 | * Signal a software alarm to the SCC. This will take the SCC and other PISA 372 | * parts out of Secure mode and into Security Failure mode. The SCC will stay 373 | * in failed mode until a reboot. 374 | * 375 | * @internal 376 | * If the SCC is not already in fail state, simply write the 377 | * #SMN_COMMAND_SET_SOFTWARE_ALARM bit in #SMN_COMMAND_REG. Since there is no 378 | * reason to wait for the interrupt to bounce back, simply act as though 379 | * one did. 380 | */ 381 | extern void scc_set_sw_alarm(void); 382 | 383 | /** 384 | * This routine will register a function to be called should a Security Failure 385 | * be signalled by the SCC (Security Monitor). 386 | * 387 | * The callback function may be called from interrupt level, it may be called 388 | * from some process' task. It should therefore not take a long time to 389 | * perform its operation, and it may not sleep. 390 | * 391 | * @param callback_func Function pointer to routine which will receive 392 | * notification of the security failure. 393 | * @return 0 if function was successfully registered, non-zero on 394 | * failure. See #scc_return_t. 395 | * 396 | * @internal 397 | * There is a fixed global static array which keeps track of the requests to 398 | * monitor the failure. 399 | * 400 | * Add @c callback_func to the first empty slot in #scc_callbacks[]. If there 401 | * is no room, return #SCC_RET_TOO_MANY_FUNCTIONS. 402 | */ 403 | extern scc_return_t scc_monitor_security_failure(void 404 | callback_func(void)); 405 | 406 | /** 407 | * This routine will deregister a function previously registered with 408 | * #scc_monitor_security_failure(). 409 | * 410 | * @param callback_func Function pointer to routine previously registered with 411 | * #scc_stop_monitoring_security_failure(). 412 | */ 413 | extern void scc_stop_monitoring_security_failure(void 414 | callback_func(void)); 415 | 416 | /** 417 | * Read value from an SCC register. 418 | * The offset will be checked for validity (range) as well as whether it is 419 | * accessible (e.g. not busy, not in failed state) at the time of the call. 420 | * 421 | * @param[in] register_offset The (byte) offset within the SCC block 422 | * of the register to be queried. See 423 | * @ref scmregs and @ref smnregs. 424 | * @param[out] value Pointer to where value from the register 425 | * should be placed. 426 | * @return 0 if OK, non-zero on error. See #scc_return_t. 427 | * 428 | * @internal 429 | * Verify that the register_offset is a) valid, b) refers to a readable 430 | * register, and c) the SCC is in a state which would allow a read of this 431 | * register. 432 | */ 433 | extern scc_return_t scc_read_register(int register_offset, 434 | uint32_t *value); 435 | 436 | /** 437 | * Write a new value into an SCC register. 438 | * The offset will be checked for validity (range) as well as whether it is 439 | * accessible (e.g. not busy, not in failed state) at the time of the call. 440 | * 441 | * @param[in] register_offset The (byte) offset within the SCC block 442 | * of the register to be modified. See 443 | * @ref scmregs and @ref smnregs 444 | * @param[in] value The value to store into the register. 445 | * @return 0 if OK, non-zero on error. See #scc_return_t. 446 | * 447 | * @internal 448 | * Verify that the register_offset is a) valid, b) refers to a writeable 449 | * register, and c) the SCC is in a state which would allow a write to this 450 | * register. 451 | */ 452 | extern scc_return_t scc_write_register(int register_offset, 453 | uint32_t value); 454 | 455 | /** 456 | * @defgroup scmregs SCM Registers 457 | * 458 | * These values are offsets into the SCC for the Secure Memory 459 | * (SCM) registers. They are used in the @c register_offset parameter of 460 | * #scc_read_register() and #scc_write_register(). 461 | */ 462 | /** @addtogroup scmregs */ 463 | /** @{ */ 464 | /** Offset of SCM Version ID Register */ 465 | #define SCM_VERSION_REG 0x000 466 | /** Offset of SCM Interrupt Control Register */ 467 | #define SCM_INT_CTL_REG 0x008 468 | /** Offset of SCM Status Register */ 469 | #define SCM_STATUS_REG 0x00c 470 | /** Offset of SCM Error Status Register */ 471 | #define SCM_ERR_STATUS_REG 0x010 472 | /** Offset of SCM Fault Address Register */ 473 | #define SCM_FAULT_ADR_REG 0x014 474 | /** Offset of SCM Partition Owners Register */ 475 | #define SCM_PART_OWNERS_REG 0x018 476 | /** Offset of SCM Partitions Engaged Register */ 477 | #define SCM_PART_ENGAGED_REG 0x01c 478 | /** Offset of SCM Unique Number 0 Register */ 479 | #define SCM_UNIQUE_ID0_REG 0x020 480 | /** Offset of SCM Unique Number 1 Register */ 481 | #define SCM_UNIQUE_ID1_REG 0x024 482 | /** Offset of SCM Unique Number 2 Register */ 483 | #define SCM_UNIQUE_ID2_REG 0x028 484 | /** Offset of SCM Unique Number 3 Register */ 485 | #define SCM_UNIQUE_ID3_REG 0x02c 486 | /** Offset of SCM Zeroize Command Register */ 487 | #define SCM_ZCMD_REG 0x050 488 | /** Offset of SCM Cipher Command Register */ 489 | #define SCM_CCMD_REG 0x054 490 | /** Offset of SCM Cipher Black RAM Start Address Register */ 491 | #define SCM_C_BLACK_ST_REG 0x058 492 | /** Offset of SCM Internal Debug Register */ 493 | #define SCM_DBG_STATUS_REG 0x05c 494 | /** Offset of SCM Cipher IV 0 Register */ 495 | #define SCM_AES_CBC_IV0_REG 0x060 496 | /** Offset of SCM Cipher IV 1 Register */ 497 | #define SCM_AES_CBC_IV1_REG 0x064 498 | /** Offset of SCM Cipher IV 2 Register */ 499 | #define SCM_AES_CBC_IV2_REG 0x068 500 | /** Offset of SCM Cipher IV 3 Register */ 501 | #define SCM_AES_CBC_IV3_REG 0x06c 502 | /** Offset of SCM SMID Partition 0 Register */ 503 | #define SCM_SMID0_REG 0x080 504 | /** Offset of SCM Partition 0 Access Permissions Register */ 505 | #define SCM_ACC0_REG 0x084 506 | /** Offset of SCM SMID Partition 1 Register */ 507 | #define SCM_SMID1_REG 0x088 508 | /** Offset of SCM Partition 1 Access Permissions Register */ 509 | #define SCM_ACC1_REG 0x08c 510 | /** Offset of SCM SMID Partition 2 Register */ 511 | #define SCM_SMID2_REG 0x090 512 | /** Offset of SCM Partition 2 Access Permissions Register */ 513 | #define SCM_ACC2_REG 0x094 514 | /** Offset of SCM SMID Partition 3 Register */ 515 | #define SCM_SMID3_REG 0x098 516 | /** Offset of SCM Partition 3 Access Permissions Register */ 517 | #define SCM_ACC3_REG 0x09c 518 | /** Offset of SCM SMID Partition 4 Register */ 519 | #define SCM_SMID4_REG 0x0a0 520 | /** Offset of SCM Partition 4 Access Permissions Register */ 521 | #define SCM_ACC4_REG 0x0a4 522 | /** Offset of SCM SMID Partition 5 Register */ 523 | #define SCM_SMID5_REG 0x0a8 524 | /** Offset of SCM Partition 5 Access Permissions Register */ 525 | #define SCM_ACC5_REG 0x0ac 526 | /** Offset of SCM SMID Partition 6 Register */ 527 | #define SCM_SMID6_REG 0x0b0 528 | /** Offset of SCM Partition 6 Access Permissions Register */ 529 | #define SCM_ACC6_REG 0x0b4 530 | /** Offset of SCM SMID Partition 7 Register */ 531 | #define SCM_SMID7_REG 0x0b8 532 | /** Offset of SCM Partition 7 Access Permissions Register */ 533 | #define SCM_ACC7_REG 0x0bc 534 | /** Offset of SCM SMID Partition 8 Register */ 535 | #define SCM_SMID8_REG 0x0c0 536 | /** Offset of SCM Partition 8 Access Permissions Register */ 537 | #define SCM_ACC8_REG 0x0c4 538 | /** Offset of SCM SMID Partition 9 Register */ 539 | #define SCM_SMID9_REG 0x0c8 540 | /** Offset of SCM Partition 9 Access Permissions Register */ 541 | #define SCM_ACC9_REG 0x0cc 542 | /** Offset of SCM SMID Partition 10 Register */ 543 | #define SCM_SMID10_REG 0x0d0 544 | /** Offset of SCM Partition 10 Access Permissions Register */ 545 | #define SCM_ACC10_REG 0x0d4 546 | /** Offset of SCM SMID Partition 11 Register */ 547 | #define SCM_SMID11_REG 0x0d8 548 | /** Offset of SCM Partition 11 Access Permissions Register */ 549 | #define SCM_ACC11_REG 0x0dc 550 | /** Offset of SCM SMID Partition 12 Register */ 551 | #define SCM_SMID12_REG 0x0e0 552 | /** Offset of SCM Partition 12 Access Permissions Register */ 553 | #define SCM_ACC12_REG 0x0e4 554 | /** Offset of SCM SMID Partition 13 Register */ 555 | #define SCM_SMID13_REG 0x0e8 556 | /** Offset of SCM Partition 13 Access Permissions Register */ 557 | #define SCM_ACC13_REG 0x0ec 558 | /** Offset of SCM SMID Partition 14 Register */ 559 | #define SCM_SMID14_REG 0x0f0 560 | /** Offset of SCM Partition 14 Access Permissions Register */ 561 | #define SCM_ACC14_REG 0x0f4 562 | /** Offset of SCM SMID Partition 15 Register */ 563 | #define SCM_SMID15_REG 0x0f8 564 | /** Offset of SCM Partition 15 Access Permissions Register */ 565 | #define SCM_ACC15_REG 0x0fc 566 | /** @} */ 567 | 568 | /** Number of bytes of register space for the SCM. */ 569 | #define SCM_REG_BANK_SIZE 0x100 570 | 571 | /** Number of bytes of register space for the SCM. */ 572 | #define SCM_REG_BANK_SIZE 0x100 573 | 574 | /** Offset of the SMN registers */ 575 | #define SMN_ADDR_OFFSET 0x100 576 | 577 | /** 578 | * @defgroup smnregs SMN Registers 579 | * 580 | * These values are offsets into the SCC for the Security Monitor 581 | * (SMN) registers. They are used in the @c register_offset parameter of the 582 | * #scc_read_register() and #scc_write_register(). 583 | */ 584 | /** @addtogroup smnregs */ 585 | /** @{ */ 586 | /** Offset of SMN Status Register */ 587 | #define SMN_STATUS_REG (SMN_ADDR_OFFSET+0x00000000) 588 | /** Offset of SMH Command Register */ 589 | #define SMN_COMMAND_REG (SMN_ADDR_OFFSET+0x00000004) 590 | /** Offset of SMH Sequence Start Register */ 591 | #define SMN_SEQ_START_REG (SMN_ADDR_OFFSET+0x00000008) 592 | /** Offset of SMH Sequence End Register */ 593 | #define SMN_SEQ_END_REG (SMN_ADDR_OFFSET+0x0000000c) 594 | /** Offset of SMH Sequence Check Register */ 595 | #define SMN_SEQ_CHECK_REG (SMN_ADDR_OFFSET+0x00000010) 596 | /** Offset of SMH BitBank Count Register */ 597 | #define SMN_BB_CNT_REG (SMN_ADDR_OFFSET+0x00000014) 598 | /** Offset of SMH BitBank Increment Register */ 599 | #define SMN_BB_INC_REG (SMN_ADDR_OFFSET+0x00000018) 600 | /** Offset of SMH BitBank Decrement Register */ 601 | #define SMN_BB_DEC_REG (SMN_ADDR_OFFSET+0x0000001c) 602 | /** Offset of SMH Compare Register */ 603 | #define SMN_COMPARE_REG (SMN_ADDR_OFFSET+0x00000020) 604 | /** Offset of SMH Plaintext Check Register */ 605 | #define SMN_PT_CHK_REG (SMN_ADDR_OFFSET+0x00000024) 606 | /** Offset of SMH Ciphertext Check Register */ 607 | #define SMN_CT_CHK_REG (SMN_ADDR_OFFSET+0x00000028) 608 | /** Offset of SMH Timer Initial Value Register */ 609 | #define SMN_TIMER_IV_REG (SMN_ADDR_OFFSET+0x0000002c) 610 | /** Offset of SMH Timer Control Register */ 611 | #define SMN_TIMER_CTL_REG (SMN_ADDR_OFFSET+0x00000030) 612 | /** Offset of SMH Security Violation Register */ 613 | #define SMN_SEC_VIO_REG (SMN_ADDR_OFFSET+0x00000034) 614 | /** Offset of SMH Timer Register */ 615 | #define SMN_TIMER_REG (SMN_ADDR_OFFSET+0x00000038) 616 | /** Offset of SMH High-Assurance Control Register */ 617 | #define SMN_HAC_REG (SMN_ADDR_OFFSET+0x0000003c) 618 | /** Number of bytes allocated to the SMN registers */ 619 | #define SMN_REG_BANK_SIZE 0x40 620 | /** @} */ 621 | 622 | /** Number of bytes of total register space for the SCC. */ 623 | #define SCC_ADDRESS_RANGE (SMN_ADDR_OFFSET + SMN_REG_BANK_SIZE) 624 | 625 | /** 626 | * @defgroup smnstatusregdefs SMN Status Register definitions (SMN_STATUS) 627 | */ 628 | /** @addtogroup smnstatusregdefs */ 629 | /** @{ */ 630 | /** SMN version id. */ 631 | #define SMN_STATUS_VERSION_ID_MASK 0xfc000000 632 | /** number of bits to shift #SMN_STATUS_VERSION_ID_MASK to get it to LSB */ 633 | #define SMN_STATUS_VERSION_ID_SHIFT 28 634 | /** Illegal bus master access attempted. */ 635 | #define SMN_STATUS_ILLEGAL_MASTER 0x01000000 636 | /** Scan mode entered/exited since last reset. */ 637 | #define SMN_STATUS_SCAN_EXIT 0x00800000 638 | /** Some security peripheral is initializing */ 639 | #define SMN_STATUS_PERIP_INIT 0x00010000 640 | /** Internal error detected in SMN. */ 641 | #define SMN_STATUS_SMN_ERROR 0x00004000 642 | /** SMN has an outstanding interrupt. */ 643 | #define SMN_STATUS_SMN_STATUS_IRQ 0x00004000 644 | /** Software Alarm was triggered. */ 645 | #define SMN_STATUS_SOFTWARE_ALARM 0x00002000 646 | /** Timer has expired. */ 647 | #define SMN_STATUS_TIMER_ERROR 0x00001000 648 | /** Plaintext/Ciphertext compare failed. */ 649 | #define SMN_STATUS_PC_ERROR 0x00000800 650 | /** Bit Bank detected overflow or underflow */ 651 | #define SMN_STATUS_BITBANK_ERROR 0x00000400 652 | /** Algorithm Sequence Check failed. */ 653 | #define SMN_STATUS_ASC_ERROR 0x00000200 654 | /** Security Policy Block detected error. */ 655 | #define SMN_STATUS_SECURITY_POLICY_ERROR 0x00000100 656 | /** Security Violation Active error. */ 657 | #define SMN_STATUS_SEC_VIO_ACTIVE_ERROR 0x00000080 658 | /** Processor booted from internal ROM. */ 659 | #define SMN_STATUS_INTERNAL_BOOT 0x00000020 660 | /** SMN's internal state. */ 661 | #define SMN_STATUS_STATE_MASK 0x0000001F 662 | /** Number of bits to shift #SMN_STATUS_STATE_MASK to get it to LSB. */ 663 | #define SMN_STATUS_STATE_SHIFT 0 664 | /** @} */ 665 | 666 | /** 667 | * @defgroup sccscmstates SMN Model Secure State Controller States (SMN_STATE_MASK) 668 | */ 669 | /** @addtogroup sccscmstates */ 670 | /** @{ */ 671 | /** This is the first state of the SMN after power-on reset */ 672 | #define SMN_STATE_START 0x0 673 | /** The SMN is zeroizing its RAM during reset */ 674 | #define SMN_STATE_ZEROIZE_RAM 0x5 675 | /** SMN has passed internal checks, and is waiting for Software check-in */ 676 | #define SMN_STATE_HEALTH_CHECK 0x6 677 | /** Fatal Security Violation. SMN is locked, SCM is inoperative. */ 678 | #define SMN_STATE_FAIL 0x9 679 | /** SCC is in secure state. SCM is using secret key. */ 680 | #define SMN_STATE_SECURE 0xA 681 | /** Due to non-fatal error, device is not secure. SCM is using default key. */ 682 | #define SMN_STATE_NON_SECURE 0xC 683 | /** @} */ 684 | 685 | /** @{ */ 686 | /** SCM Status bit: Key Status is Default Key in Use */ 687 | #define SCM_STATUS_KST_DEFAULT_KEY 0x80000000 688 | /** SCM Status bit: Key Status is (reserved) */ 689 | #define SCM_STATUS_KST_RESERVED1 0x40000000 690 | /** SCM Status bit: Key status is Wrong Key */ 691 | #define SCM_STATUS_KST_WRONG_KEY 0x20000000 692 | /** SCM Status bit: Bad Key detected */ 693 | #define SCM_STATUS_KST_BAD_KEY 0x10000000 694 | /** SCM Status bit: Error has occurred */ 695 | #define SCM_STATUS_ERR 0x00008000 696 | /** SCM Status bit: Monitor State is Failed */ 697 | #define SCM_STATUS_MSS_FAIL 0x00004000 698 | /** SCM Status bit: Monitor State is Secure */ 699 | #define SCM_STATUS_MSS_SEC 0x00002000 700 | /** SCM Status bit: Secure Storage is Failed */ 701 | #define SCM_STATUS_RSS_FAIL 0x00000400 702 | /** SCM Status bit: Secure Storage is Secure */ 703 | #define SCM_STATUS_RSS_SEC 0x00000200 704 | /** SCM Status bit: Secure Storage is Initializing */ 705 | #define SCM_STATUS_RSS_INIT 0x00000100 706 | /** SCM Status bit: Unique Number Valid */ 707 | #define SCM_STATUS_UNV 0x00000080 708 | /** SCM Status bit: Big Endian mode */ 709 | #define SCM_STATUS_BIG 0x00000040 710 | /** SCM Status bit: Using Secret Key */ 711 | #define SCM_STATUS_USK 0x00000020 712 | /** SCM Status bit: Ram is being blocked */ 713 | #define SCM_STATUS_BAR 0x00000010 714 | /** Bit mask of SRS */ 715 | #define SCM_STATUS_SRS_MASK 0x0000000F 716 | /** Number of bits to shift SRS to/from MSb */ 717 | #define SCM_STATUS_SRS_SHIFT 0 718 | /** @} */ 719 | 720 | #define SCM_STATUS_SRS_RESET 0x0 /**< Reset, Zeroise All */ 721 | #define SCM_STATUS_SRS_READY 0x1 /**< All Ready */ 722 | #define SCM_STATUS_SRS_ZBUSY 0x2 /**< Zeroize Busy (Partition Only) */ 723 | #define SCM_STATUS_SRS_CBUSY 0x3 /**< Cipher Busy */ 724 | #define SCM_STATUS_SRS_ABUSY 0x4 /**< All Busy */ 725 | #define SCM_STATUS_SRS_ZDONE 0x5 /**< Zeroize Done, Cipher Ready */ 726 | #define SCM_STATUS_SRS_CDONE 0x6 /**< Cipher Done, Zeroize Ready */ 727 | #define SCM_STATUS_SRS_ZDONE2 0x7 /**< Zeroize Done, Cipher Busy */ 728 | #define SCM_STATUS_SRS_CDONE2 0x8 /**< Cipher Done, Zeroize Busy */ 729 | #define SCM_STATUS_SRS_ADONE 0xD /**< All Done */ 730 | #define SCM_STATUS_SRS_FAIL 0xF /**< Fail State */ 731 | 732 | 733 | /* Format of the SCM VERSION ID REGISTER */ 734 | #define SCM_VER_BPP_MASK 0xFF000000 /**< Bytes Per Partition Mask */ 735 | #define SCM_VER_BPP_SHIFT 24 /**< Bytes Per Partition Shift */ 736 | #define SCM_VER_BPCB_MASK 0x001F0000 /**< Bytes Per Cipher Block Mask */ 737 | #define SCM_VER_BPCB_SHIFT 16 /**< Bytes Per Cipher Block Shift */ 738 | #define SCM_VER_NP_MASK 0x0000F000 /**< Number of Partitions Mask */ 739 | #define SCM_VER_NP_SHIFT 12 /**< Number of Partitions Shift */ 740 | #define SCM_VER_MAJ_MASK 0x00000F00 /**< Major Version Mask */ 741 | #define SCM_VER_MAJ_SHIFT 8 /**< Major Version Shift */ 742 | #define SCM_VER_MIN_MASK 0x000000FF /**< Minor Version Mask */ 743 | #define SCM_VER_MIN_SHIFT 0 /**< Minor Version Shift */ 744 | 745 | /**< SCC Hardware version supported by this driver */ 746 | #define SCM_MAJOR_VERSION_2 2 747 | 748 | /* Format of the SCM ERROR STATUS REGISTER */ 749 | #define SCM_ERRSTAT_MID_MASK 0x00F00000 /**< Master ID Mask */ 750 | #define SCM_ERRSTAT_MID_SHIFT 20 /**< Master ID Shift */ 751 | #define SCM_ERRSTAT_ILM 0x00080000 /**< Illegal Master */ 752 | #define SCM_ERRSTAT_SUP 0x00008000 /**< Supervisor Access */ 753 | #define SCM_ERRSTAT_ERC_MASK 0x00000F00 /**< Error Code Mask */ 754 | #define SCM_ERRSTAT_ERC_SHIFT 8 /**< Error Code Shift */ 755 | #define SCM_ERRSTAT_SMS_MASK 0x000000F0 /**< Secure Monitor State Mask */ 756 | #define SCM_ERRSTAT_SMS_SHIFT 4 /**< Secure Monitor State Shift */ 757 | #define SCM_ERRSTAT_SRS_MASK 0x0000000F /**< Secure Ram State Mask */ 758 | #define SCM_ERRSTAT_SRS_SHIFT 0 /**< Secure Ram State Shift */ 759 | 760 | /* SCM ERROR STATUS REGISTER ERROR CODES */ 761 | #define SCM_ERCD_UNK_ADDR 0x1 /**< Unknown Address */ 762 | #define SCM_ERCD_UNK_CMD 0x2 /**< Unknown Command */ 763 | #define SCM_ERCD_READ_PERM 0x3 /**< Read Permission Error */ 764 | #define SCM_ERCD_WRITE_PERM 0x4 /**< Write Permission Error */ 765 | #define SCM_ERCD_DMA_ERROR 0x5 /**< DMA Error */ 766 | #define SCM_ERCD_BLK_OVFL 0x6 /**< Encryption Block Length Overflow */ 767 | #define SCM_ERCD_NO_KEY 0x7 /**< Key Not Engaged */ 768 | #define SCM_ERCD_ZRZ_OVFL 0x8 /**< Zeroize Command Queue Overflow */ 769 | #define SCM_ERCD_CPHR_OVFL 0x9 /**< Cipher Command Queue Overflow */ 770 | #define SCM_ERCD_PROC_INTR 0xA /**< Process Interrupted */ 771 | #define SCM_ERCD_WRNG_KEY 0xB /**< Wrong Key */ 772 | #define SCM_ERCD_DEVICE_BUSY 0xC /**< Device Busy */ 773 | #define SCM_ERCD_UNALGN_ADDR 0xD /**< DMA Unaligned Address */ 774 | 775 | /* Format of the CIPHER COMMAND REGISTER */ 776 | #define SCM_CCMD_LENGTH_MASK 0xFFF00000 /**< Cipher Length Mask */ 777 | #define SCM_CCMD_LENGTH_SHIFT 20 /**< Cipher Length Shift */ 778 | #define SCM_CCMD_OFFSET_MASK 0x000FFF00 /**< Block Offset Mask */ 779 | #define SCM_CCMD_OFFSET_SHIFT 8 /**< Block Offset Shift */ 780 | #define SCM_CCMD_PART_MASK 0x000000F0 /**< Partition Number Mask */ 781 | #define SCM_CCMD_PART_SHIFT 4 /**< Partition Number Shift */ 782 | #define SCM_CCMD_CCMD_MASK 0x0000000F /**< Cipher Command Mask */ 783 | #define SCM_CCMD_CCMD_SHIFT 0 /**< Cipher Command Shift */ 784 | 785 | /* Values for SCM_CCMD_CCMD field */ 786 | #define SCM_CCMD_AES_DEC_ECB 1 /**< Decrypt without Chaining (ECB) */ 787 | #define SCM_CCMD_AES_ENC_ECB 3 /**< Encrypt without Chaining (ECB) */ 788 | #define SCM_CCMD_AES_DEC_CBC 5 /**< Decrypt with Chaining (CBC) */ 789 | #define SCM_CCMD_AES_ENC_CBC 7 /**< Encrypt with Chaining (CBC) */ 790 | 791 | #define SCM_CCMD_AES 1 /**< Use AES Mode */ 792 | #define SCM_CCMD_DEC 0 /**< Decrypt */ 793 | #define SCM_CCMD_ENC 2 /**< Encrypt */ 794 | #define SCM_CCMD_ECB 0 /**< Perform operation without chaining (ECB) */ 795 | #define SCM_CCMD_CBC 4 /**< Perform operation with chaining (CBC) */ 796 | 797 | /* Format of the ZEROIZE COMMAND REGISTER */ 798 | #define SCM_ZCMD_PART_MASK 0x000000F0 /**< Target Partition Mask */ 799 | #define SCM_ZCMD_PART_SHIFT 4 /**< Target Partition Shift */ 800 | #define SCM_ZCMD_CCMD_MASK 0x0000000F /**< Zeroize Command Mask */ 801 | #define SCM_ZCMD_CCMD_SHIFT 0 /**< Zeroize Command Shift */ 802 | 803 | /* MASTER ACCESS PERMISSIONS REGISTER */ 804 | /* Note that API users should use the FSL_PERM_ defines instead of these */ 805 | /** SCM Access Permission: Do not zeroize/deallocate partition 806 | on SMN Fail state */ 807 | #define SCM_PERM_NO_ZEROIZE 0x10000000 808 | /** SCM Access Permission: Ignore Supervisor/User mode 809 | in permission determination */ 810 | #define SCM_PERM_HD_SUP_DISABLE 0x00000800 811 | /** SCM Access Permission: Allow Read Access to Host Domain */ 812 | #define SCM_PERM_HD_READ 0x00000400 813 | /** SCM Access Permission: Allow Write Access to Host Domain */ 814 | #define SCM_PERM_HD_WRITE 0x00000200 815 | /** SCM Access Permission: Allow Execute Access to Host Domain */ 816 | #define SCM_PERM_HD_EXECUTE 0x00000100 817 | /** SCM Access Permission: Allow Read Access to Trusted Host Domain */ 818 | #define SCM_PERM_TH_READ 0x00000040 819 | /** SCM Access Permission: Allow Write Access to Trusted Host Domain */ 820 | #define SCM_PERM_TH_WRITE 0x00000020 821 | /** SCM Access Permission: Allow Read Access to Other/World Domain */ 822 | #define SCM_PERM_OT_READ 0x00000004 823 | /** SCM Access Permission: Allow Write Access to Other/World Domain */ 824 | #define SCM_PERM_OT_WRITE 0x00000002 825 | /** SCM Access Permission: Allow Execute Access to Other/World Domain */ 826 | #define SCM_PERM_OT_EXECUTE 0x00000001 827 | /**< Valid bits that can be set in the Permissions register */ 828 | #define SCM_PERM_MASK 0xC0000F67 829 | 830 | /* Zeroize Command register definitions */ 831 | #define ZCMD_DEALLOC_PART 3 /**< Deallocate Partition */ 832 | #define Z_INT_EN 0x00000002 /**< Zero Interrupt Enable */ 833 | 834 | /** 835 | * @defgroup scmpartitionownersregdefs SCM Partition Owners Register 836 | */ 837 | /** @addtogroup scmpartitionownersregdefs */ 838 | /** @{ */ 839 | /** Number of bits to shift partition number to get to its field. */ 840 | #define SCM_POWN_SHIFT 2 841 | /** Mask for a field once the register has been shifted. */ 842 | #define SCM_POWN_MASK 3 843 | /** Partition is free */ 844 | #define SCM_POWN_PART_FREE 0 845 | /** Partition is unable to be allocated */ 846 | #define SCM_POWN_PART_UNUSABLE 1 847 | /** Partition is owned by another master */ 848 | #define SCM_POWN_PART_OTHER 2 849 | /** Partition is owned by this master */ 850 | #define SCM_POWN_PART_OWNED 3 851 | /** @} */ 852 | 853 | /** 854 | * @defgroup smnpartitionsengagedregdefs SCM Partitions Engaged Register 855 | */ 856 | /** @addtogroup smnpartitionsengagedregdefs */ 857 | /** @{ */ 858 | /** Number of bits to shift partition number to get to its field. */ 859 | #define SCM_PENG_SHIFT 1 860 | /** Engaged value for a field once the register has been shifted. */ 861 | #define SCM_PENG_ENGAGED 1 862 | /** @} */ 863 | 864 | /** Number of bytes between each subsequent SMID register */ 865 | #define SCM_SMID_WIDTH 8 866 | 867 | /** 868 | * @defgroup smncommandregdefs SMN Command Register Definitions (SMN_COMMAND_REG) 869 | */ 870 | /** @addtogroup smncommandregdefs */ 871 | /** @{ */ 872 | 873 | /** These bits are unimplemented or reserved */ 874 | #define SMN_COMMAND_ZEROS_MASK 0xfffffff0 875 | #define SMN_COMMAND_CLEAR_INTERRUPT 0x8 /**< Clear SMN Interrupt */ 876 | #define SMN_COMMAND_CLEAR_BIT_BANK 0x4 /**< Clear SMN Bit Bank */ 877 | #define SMN_COMMAND_ENABLE_INTERRUPT 0x2 /**< Enable SMN Interrupts */ 878 | #define SMN_COMMAND_SET_SOFTWARE_ALARM 0x1 /**< Set Software Alarm */ 879 | /** @} */ 880 | 881 | /** 882 | * @defgroup smntimercontroldefs SMN Timer Control Register definitions (SMN_TIMER_CONTROL) 883 | */ 884 | /** @addtogroup smntimercontroldefs */ 885 | /** @{ */ 886 | /** These bits are reserved or zero */ 887 | #define SMN_TIMER_CTRL_ZEROS_MASK 0xfffffffc 888 | /** Load the timer from #SMN_TIMER_IV_REG */ 889 | #define SMN_TIMER_LOAD_TIMER 0x2 890 | /** Setting to zero stops the Timer */ 891 | #define SMN_TIMER_STOP_MASK 0x1 892 | /** Setting this value starts the timer */ 893 | #define SMN_TIMER_START_TIMER 0x1 894 | /** @} */ 895 | 896 | /** 897 | * @defgroup scmchainmodedefs SCM_CHAINING_MODE_MASK - Bit definitions 898 | */ 899 | /** @addtogroup scmchainmodedefs */ 900 | /** @{ */ 901 | #define SCM_CBC_MODE 0x2 /**< Cipher block chaining */ 902 | #define SCM_ECB_MODE 0x0 /**< Electronic codebook. */ 903 | /** @} */ 904 | 905 | /* Bit definitions in the SCM_CIPHER_MODE_MASK */ 906 | /** 907 | * @defgroup scmciphermodedefs SCM_CIPHER_MODE_MASK - Bit definitions 908 | */ 909 | /** @addtogroup scmciphermodedefs */ 910 | /** @{ */ 911 | #define SCM_DECRYPT_MODE 0x1 /**< decrypt from black to red memory */ 912 | #define SCM_ENCRYPT_MODE 0x0 /**< encrypt from red to black memory */ 913 | /** @} */ 914 | 915 | /** 916 | * @defgroup smndbgdetdefs SMN Debug Detector Status Register (SCM_DEBUG_DETECT_STAT) 917 | */ 918 | /** @addtogroup smndbgdetdefs */ 919 | /** @{ */ 920 | #define SMN_DBG_ZEROS_MASK 0xfffff000 /**< These bits are zero or reserved */ 921 | #define SMN_DBG_D12 0x0800 /**< Error detected on Debug Port D12 */ 922 | #define SMN_DBG_D11 0x0400 /**< Error detected on Debug Port D11 */ 923 | #define SMN_DBG_D10 0x0200 /**< Error detected on Debug Port D10 */ 924 | #define SMN_DBG_D9 0x0100 /**< Error detected on Debug Port D9 */ 925 | #define SMN_DBG_D8 0x0080 /**< Error detected on Debug Port D8 */ 926 | #define SMN_DBG_D7 0x0040 /**< Error detected on Debug Port D7 */ 927 | #define SMN_DBG_D6 0x0020 /**< Error detected on Debug Port D6 */ 928 | #define SMN_DBG_D5 0x0010 /**< Error detected on Debug Port D5 */ 929 | #define SMN_DBG_D4 0x0008 /**< Error detected on Debug Port D4 */ 930 | #define SMN_DBG_D3 0x0004 /**< Error detected on Debug Port D3 */ 931 | #define SMN_DBG_D2 0x0002 /**< Error detected on Debug Port D2 */ 932 | #define SMN_DBG_D1 0x0001 /**< Error detected on Debug Port D1 */ 933 | /** @} */ 934 | 935 | /** Mask for the usable bits of the Sequence Start Register 936 | (#SMN_SEQ_START_REG) */ 937 | #define SMN_SEQUENCE_START_MASK 0x0000ffff 938 | 939 | /** Mask for the usable bits of the Sequence End Register 940 | (#SMN_SEQ_END_REG) */ 941 | #define SMN_SEQUENCE_END_MASK 0x0000ffff 942 | 943 | /** Mask for the usable bits of the Sequence Check Register 944 | (#SMN_SEQ_CHECK_REG) */ 945 | #define SMN_SEQUENCE_CHECK_MASK 0x0000ffff 946 | 947 | /** Mask for the usable bits of the Bit Counter Register 948 | (#SMN_BB_CNT_REG) */ 949 | #define SMN_BIT_COUNT_MASK 0x000007ff 950 | 951 | /** Mask for the usable bits of the Bit Bank Increment Size Register 952 | (#SMN_BB_INC_REG) */ 953 | #define SMN_BITBANK_INC_SIZE_MASK 0x000007ff 954 | 955 | /** Mask for the usable bits of the Bit Bank Decrement Register 956 | (#SMN_BB_DEC_REG) */ 957 | #define SMN_BITBANK_DECREMENT_MASK 0x000007ff 958 | 959 | /** Mask for the usable bits of the Compare Size Register 960 | (#SMN_COMPARE_REG) */ 961 | #define SMN_COMPARE_SIZE_MASK 0x0000003f 962 | 963 | /*! @} */ 964 | 965 | #endif /* SCC_DRIVER_H */ 966 | -------------------------------------------------------------------------------- /portable_os.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved. 3 | */ 4 | 5 | /* 6 | * The code contained herein is licensed under the GNU General Public 7 | * License. You may obtain a copy of the GNU General Public License 8 | * Version 2 or later at the following locations: 9 | * 10 | * http://www.opensource.org/licenses/gpl-license.html 11 | * http://www.gnu.org/copyleft/gpl.html 12 | */ 13 | 14 | #ifndef PORTABLE_OS_H 15 | #define PORTABLE_OS_H 16 | 17 | /***************************************************************************/ 18 | 19 | /* 20 | * Add support for your target OS by checking appropriate flags and then 21 | * including the appropriate file. Don't forget to document the conditions 22 | * in the later documentation section at the beginning of the 23 | * DOXYGEN_PORTABLE_OS_DOC. 24 | */ 25 | 26 | #include "linux_port.h" 27 | 28 | /***************************************************************************/ 29 | 30 | /*! 31 | * @file portable_os.h 32 | * 33 | * This file should be included by portable driver code in order to gain access 34 | * to the OS-specific header files. It is the only OS-related header file that 35 | * the writer of a portable driver should need. 36 | * 37 | * This file also contains the documentation for the common API. 38 | * 39 | * Begin reading the documentation for this file at the @ref index "main page". 40 | * 41 | */ 42 | 43 | /*! 44 | * @if USE_MAINPAGE 45 | * @mainpage Generic OS API for STC Drivers 46 | * @endif 47 | * 48 | * @section intro_sec Introduction 49 | * 50 | * This defines the API / kernel programming environment for portable drivers. 51 | * 52 | * This API is broken up into several functional areas. It greatly limits the 53 | * choices of a device-driver author, but at the same time should allow for 54 | * greater portability of the resulting code. 55 | * 56 | * Each kernel-to-driver function (initialization function, interrupt service 57 | * routine, etc.) has a 'portable signature' which must be used, and a specific 58 | * function which must be called to generate the return statement. There is 59 | * one exception, a background task or "bottom half" routine, which instead has 60 | * a specific structure which must be followed. These signatures and function 61 | * definitions are found in @ref drsigs. 62 | * 63 | * None of these kernel-to-driver functions seem to get any arguments passed to 64 | * them. Instead, there are @ref drsigargs which allow one of these functions 65 | * to get at fairly generic parts of its calling arguments, if there are any. 66 | * 67 | * Almost every driver will have some need to call the operating system 68 | * @ref dkops is the list of services which are available to the driver. 69 | * 70 | * 71 | * @subsection warn_sec Warning 72 | * 73 | * The specifics of the types, values of the various enumerations 74 | * (unless specifically stated, like = 0), etc., are only here for illustrative 75 | * purposes. No attempts should be made to make use of any specific knowledge 76 | * gleaned from this documentation. These types are only meant to be passed in 77 | * and out of the API, and their contents are to be handled only by the 78 | * provided OS-specific functions. 79 | * 80 | * Also, note that the function may be provided as macros in some 81 | * implementations, or vice versa. 82 | * 83 | * 84 | * @section dev_sec Writing a Portable Driver 85 | * 86 | * First off, writing a portable driver means calling no function in an OS 87 | * except what is available through this header file. 88 | * 89 | * Secondly, all OS-called functions in your driver must be invoked and 90 | * referenced through the signature routines. 91 | * 92 | * Thirdly, there might be some rules which you can get away with ignoring or 93 | * violating on one OS, yet will cause your code not to be portable to a 94 | * different OS. 95 | * 96 | * 97 | * @section limit_sec Limitations 98 | * 99 | * This API is not expected to handle every type of driver which may be found 100 | * in an operating system. For example, it will not be able to handle the 101 | * usual design for something like a UART driver, where there are multiple 102 | * logical devices to access, because the design usually calls for some sort of 103 | * indication to the #OS_DEV_TASK() function or OS_DEV_ISR() to indicate which 104 | * channel is to be serviced by that instance of the task/function. This sort 105 | * of argument is missing in this API for functions like os_dev_schedule_task() and 106 | * os_register_interrupt(). 107 | * 108 | * 109 | * @section port_guide Porting Guidelines 110 | * 111 | * This section is intended for a developer who needs to port the header file 112 | * to an operating system which is not yet supported. 113 | * 114 | * This interface allows for a lot of flexibility when it comes to porting to 115 | * an operating systems device driver interface. There are three main areas to 116 | * examine: The use of Driver Routine Signatures, the use of Driver Argument 117 | * Access functions, the Calls to Kernel Functions, and Data Types. 118 | * 119 | * 120 | * @subsection port_sig Porting Driver Routine Signatures 121 | * 122 | * The three macros for each function (e.g. #OS_DEV_INIT(), #OS_DEV_INIT_DCL(), 123 | * and #OS_DEV_INIT_REF()) allow the flexibility of having a 'wrapper' function 124 | * with the OS-required signature, which would then call the user's function 125 | * with some different signature. 126 | * 127 | * The first form would lay down the wrapper function, followed by the 128 | * signature for the user function. The second form would lay down just the 129 | * signatures for both functions, and the last function would reference the 130 | * wrapper function, since that is the interface function called by the OS. 131 | * 132 | * Note that the driver author has no visibility at all to the signature of the 133 | * routines. The author can access arguments only through a limited set of 134 | * functions, and must return via another function. 135 | * 136 | * The Return Functions allow a lot of flexibility in converting the return 137 | * value, or not returning a value at all. These will likely be implemented as 138 | * macros. 139 | * 140 | * 141 | * @subsection port_arg Porting Driver Argument Access Functions 142 | * 143 | * The signatures defined by the guide will usually be replaced with macro 144 | * definitions. 145 | * 146 | * 147 | * @subsection port_dki Porting Calls to Kernel Functions 148 | * 149 | * The signatures defined by the guide may be replaced with macro definitions, 150 | * if that makes more sense. 151 | * 152 | * Implementors are free to ignore arguments which are not applicable to their 153 | * OS. 154 | * 155 | * @subsection port_datatypes Porting Data Types 156 | * 157 | * 158 | */ 159 | 160 | /*************************************************************************** 161 | * Compile flags 162 | **************************************************************************/ 163 | 164 | /* 165 | * This compile flag should only be turned on when running doxygen to generate 166 | * the API documentation. 167 | */ 168 | #ifdef DOXYGEN_PORTABLE_OS_DOC 169 | 170 | /*! 171 | * @todo module_init()/module_cleanup() for Linux need to be added to OS 172 | * abstractions. Also need EXPORT_SYMBOL() equivalent?? 173 | * 174 | */ 175 | 176 | /* Drop OS differentation documentation here */ 177 | 178 | /*! 179 | * \#define this flag to build your driver as a Linux driver 180 | */ 181 | #define LINUX 182 | 183 | /* end OS differentation documentation */ 184 | 185 | /*! 186 | * Symbol to give version number of the implementation file. Earliest 187 | * definition is in version 1.1, with value 101 (to mean version 1.1) 188 | */ 189 | #define PORTABLE_OS_VERSION 101 190 | 191 | /* 192 | * NOTICE: The following definitions (the rest of the file) are not meant ever 193 | * to be compiled. Instead, they are the documentation for the portable OS 194 | * API, to be used by driver writers. 195 | * 196 | * Each individual OS port will define each of these types, functions, or 197 | * macros as appropriate to the target OS. This is why they are under the 198 | * DOXYGEN_PORTABLE_OS_DOC flag. 199 | */ 200 | 201 | /*************************************************************************** 202 | * Type definitions 203 | **************************************************************************/ 204 | 205 | /*! 206 | * Type used for registering and deregistering interrupts. 207 | * 208 | * This is typically an interrupt channel number. 209 | */ 210 | typedef int os_interrupt_id_t; 211 | 212 | /*! 213 | * Type used as handle for a process 214 | * 215 | * See #os_get_process_handle() and #os_send_signal(). 216 | */ 217 | typedef int os_process_handle_t; 218 | 219 | /*! 220 | * Generic return code for functions which need such a thing. 221 | * 222 | * No knowledge should be assumed of the value of any of these symbols except 223 | * that @c OS_ERROR_OK_S is guaranteed to be zero. 224 | * 225 | * @todo Any other named values? What about (-EAGAIN? -ERESTARTSYS? Are they 226 | * too Linux/Unix-specific read()/write() return values) ? 227 | */ 228 | typedef enum { 229 | OS_ERROR_OK_S = 0, /*!< Success */ 230 | OS_ERROR_FAIL_S, /*!< Generic driver failure */ 231 | OS_ERROR_NO_MEMORY_S, /*!< Failure to acquire/use memory */ 232 | OS_ERROR_BAD_ADDRESS_S, /*!< Bad address */ 233 | OS_ERROR_BAD_ARG_S /*!< Bad input argument */ 234 | } os_error_code; 235 | 236 | /*! 237 | * Handle to a lock. 238 | */ 239 | typedef int *os_lock_t; 240 | 241 | /*! 242 | * Context while locking. 243 | */ 244 | typedef int os_lock_context_t; 245 | 246 | /*! 247 | * An object which can be slept on and later used to wake any/all sleepers. 248 | */ 249 | typedef int os_sleep_object_t; 250 | 251 | /*! 252 | * Driver registration handle 253 | */ 254 | typedef void *os_driver_reg_t; 255 | 256 | /*! 257 | * Function signature for an #OS_DEV_INIT() function. 258 | * 259 | * @return A call to os_dev_init_return() function. 260 | */ 261 | typedef void (*os_init_function_t) (void); 262 | 263 | /*! 264 | * Function signature for an #OS_DEV_SHUTDOWN() function. 265 | * 266 | * @return A call to os_dev_shutdown_return() function. 267 | */ 268 | typedef void (*os_shutdown_function_t) (void); 269 | 270 | /*! 271 | * Function signature for a user-driver function. 272 | * 273 | * @return A call to the appropriate os_dev_xxx_return() function. 274 | */ 275 | typedef void (*os_user_function_t) (void); 276 | 277 | /*! 278 | * Function signature for the portable interrupt handler 279 | * 280 | * While it would be nice to know which interrupt is being serviced, the 281 | * Least Common Denominator rule says that no arguments get passed in. 282 | * 283 | * @return A call to #os_dev_isr_return() 284 | */ 285 | typedef void (*os_interrupt_handler_t) (void); 286 | 287 | /*! 288 | * Function signature for a task function 289 | * 290 | * Many task function definitions get some sort of generic argument so that the 291 | * same function can run across many (queues, channels, ...) as separate task 292 | * instances. This has been left out of this API. 293 | * 294 | * This function must be structured as documented by #OS_DEV_TASK(). 295 | * 296 | */ 297 | typedef void (*os_task_fn_t) (void); 298 | 299 | /*! 300 | * Function types which can be associated with driver entry points. These are 301 | * used in os_driver_add_registration(). 302 | * 303 | * Note that init and shutdown are absent. 304 | */ 305 | typedef enum { 306 | OS_FN_OPEN, /*!< open() operation handler. */ 307 | OS_FN_CLOSE, /*!< close() operation handler. */ 308 | OS_FN_READ, /*!< read() operation handler. */ 309 | OS_FN_WRITE, /*!< write() operation handler. */ 310 | OS_FN_IOCTL, /*!< ioctl() operation handler. */ 311 | OS_FN_MMAP /*!< mmap() operation handler. */ 312 | } os_driver_fn_t; 313 | 314 | /*************************************************************************** 315 | * Driver-to-Kernel Operations 316 | **************************************************************************/ 317 | 318 | /*! 319 | * @defgroup dkops Driver-to-Kernel Operations 320 | * 321 | * These are the operations which drivers should call to get the OS to perform 322 | * services. 323 | */ 324 | 325 | /*! @addtogroup dkops */ 326 | /*! @{ */ 327 | 328 | /*! 329 | * Register an interrupt handler. 330 | * 331 | * @param driver_name The name of the driver 332 | * @param interrupt_id The interrupt line to monitor (type 333 | * #os_interrupt_id_t) 334 | * @param function The function to be called to handle an interrupt 335 | * 336 | * @return #os_error_code 337 | */ 338 | os_error_code os_register_interrupt(char *driver_name, 339 | os_interrupt_id_t interrupt_id, 340 | os_interrupt_handler_t function); 341 | 342 | /*! 343 | * Deregister an interrupt handler. 344 | * 345 | * @param interrupt_id The interrupt line to stop monitoring 346 | * 347 | * @return #os_error_code 348 | */ 349 | os_error_code os_deregister_interrupt(os_interrupt_id_t interrupt_id); 350 | 351 | /*! 352 | * Initialize driver registration. 353 | * 354 | * If the driver handles open(), close(), ioctl(), read(), write(), or mmap() 355 | * calls, then it needs to register their location with the kernel so that they 356 | * get associated with the device. 357 | * 358 | * @param handle The handle object to be used with this registration. The 359 | * object must live (be in memory somewhere) at least until 360 | * os_driver_remove_registration() is called. 361 | * 362 | * @return An os error code. 363 | */ 364 | os_error_code os_driver_init_registration(os_driver_reg_t handle); 365 | 366 | /*! 367 | * Add a function registration to driver registration. 368 | * 369 | * @param handle The handle used with #os_driver_init_registration(). 370 | * @param name Which function is being supported. 371 | * @param function The result of a call to a @c _REF version of one of the 372 | * driver function signature macros 373 | * driver function signature macros 374 | * @return void 375 | */ 376 | void os_driver_add_registration(os_driver_reg_t handle, os_driver_fn_t name, 377 | void *function); 378 | 379 | /*! 380 | * Finalize the driver registration with the kernel. 381 | * 382 | * Upon return from this call, the driver may begin receiving calls at the 383 | * defined entry points. 384 | * 385 | * @param handle The handle used with #os_driver_init_registration(). 386 | * @param major The major device number to be associated with the driver. 387 | * If this value is zero, a major number may be assigned. 388 | * See #os_driver_get_major() to determine final value. 389 | * #os_driver_remove_registration(). 390 | * @param driver_name The driver name. Can be used as part of 'device node' 391 | * name on platforms which support such a feature. 392 | * 393 | * @return An error code 394 | */ 395 | os_error_code os_driver_complete_registration(os_driver_reg_t handle, 396 | int major, char *driver_name); 397 | 398 | /*! 399 | * Get driver Major Number from handle after a successful registration. 400 | * 401 | * @param handle A handle which has completed registration. 402 | * 403 | * @return The major number (if any) associated with the handle. 404 | */ 405 | uint32_t os_driver_get_major(os_driver_reg_t handle); 406 | 407 | /*! 408 | * Remove the driver's registration with the kernel. 409 | * 410 | * Upon return from this call, the driver not receive any more calls at the 411 | * defined entry points (other than ISR and shutdown). 412 | * 413 | * @param major The major device number to be associated with the driver. 414 | * @param driver_name The driver name 415 | * 416 | * @return An error code. 417 | */ 418 | os_error_code os_driver_remove_registration(int major, char *driver_name); 419 | 420 | /*! 421 | * Print a message to console / into log file. After the @c msg argument a 422 | * number of printf-style arguments may be added. Types should be limited to 423 | * printf string, char, octal, decimal, and hexadecimal types. (This excludes 424 | * pointers, and floating point). 425 | * 426 | * @param msg The message to print to console / system log 427 | * 428 | * @return (void) 429 | */ 430 | void os_printk(char *msg, ...); 431 | 432 | /*! 433 | * Allocate some kernel memory 434 | * 435 | * @param amount Number of 8-bit bytes to allocate 436 | * @param flags Some indication of purpose of memory (needs definition) 437 | * 438 | * @return Pointer to allocated memory, or NULL if failed. 439 | */ 440 | void *os_alloc_memory(unsigned amount, int flags); 441 | 442 | /*! 443 | * Free some kernel memory 444 | * 445 | * @param location The beginning of the region to be freed. 446 | * 447 | * Do some OSes have separate free() functions which should be 448 | * distinguished by passing in @c flags here, too? Don't some also require the 449 | * size of the buffer being freed? Perhaps separate routines for each 450 | * alloc/free pair (DMAable, etc.)? 451 | */ 452 | void os_free_memory(void *location); 453 | 454 | /*! 455 | * Allocate cache-coherent memory 456 | * 457 | * @param amount Number of bytes to allocate 458 | * @param[out] dma_addrp Location to store physical address of allocated 459 | * memory. 460 | * @param flags Some indication of purpose of memory (needs 461 | * definition). 462 | * 463 | * @return (virtual space) pointer to allocated memory, or NULL if failed. 464 | * 465 | */ 466 | void *os_alloc_coherent(unsigned amount, uint32_t * dma_addrp, int flags); 467 | 468 | /*! 469 | * Free cache-coherent memory 470 | * 471 | * @param size Number of bytes which were allocated. 472 | * @param[out] virt_addr Virtual(kernel) address of memory.to be freed, as 473 | * returned by #os_alloc_coherent(). 474 | * @param[out] dma_addr Physical address of memory.to be freed, as returned 475 | * by #os_alloc_coherent(). 476 | * 477 | * @return void 478 | * 479 | */ 480 | void os_free_coherent(unsigned size, void *virt_addr, uint32_t dma_addr); 481 | 482 | /*! 483 | * Map an I/O space into kernel memory space 484 | * 485 | * @param start The starting address of the (physical / io space) region 486 | * @param range_bytes The number of bytes to map 487 | * 488 | * @return A pointer to the mapped area, or NULL on failure 489 | */ 490 | void *os_map_device(uint32_t start, unsigned range_bytes); 491 | 492 | /*! 493 | * Unmap an I/O space from kernel memory space 494 | * 495 | * @param start The starting address of the (virtual) region 496 | * @param range_bytes The number of bytes to unmap 497 | * 498 | * @return None 499 | */ 500 | void os_unmap_device(void *start, unsigned range_bytes); 501 | 502 | /*! 503 | * Copy data from Kernel space to User space 504 | * 505 | * @param to The target location in user memory 506 | * @param from The source location in kernel memory 507 | * @param size The number of bytes to be copied 508 | * 509 | * @return #os_error_code 510 | */ 511 | os_error_code os_copy_to_user(void *to, void *from, unsigned size); 512 | 513 | /*! 514 | * Copy data from User space to Kernel space 515 | * 516 | * @param to The target location in kernel memory 517 | * @param from The source location in user memory 518 | * @param size The number of bytes to be copied 519 | * 520 | * @return #os_error_code 521 | */ 522 | os_error_code os_copy_from_user(void *to, void *from, unsigned size); 523 | 524 | /*! 525 | * Read an 8-bit device register 526 | * 527 | * @param register_address The (bus) address of the register to write to 528 | * @return The value in the register 529 | */ 530 | uint8_t os_read8(uint8_t * register_address); 531 | 532 | /*! 533 | * Write an 8-bit device register 534 | * 535 | * @param register_address The (bus) address of the register to write to 536 | * @param value The value to write into the register 537 | */ 538 | void os_write8(uint8_t * register_address, uint8_t value); 539 | 540 | /*! 541 | * Read a 16-bit device register 542 | * 543 | * @param register_address The (bus) address of the register to write to 544 | * @return The value in the register 545 | */ 546 | uint16_t os_read16(uint16_t * register_address); 547 | 548 | /*! 549 | * Write a 16-bit device register 550 | * 551 | * @param register_address The (bus) address of the register to write to 552 | * @param value The value to write into the register 553 | */ 554 | void os_write16(uint16_t * register_address, uint16_t value); 555 | 556 | /*! 557 | * Read a 32-bit device register 558 | * 559 | * @param register_address The (bus) address of the register to write to 560 | * @return The value in the register 561 | */ 562 | uint32_t os_read32(uint32_t * register_address); 563 | 564 | /*! 565 | * Write a 32-bit device register 566 | * 567 | * @param register_address The (bus) address of the register to write to 568 | * @param value The value to write into the register 569 | */ 570 | void os_write32(uint32_t * register_address, uint32_t value); 571 | 572 | /*! 573 | * Read a 64-bit device register 574 | * 575 | * @param register_address The (bus) address of the register to write to 576 | * @return The value in the register 577 | */ 578 | uint64_t os_read64(uint64_t * register_address); 579 | 580 | /*! 581 | * Write a 64-bit device register 582 | * 583 | * @param register_address The (bus) address of the register to write to 584 | * @param value The value to write into the register 585 | */ 586 | void os_write64(uint64_t * register_address, uint64_t value); 587 | 588 | /*! 589 | * Prepare a task to execute the given function. This should only be done once 590 | * per task, during the driver's initialization routine. 591 | * 592 | * @param task_fn Name of the OS_DEV_TASK() function to be created. 593 | * 594 | * @return an OS ERROR code. 595 | */ 596 | os_error os_create_task(os_task_fn_t * task_fn); 597 | 598 | /*! 599 | * Run the task associated with an #OS_DEV_TASK() function 600 | * 601 | * The task will begin execution sometime after or during this call. 602 | * 603 | * @param task_fn Name of the OS_DEV_TASK() function to be scheduled. 604 | * 605 | * @return void 606 | */ 607 | void os_dev_schedule_task(os_task_fn_t * task_fn); 608 | 609 | /*! 610 | * Make sure that task is no longer running and will no longer run. 611 | * 612 | * This function will not return until both are true. This is useful when 613 | * shutting down a driver. 614 | * 615 | * @param task_fn Name of the OS_DEV_TASK() funciton to be stopped. 616 | * 617 | */ 618 | void os_stop_task(os_task_fn_t * task_fn); 619 | 620 | /*! 621 | * Delay some number of microseconds 622 | * 623 | * Note that this is a busy-loop, not a suspension of the task/process. 624 | * 625 | * @param msecs The number of microseconds to delay 626 | * 627 | * @return void 628 | */ 629 | void os_mdelay(unsigned long msecs); 630 | 631 | /*! 632 | * Calculate virtual address from physical address 633 | * 634 | * @param pa Physical address 635 | * 636 | * @return virtual address 637 | * 638 | * @note this assumes that addresses are 32 bits wide 639 | */ 640 | void *os_va(uint32_t pa); 641 | 642 | /*! 643 | * Calculate physical address from virtual address 644 | * 645 | * 646 | * @param va Virtual address 647 | * 648 | * @return physical address 649 | * 650 | * @note this assumes that addresses are 32 bits wide 651 | */ 652 | uint32_t os_pa(void *va); 653 | 654 | /*! 655 | * Allocate and initialize a lock, returning a lock handle. 656 | * 657 | * The lock state will be initialized to 'unlocked'. 658 | * 659 | * @return A lock handle, or NULL if an error occurred. 660 | */ 661 | os_lock_t os_lock_alloc_init(void); 662 | 663 | /*! 664 | * Acquire a lock. 665 | * 666 | * This function should only be called from an interrupt service routine. 667 | * 668 | * @param lock_handle A handle to the lock to acquire. 669 | * 670 | * @return void 671 | */ 672 | void os_lock(os_lock_t lock_handle); 673 | 674 | /*! 675 | * Unlock a lock. Lock must have been acquired by #os_lock(). 676 | * 677 | * @param lock_handle A handle to the lock to unlock. 678 | * 679 | * @return void 680 | */ 681 | void os_unlock(os_lock_t lock_handle); 682 | 683 | /*! 684 | * Acquire a lock in non-ISR context 685 | * 686 | * This function will spin until the lock is available. 687 | * 688 | * @param lock_handle A handle of the lock to acquire. 689 | * @param context Place to save the before-lock context 690 | * 691 | * @return void 692 | */ 693 | void os_lock_save_context(os_lock_t lock_handle, os_lock_context_t context); 694 | 695 | /*! 696 | * Release a lock in non-ISR context 697 | * 698 | * @param lock_handle A handle of the lock to release. 699 | * @param context Place where before-lock context was saved. 700 | * 701 | * @return void 702 | */ 703 | void os_unlock_restore_context(os_lock_t lock_handle, 704 | os_lock_context_t context); 705 | 706 | /*! 707 | * Deallocate a lock handle. 708 | * 709 | * @param lock_handle An #os_lock_t that has been allocated. 710 | * 711 | * @return void 712 | */ 713 | void os_lock_deallocate(os_lock_t lock_handle); 714 | 715 | /*! 716 | * Determine process handle 717 | * 718 | * The process handle of the current user is returned. 719 | * 720 | * @return A handle on the current process. 721 | */ 722 | os_process_handle_t os_get_process_handle(); 723 | 724 | /*! 725 | * Send a signal to a process 726 | * 727 | * @param proc A handle to the target process. 728 | * @param sig The POSIX signal to send to that process. 729 | */ 730 | void os_send_signal(os_process_handle_t proc, int sig); 731 | 732 | /*! 733 | * Get some random bytes 734 | * 735 | * @param buf The location to store the random data. 736 | * @param count The number of bytes to store. 737 | * 738 | * @return void 739 | */ 740 | void os_get_random_bytes(void *buf, unsigned count); 741 | 742 | /*! 743 | * Go to sleep on an object. 744 | * 745 | * Example: code = os_sleep(my_queue, available_count == 0, 0); 746 | * 747 | * @param object The object on which to sleep 748 | * @param condition An expression to check for sleep completion. Must be 749 | * coded so that it can be referenced more than once inside 750 | * macro, i.e., no ++ or other modifying expressions. 751 | * @param atomic Non-zero if sleep must not return until condition. 752 | * 753 | * @return error code -- OK or sleep interrupted?? 754 | */ 755 | os_error_code os_sleep(os_sleep_object_t object, unsigned condition, 756 | unsigned atomic); 757 | 758 | /*! 759 | * Wake up whatever is sleeping on sleep object 760 | * 761 | * @param object The object on which things might be sleeping 762 | * 763 | * @return none 764 | */ 765 | void os_wake_sleepers(os_sleep_object_t object); 766 | 767 | /*! @} *//* dkops */ 768 | 769 | /***************************************************************************** 770 | * Function-signature-generating macros 771 | *****************************************************************************/ 772 | 773 | /*! 774 | * @defgroup drsigs Driver Function Signatures 775 | * 776 | * These macros will define the entry point signatures for interrupt handlers; 777 | * driver initialization and shutdown; device open/close; etc. They are to be 778 | * used whenever the Kernel will call into the Driver. They are not 779 | * appropriate for driver calls to other routines in the driver. 780 | * 781 | * There are three versions of each macro for a given Driver Entry Point. The 782 | * first version is used to define a function and its implementation in the 783 | * driver.c file, e.g. #OS_DEV_INIT(). 784 | * 785 | * The second form is used whenever a forward declaration (prototype) is 786 | * needed. It has the letters @c _DCL appended to the name of the definition 787 | * function. These are not otherwise mentioned in this documenation. 788 | * 789 | * There is a third form used when a reference to a function is required, for 790 | * instance when passing the routine as a pointer to a function. It has the 791 | * letters @c _REF appended to the name of the definition function 792 | * (e.g. DEV_IOCTL_REF). 793 | * 794 | * Note that these two extra forms are required because of the possibility of 795 | * having an invisible 'wrapper function' created by the os-specific header 796 | * file which would need to be invoked by the operating system, and which in 797 | * turn would invoke the generic function. 798 | * 799 | * Example: 800 | * 801 | * (in a header file) 802 | * @code 803 | * OS_DEV_INIT_DCL(widget_init); 804 | * OS_DEV_ISR_DCL(widget_isr); 805 | * @endcode 806 | * 807 | * (in an implementation file) 808 | * @code 809 | * OS_DEV_INIT(widget, widget_init) 810 | * { 811 | * 812 | * os_register_interrupt("widget", WIDGET_IRQ, OS_DEV_ISR_REF(widget_isr)); 813 | * 814 | * os_dev_init_return(OS_RETURN_NO_ERROR_S); 815 | * } 816 | * 817 | * OS_DEV_ISR(widget_isr) 818 | * { 819 | * os_dev_isr_return(TRUE); 820 | * } 821 | * @endcode 822 | */ 823 | 824 | /*! @addtogroup drsigs */ 825 | /*! @{ */ 826 | 827 | /*! 828 | * Define a function which will handle device initialization 829 | * 830 | * This is tne driver initialization routine. This is normally where the 831 | * part would be initialized; queues, locks, interrupts handlers defined; 832 | * long-term dynamic memory allocated for driver use; etc. 833 | * 834 | * @param function_name The name of the portable initialization function. 835 | * 836 | * @return A call to #os_dev_init_return() 837 | * 838 | */ 839 | #define OS_DEV_INIT(function_name) 840 | 841 | /*! 842 | * Define a function which will handle device shutdown 843 | * 844 | * This is the reverse of the #OS_DEV_INIT() routine. 845 | * 846 | * @param function_name The name of the portable driver shutdown routine. 847 | * 848 | * @return A call to #os_dev_shutdown_return() 849 | */ 850 | #define OS_DEV_SHUTDOWN(function_name) 851 | 852 | /*! 853 | * Define a function which will open the device for a user. 854 | * 855 | * @param function_name The name of the driver open() function 856 | * 857 | * @return A call to #os_dev_open_return() 858 | */ 859 | #define OS_DEV_OPEN(function_name) 860 | 861 | /*! 862 | * Define a function which will handle a user's ioctl() request 863 | * 864 | * @param function_name The name of the driver ioctl() function 865 | * 866 | * @return A call to #os_dev_ioctl_return() 867 | */ 868 | #define OS_DEV_IOCTL(function_name) 869 | 870 | /*! 871 | * Define a function which will handle a user's read() request 872 | * 873 | * @param function_name The name of the driver read() function 874 | * 875 | * @return A call to #os_dev_read_return() 876 | */ 877 | #define OS_DEV_READ(function_name) 878 | 879 | /*! 880 | * Define a function which will handle a user's write() request 881 | * 882 | * @param function_name The name of the driver write() function 883 | * 884 | * @return A call to #os_dev_write_return() 885 | */ 886 | #define OS_DEV_WRITE(function_name) 887 | 888 | /*! 889 | * Define a function which will handle a user's mmap() request 890 | * 891 | * The mmap() function requests the driver to map some memory into user space. 892 | * 893 | * @todo Determine what support functions are needed for mmap() handling. 894 | * 895 | * @param function_name The name of the driver mmap() function 896 | * 897 | * @return A call to #os_dev_mmap_return() 898 | */ 899 | #define OS_DEV_MMAP(function_name) 900 | 901 | /*! 902 | * Define a function which will close the device - opposite of OS_DEV_OPEN() 903 | * 904 | * @param function_name The name of the driver close() function 905 | * 906 | * @return A call to #os_dev_close_return() 907 | */ 908 | #define OS_DEV_CLOSE(function_name) 909 | 910 | /*! 911 | * Define a function which will handle an interrupt 912 | * 913 | * No arguments are available to the generic function. It must not invoke any 914 | * OS functions which are illegal in a ISR. It gets no parameters, and must 915 | * have a call to #os_dev_isr_return() instead of any/all return statements. 916 | * 917 | * Example: 918 | * @code 919 | * OS_DEV_ISR(widget, widget_isr, WIDGET_IRQ_NUMBER) 920 | * { 921 | * os_dev_isr_return(1); 922 | * } 923 | * @endcode 924 | * 925 | * @param function_name The name of the driver ISR function 926 | * 927 | * @return A call to #os_dev_isr_return() 928 | */ 929 | #define OS_DEV_ISR(function_name) 930 | 931 | /*! 932 | * Define a function which will operate as a background task / bottom half. 933 | * 934 | * The function implementation must be structured in the following manner: 935 | * @code 936 | * OS_DEV_TASK(widget_task) 937 | * { 938 | * OS_DEV_TASK_SETUP(widget_task); 939 | * 940 | * while OS_DEV_TASK_CONDITION(widget_task) } 941 | * 942 | * }; 943 | * } 944 | * @endcode 945 | * 946 | * @todo In some systems the OS_DEV_TASK_CONDITION() will be an action which 947 | * will cause the task to sleep on some event triggered by os_run_task(). In 948 | * others, the macro will reference a variable laid down by 949 | * OS_DEV_TASK_SETUP() to make sure that the loop is only performed once. 950 | * 951 | * @param function_name The name of this background task function 952 | */ 953 | #define OS_DEV_TASK(function_name) 954 | 955 | /*! @} *//* drsigs */ 956 | 957 | /*! @defgroup dclsigs Routines to declare Driver Signature routines 958 | * 959 | * These macros drop prototypes suitable for forward-declaration of 960 | * @ref drsigs "function signatures". 961 | */ 962 | 963 | /*! @addtogroup dclsigs */ 964 | /*! @{ */ 965 | 966 | /*! 967 | * Declare prototype for the device initialization function 968 | * 969 | * @param function_name The name of the portable initialization function. 970 | */ 971 | #define OS_DEV_INIT_DCL(function_name) 972 | 973 | /*! 974 | * Declare prototype for the device shutdown function 975 | * 976 | * @param function_name The name of the portable driver shutdown routine. 977 | * 978 | * @return A call to #os_dev_shutdown_return() 979 | */ 980 | #define OS_DEV_SHUTDOWN_DCL(function_name) 981 | 982 | /*! 983 | * Declare prototype for the open() function. 984 | * 985 | * @param function_name The name of the driver open() function 986 | * 987 | * @return A call to #os_dev_open_return() 988 | */ 989 | #define OS_DEV_OPEN_DCL(function_name) 990 | 991 | /*! 992 | * Declare prototype for the user's ioctl() request function 993 | * 994 | * @param function_name The name of the driver ioctl() function 995 | * 996 | * @return A call to #os_dev_ioctl_return() 997 | */ 998 | #define OS_DEV_IOCTL_DCL(function_name) 999 | 1000 | /*! 1001 | * Declare prototype for the function a user's read() request 1002 | * 1003 | * @param function_name The name of the driver read() function 1004 | */ 1005 | #define OS_DEV_READ_DCL(function_name) 1006 | 1007 | /*! 1008 | * Declare prototype for the user's write() request function 1009 | * 1010 | * @param function_name The name of the driver write() function 1011 | */ 1012 | #define OS_DEV_WRITE_DCL(function_name) 1013 | 1014 | /*! 1015 | * Declare prototype for the user's mmap() request function 1016 | * 1017 | * @param function_name The name of the driver mmap() function 1018 | */ 1019 | #define OS_DEV_MMAP_DCL(function_name) 1020 | 1021 | /*! 1022 | * Declare prototype for the close function 1023 | * 1024 | * @param function_name The name of the driver close() function 1025 | * 1026 | * @return A call to #os_dev_close_return() 1027 | */ 1028 | #define OS_DEV_CLOSE_DCL(function_name) 1029 | 1030 | /*! 1031 | * Declare prototype for the interrupt handling function 1032 | * 1033 | * @param function_name The name of the driver ISR function 1034 | */ 1035 | #define OS_DEV_ISR_DCL(function_name) 1036 | 1037 | /*! 1038 | * Declare prototype for a background task / bottom half function 1039 | * 1040 | * @param function_name The name of this background task function 1041 | */ 1042 | #define OS_DEV_TASK_DCL(function_name) 1043 | 1044 | /*! @} *//* dclsigs */ 1045 | 1046 | /***************************************************************************** 1047 | * Functions for Returning Values from Driver Signature routines 1048 | *****************************************************************************/ 1049 | 1050 | /*! 1051 | * @defgroup retfns Functions to Return Values from Driver Signature routines 1052 | */ 1053 | 1054 | /*! @addtogroup retfns */ 1055 | /*! @{ */ 1056 | 1057 | /*! 1058 | * Return from the #OS_DEV_INIT() function 1059 | * 1060 | * @param code An error code to report success or failure. 1061 | * 1062 | */ 1063 | void os_dev_init_return(os_error_code code); 1064 | 1065 | /*! 1066 | * Return from the #OS_DEV_SHUTDOWN() function 1067 | * 1068 | * @param code An error code to report success or failure. 1069 | * 1070 | */ 1071 | void os_dev_shutdown_return(os_error_code code); 1072 | 1073 | /*! 1074 | * Return from the #OS_DEV_ISR() function 1075 | * 1076 | * The function should verify that it really was supposed to be called, 1077 | * and that its device needed attention, in order to properly set the 1078 | * return code. 1079 | * 1080 | * @param code non-zero if interrupt handled, zero otherwise. 1081 | * 1082 | */ 1083 | void os_dev_isr_return(int code); 1084 | 1085 | /*! 1086 | * Return from the #OS_DEV_OPEN() function 1087 | * 1088 | * @param code An error code to report success or failure. 1089 | * 1090 | */ 1091 | void os_dev_open_return(os_error_code code); 1092 | 1093 | /*! 1094 | * Return from the #OS_DEV_IOCTL() function 1095 | * 1096 | * @param code An error code to report success or failure. 1097 | * 1098 | */ 1099 | void os_dev_ioctl_return(os_error_code code); 1100 | 1101 | /*! 1102 | * Return from the #OS_DEV_READ() function 1103 | * 1104 | * @param code Number of bytes read, or an error code to report failure. 1105 | * 1106 | */ 1107 | void os_dev_read_return(os_error_code code); 1108 | 1109 | /*! 1110 | * Return from the #OS_DEV_WRITE() function 1111 | * 1112 | * @param code Number of bytes written, or an error code to report failure. 1113 | * 1114 | */ 1115 | void os_dev_write_return(os_error_code code); 1116 | 1117 | /*! 1118 | * Return from the #OS_DEV_MMAP() function 1119 | * 1120 | * @param code Number of bytes written, or an error code to report failure. 1121 | * 1122 | */ 1123 | void os_dev_mmap_return(os_error_code code); 1124 | 1125 | /*! 1126 | * Return from the #OS_DEV_CLOSE() function 1127 | * 1128 | * @param code An error code to report success or failure. 1129 | * 1130 | */ 1131 | void os_dev_close_return(os_error_code code); 1132 | 1133 | /*! 1134 | * Start the #OS_DEV_TASK() function 1135 | * 1136 | * In some implementations, this could be turned into a label for 1137 | * the os_dev_task_return() call. 1138 | * 1139 | * For a more portable interface, should this take the sleep object as an 1140 | * argument??? 1141 | * 1142 | * @return none 1143 | */ 1144 | void os_dev_task_begin(void); 1145 | 1146 | /*! 1147 | * Return from the #OS_DEV_TASK() function 1148 | * 1149 | * In some implementations, this could be turned into a sleep followed 1150 | * by a jump back to the os_dev_task_begin() call. 1151 | * 1152 | * @param code An error code to report success or failure. 1153 | * 1154 | */ 1155 | void os_dev_task_return(os_error_code code); 1156 | 1157 | /*! @} *//* retfns */ 1158 | 1159 | /***************************************************************************** 1160 | * Functions/Macros for accessing arguments from Driver Signature routines 1161 | *****************************************************************************/ 1162 | 1163 | /*! @defgroup drsigargs Functions for Getting Arguments in Signature functions 1164 | * 1165 | */ 1166 | /* @addtogroup @drsigargs */ 1167 | /*! @{ */ 1168 | 1169 | /*! 1170 | * Check whether user is requesting read (permission) on the file/device. 1171 | * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() 1172 | * and #OS_DEV_WRITE() routines. 1173 | */ 1174 | int os_dev_is_flag_read(void); 1175 | 1176 | /*! 1177 | * Check whether user is requesting write (permission) on the file/device. 1178 | * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() 1179 | * and #OS_DEV_WRITE() routines. 1180 | */ 1181 | int os_dev_is_flag_write(void); 1182 | 1183 | /*! 1184 | * Check whether user is requesting non-blocking I/O. Usable in 1185 | * #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and 1186 | * #OS_DEV_WRITE() routines. 1187 | * 1188 | * @todo Specify required behavior when nonblock is requested and (sufficient?) 1189 | * data are not available to fulfill the request. 1190 | * 1191 | */ 1192 | int os_dev_is_flag_nonblock(void); 1193 | 1194 | /*! 1195 | * Determine which major device is being accessed. Usable in #OS_DEV_OPEN() 1196 | * and #OS_DEV_CLOSE(). 1197 | */ 1198 | int os_dev_get_major(void); 1199 | 1200 | /*! 1201 | * Determine which minor device is being accessed. Usable in #OS_DEV_OPEN() 1202 | * and #OS_DEV_CLOSE(). 1203 | */ 1204 | int os_dev_get_minor(void); 1205 | 1206 | /*! 1207 | * Determine which operation the user wants performed. Usable in 1208 | * #OS_DEV_IOCTL(). 1209 | * 1210 | * @return Value of the operation. 1211 | * 1212 | * @todo Define some generic way to define the individual operations. 1213 | */ 1214 | unsigned os_dev_get_ioctl_op(void); 1215 | 1216 | /*! 1217 | * Retrieve the associated argument for the desired operation. Usable in 1218 | * #OS_DEV_IOCTL(). 1219 | * 1220 | * @return A value which can be cast to a struct pointer or used as 1221 | * int/long. 1222 | */ 1223 | os_dev_ioctl_arg_t os_dev_get_ioctl_arg(void); 1224 | 1225 | /*! 1226 | * Determine the requested byte count. This should be the size of buffer at 1227 | * #os_dev_get_user_buffer(). Usable in OS_DEV_READ() and OS_DEV_WRITE() 1228 | * routines. 1229 | * 1230 | * @return A count of bytes 1231 | */ 1232 | unsigned os_dev_get_count(void); 1233 | 1234 | /*! 1235 | * Get the pointer to the user's data buffer. Usable in OS_DEV_READ(), 1236 | * OS_DEV_WRITE(), and OS_DEV_MMAP() routines. 1237 | * 1238 | * @return Pointer to user buffer (in user space). See #os_copy_to_user() 1239 | * and #os_copy_from_user(). 1240 | */ 1241 | void *os_dev_get_user_buffer(void); 1242 | 1243 | /*! 1244 | * Get the POSIX flags field for the associated open file. Usable in 1245 | * OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines. 1246 | * 1247 | * @return The flags associated with the file. 1248 | */ 1249 | unsigned os_dev_get_file_flags(void); 1250 | 1251 | /*! 1252 | * Set the driver's private structure associated with this file/open. 1253 | * 1254 | * Generally used during #OS_DEV_OPEN(). May also be used during 1255 | * #OS_DEV_READ(), #OS_DEV_WRITE(), #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and 1256 | * #OS_DEV_CLOSE(). See also #os_dev_get_user_private(). 1257 | * 1258 | * @param struct_p The driver data structure to associate with this user. 1259 | */ 1260 | void os_dev_set_user_private(void *struct_p); 1261 | 1262 | /*! 1263 | * Get the driver's private structure associated with this file. 1264 | * 1265 | * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(), 1266 | * #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and #OS_DEV_CLOSE(). See 1267 | * also #os_dev_set_user_private(). 1268 | * 1269 | * @return The driver data structure to associate with this user. 1270 | */ 1271 | void *os_dev_get_user_private(void); 1272 | 1273 | /*! 1274 | * Get the IRQ associated with this call to the #OS_DEV_ISR() function. 1275 | * 1276 | * @return The IRQ (integer) interrupt number. 1277 | */ 1278 | int os_dev_get_irq(void); 1279 | 1280 | /*! @} *//* drsigargs */ 1281 | 1282 | /***************************************************************************** 1283 | * Functions for Generating References to Driver Routines 1284 | *****************************************************************************/ 1285 | 1286 | /*! 1287 | * @defgroup drref Functions for Generating References to Driver Routines 1288 | * 1289 | * These functions will most likely be implemented as macros. They are a 1290 | * necessary part of the portable API to guarantee portability. The @c symbol 1291 | * type in here is the same symbol passed to the associated 1292 | * signature-generating macro. 1293 | * 1294 | * These macros must be used whenever referring to a 1295 | * @ref drsigs "driver signature function", for instance when storing or 1296 | * passing a pointer to the function. 1297 | */ 1298 | 1299 | /*! @addtogroup drref */ 1300 | /*! @{ */ 1301 | 1302 | /*! 1303 | * Generate a reference to an #OS_DEV_INIT() function 1304 | * 1305 | * @param function_name The name of the init function being referenced. 1306 | * 1307 | * @return A reference to the function 1308 | */ 1309 | os_init_function_t OS_DEV_INIT_REF(symbol function_name); 1310 | 1311 | /*! 1312 | * Generate a reference to an #OS_DEV_SHUTDOWN() function 1313 | * 1314 | * @param function_name The name of the shutdown function being referenced. 1315 | * 1316 | * @return A reference to the function 1317 | */ 1318 | os_shutdown_function_t OS_DEV_SHUTDOWN_REF(symbol function_name); 1319 | 1320 | /*! 1321 | * Generate a reference to an #OS_DEV_OPEN() function 1322 | * 1323 | * @param function_name The name of the open function being referenced. 1324 | * 1325 | * @return A reference to the function 1326 | */ 1327 | os_user_function_t OS_DEV_OPEN_REF(symbol function_name); 1328 | 1329 | /*! 1330 | * Generate a reference to an #OS_DEV_CLOSE() function 1331 | * 1332 | * @param function_name The name of the close function being referenced. 1333 | * 1334 | * @return A reference to the function 1335 | */ 1336 | os_user_function_t OS_DEV_CLOSE_REF(symbol function_name); 1337 | 1338 | /*! 1339 | * Generate a reference to an #OS_DEV_READ() function 1340 | * 1341 | * @param function_name The name of the read function being referenced. 1342 | * 1343 | * @return A reference to the function 1344 | */ 1345 | os_user_function_t OS_DEV_READ_REF(symbol function_name); 1346 | 1347 | /*! 1348 | * Generate a reference to an #OS_DEV_WRITE() function 1349 | * 1350 | * @param function_name The name of the write function being referenced. 1351 | * 1352 | * @return A reference to the function 1353 | */ 1354 | os_user_function_t OS_DEV_WRITE_REF(symbol function_name); 1355 | 1356 | /*! 1357 | * Generate a reference to an #OS_DEV_IOCTL() function 1358 | * 1359 | * @param function_name The name of the ioctl function being referenced. 1360 | * 1361 | * @return A reference to the function 1362 | */ 1363 | os_user_function_t OS_DEV_IOCTL_REF(symbol function_name); 1364 | 1365 | /*! 1366 | * Generate a reference to an #OS_DEV_MMAP() function 1367 | * 1368 | * @param function_name The name of the mmap function being referenced. 1369 | * 1370 | * @return A reference to the function 1371 | */ 1372 | os_user_function_t OS_DEV_MMAP_REF(symbol function_name); 1373 | 1374 | /*! 1375 | * Generate a reference to an #OS_DEV_ISR() function 1376 | * 1377 | * @param function_name The name of the isr being referenced. 1378 | * 1379 | * @return a reference to the function 1380 | */ 1381 | os_interrupt_handler_t OS_DEV_ISR_REF(symbol function_name); 1382 | 1383 | /*! @} *//* drref */ 1384 | 1385 | /*! 1386 | * Flush and invalidate all cache lines. 1387 | */ 1388 | void os_flush_cache_all(void); 1389 | 1390 | /*! 1391 | * Flush a range of addresses from the cache 1392 | * 1393 | * @param start Starting virtual address 1394 | * @param len Number of bytes to flush 1395 | */ 1396 | void os_cache_flush_range(void *start, uint32_t len); 1397 | 1398 | /*! 1399 | * Invalidate a range of addresses in the cache 1400 | * 1401 | * @param start Starting virtual address 1402 | * @param len Number of bytes to flush 1403 | */ 1404 | void os_cache_inv_range(void *start, uint32_t len); 1405 | 1406 | /*! 1407 | * Clean a range of addresses from the cache 1408 | * 1409 | * @param start Starting virtual address 1410 | * @param len Number of bytes to flush 1411 | */ 1412 | void os_cache_clean_range(void *start, uint32_t len); 1413 | 1414 | /*! 1415 | * @example widget.h 1416 | */ 1417 | 1418 | /*! 1419 | * @example widget.c 1420 | */ 1421 | 1422 | /*! 1423 | * @example rng_driver.h 1424 | */ 1425 | 1426 | /*! 1427 | * @example rng_driver.c 1428 | */ 1429 | 1430 | /*! 1431 | * @example shw_driver.h 1432 | */ 1433 | 1434 | /*! 1435 | * @example shw_driver.c 1436 | */ 1437 | 1438 | #endif /* DOXYGEN_PORTABLE_OS_DOC */ 1439 | 1440 | #endif /* PORTABLE_OS_H */ 1441 | -------------------------------------------------------------------------------- /scc2_aes_dev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) WithSecure Corporation 3 | * 4 | * https://github.com/usbarmory/mxc-scc2 5 | * 6 | * This program is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the Free 8 | * Software Foundation under version 3 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 | * more details. 14 | * 15 | * Permission to use, copy, modify, and distribute this software for any 16 | * purpose with or without fee is hereby granted, provided that the above 17 | * copyright notice and this permission notice appear in all copies. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "mxc_scc2_driver.h" 32 | #include "linux_port.h" 33 | 34 | #define DEVICE_NAME "scc2_aes" 35 | #define AES_BLOCK_SIZE 16 36 | 37 | static dev_t dev; 38 | static struct cdev c_dev; 39 | static struct class *cl; 40 | 41 | static uint32_t *iv; 42 | static char aes_buf_in[SZ_4K]; 43 | static char aes_buf_out[SZ_4K]; 44 | 45 | enum scc2_cmd { 46 | SET_MODE, 47 | SET_IV, 48 | }; 49 | 50 | enum scc2_mode { 51 | ENCRYPT_CBC, 52 | DECRYPT_CBC, 53 | }; 54 | 55 | static struct scc2_cfg { 56 | uint8_t mode; 57 | char iv[AES_BLOCK_SIZE]; 58 | } cfg; 59 | 60 | static void clear_iv(void) 61 | { 62 | /* 63 | * After the first block ciphering the SCCv2 internally updates the IV 64 | * in CBC mode. 65 | */ 66 | if (iv != NULL) { 67 | kfree(iv); 68 | iv = NULL; 69 | } 70 | 71 | return; 72 | } 73 | 74 | static void aes_encrypt(uint16_t length, char *data, scc_cypher_mode_t mode, 75 | char *out) 76 | { 77 | int part_no; 78 | uint32_t part_phys; 79 | void *part_base; 80 | void *black_ram; 81 | dma_addr_t handle; 82 | 83 | scc_return_t ret; 84 | 85 | black_ram = dma_alloc_coherent(NULL, length, &handle, GFP_KERNEL); 86 | if (black_ram == NULL) { 87 | printk(KERN_ERR "scc2_aes: failed to allocate black ram\n"); 88 | return; 89 | } 90 | 91 | ret = scc_allocate_partition(0, &part_no, &part_base, &part_phys); 92 | if (ret != SCC_RET_OK) { 93 | printk(KERN_ERR "scc2_aes: failed to allocate partition, error %x\n", ret); 94 | goto out; 95 | } 96 | 97 | ret = scc_engage_partition(part_base, NULL, SCM_PERM_TH_READ | SCM_PERM_TH_WRITE | SCM_PERM_HD_READ | SCM_PERM_HD_WRITE); 98 | if (ret != SCC_RET_OK) { 99 | printk(KERN_ERR "scc2_aes: failed to engage partition, error %x\n", ret); 100 | goto out; 101 | } 102 | 103 | memcpy(part_base, data, length); 104 | 105 | ret = scc_encrypt_region((uint32_t) part_base, 0, length, (uint8_t *) virt_to_phys(black_ram), iv, mode); 106 | if (ret != SCC_RET_OK) { 107 | printk(KERN_ERR "scc2_aes: failed to encrypt block, error %x\n", ret); 108 | goto out; 109 | } 110 | 111 | memcpy(out, black_ram, length); 112 | 113 | ret = scc_release_partition(part_base); 114 | if (ret != SCC_RET_OK) { 115 | printk(KERN_ERR "scc2_aes: failed to release partition, error %x\n", ret); 116 | goto out; 117 | } 118 | 119 | out: 120 | dma_free_coherent(NULL, length, black_ram, handle); 121 | return; 122 | } 123 | 124 | static void aes_decrypt(uint16_t length, char *data, scc_cypher_mode_t mode, 125 | char *out) 126 | { 127 | int part_no; 128 | uint32_t part_phys; 129 | void *part_base; 130 | void *black_ram; 131 | dma_addr_t handle; 132 | 133 | scc_return_t ret; 134 | 135 | black_ram = dma_alloc_coherent(NULL, length, &handle, GFP_KERNEL); 136 | if (black_ram == NULL) { 137 | printk(KERN_ALERT "scc2_aes: failed to allocate black ram\n"); 138 | return; 139 | } 140 | 141 | ret = scc_allocate_partition(0, &part_no, &part_base, &part_phys); 142 | if (ret != SCC_RET_OK) { 143 | printk(KERN_ALERT "scc2_aes: failed to allocate partition, error %x\n", ret); 144 | goto out; 145 | } 146 | 147 | ret = scc_engage_partition(part_base, NULL, SCM_PERM_TH_READ | SCM_PERM_TH_WRITE | SCM_PERM_HD_READ | SCM_PERM_HD_WRITE); 148 | if (ret != SCC_RET_OK) { 149 | printk(KERN_ALERT "scc2_aes: failed to engage partition, error %x\n", ret); 150 | goto out; 151 | } 152 | 153 | memcpy(black_ram, data, length); 154 | 155 | ret = scc_decrypt_region((uint32_t) part_base, 0, length, (uint8_t *) virt_to_phys(black_ram), iv, mode); 156 | if (ret != SCC_RET_OK) { 157 | printk(KERN_ALERT "scc2_aes: failed to decrypt black ram, error %x\n", ret); 158 | goto out; 159 | } 160 | 161 | memcpy(out, part_base, length); 162 | 163 | ret = scc_release_partition(part_base); 164 | if (ret != SCC_RET_OK) { 165 | printk(KERN_ALERT "scc2_aes: failed to release partition, error %x\n", ret); 166 | goto out; 167 | } 168 | 169 | out: 170 | dma_free_coherent(NULL, length, black_ram, handle); 171 | return; 172 | } 173 | 174 | static ssize_t device_read(struct file *filp, char __user *buff, 175 | size_t len, loff_t *off) 176 | { 177 | int errlen; 178 | 179 | if (len > SZ_4K) { 180 | len = SZ_4K; 181 | } 182 | 183 | errlen = copy_to_user(buff, aes_buf_out, len); 184 | 185 | return len - errlen; 186 | } 187 | 188 | static ssize_t device_write(struct file *filp, const char __user *buff, 189 | size_t len, loff_t *off) 190 | { 191 | int errlen; 192 | 193 | if (len > SZ_4K) { 194 | len = SZ_4K; 195 | } 196 | 197 | errlen = copy_from_user(aes_buf_in, buff, len); 198 | 199 | switch (cfg.mode) { 200 | case ENCRYPT_CBC: 201 | aes_encrypt(len, aes_buf_in, SCC_CYPHER_MODE_CBC, aes_buf_out); 202 | clear_iv(); 203 | break; 204 | case DECRYPT_CBC: 205 | aes_decrypt(len, aes_buf_in, SCC_CYPHER_MODE_CBC, aes_buf_out); 206 | clear_iv(); 207 | break; 208 | default: 209 | printk(KERN_ALERT "scc2_aes: invalid configuration mode (%d)\n", cfg.mode); 210 | break; 211 | } 212 | 213 | return len - errlen; 214 | } 215 | 216 | static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 217 | { 218 | int rlen; 219 | 220 | switch (cmd) { 221 | case SET_MODE: 222 | if (arg == ENCRYPT_CBC) { 223 | printk(KERN_DEBUG "scc2_aes: setting CBC encryption mode\n"); 224 | cfg.mode = ENCRYPT_CBC; 225 | } else if (arg == DECRYPT_CBC) { 226 | printk(KERN_DEBUG "scc2_aes: setting CBC decryption mode\n"); 227 | cfg.mode = DECRYPT_CBC; 228 | } else { 229 | printk(KERN_ALERT "scc2_aes: invalid configuration mode (%lu)\n", arg); 230 | } 231 | break; 232 | case SET_IV: 233 | printk(KERN_DEBUG "scc2_aes: setting initialization vector\n"); 234 | 235 | if (iv == NULL) { 236 | iv = kzalloc(AES_BLOCK_SIZE, GFP_KERNEL); 237 | } 238 | 239 | rlen = copy_from_user(iv, (char *) arg, AES_BLOCK_SIZE); 240 | 241 | break; 242 | } 243 | 244 | return 0; 245 | } 246 | 247 | static struct file_operations fops = { 248 | .read = device_read, 249 | .write = device_write, 250 | .unlocked_ioctl = device_ioctl, 251 | }; 252 | 253 | int register_chardev(void) 254 | { 255 | int major; 256 | 257 | major = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); 258 | 259 | if (major < 0) { 260 | printk(KERN_ERR "scc2_aes: could not allocate character device\n"); 261 | goto errout; 262 | } 263 | 264 | #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) 265 | cl = class_create(THIS_MODULE, "crypto"); 266 | #else 267 | cl = class_create("crypto"); 268 | #endif 269 | if (cl == NULL) { 270 | printk(KERN_ERR "scc2_aes: class creation failed\n"); 271 | unregister_chrdev_region(dev, 1); 272 | goto errout; 273 | } 274 | 275 | if (device_create(cl, NULL, dev, NULL, DEVICE_NAME) == NULL) { 276 | printk(KERN_ERR "scc2_aes: device creation failed\n"); 277 | class_destroy(cl); 278 | unregister_chrdev_region(dev, 1); 279 | goto errout; 280 | } 281 | 282 | cdev_init(&c_dev, &fops); 283 | 284 | if (cdev_add(&c_dev, dev, 1) == -1) { 285 | printk(KERN_ERR "scc2_aes: device addition failed\n"); 286 | device_destroy(cl, dev); 287 | class_destroy(cl); 288 | unregister_chrdev_region(dev, 1); 289 | goto errout; 290 | } 291 | 292 | printk(KERN_INFO "scc2_aes: registered /dev/%s\n", DEVICE_NAME); 293 | 294 | return 0; 295 | 296 | errout: 297 | return -1; 298 | } 299 | 300 | void unregister_chardev(void) 301 | { 302 | cdev_del(&c_dev); 303 | device_destroy(cl, dev); 304 | class_destroy(cl); 305 | unregister_chrdev_region(dev, 1); 306 | 307 | printk(KERN_INFO "scc2_aes: unregistered /dev/%s\n", DEVICE_NAME); 308 | } 309 | 310 | static int scc2_aes_dev_init(void) 311 | { 312 | scc_config_t *scc_config = NULL; 313 | uint32_t status; 314 | 315 | scc_config = scc_get_configuration(); 316 | if (scc_config == NULL) { 317 | printk(KERN_ERR "scc2_aes: cannot get SCC configuration, aborting\n"); 318 | goto errout; 319 | } 320 | 321 | if (scc_config->scm_version == 0) { 322 | printk(KERN_ERR "scc2_aes: cannot read scm_version, aborting\n"); 323 | goto errout; 324 | } 325 | 326 | cfg.mode = ENCRYPT_CBC; 327 | 328 | iv = kzalloc(AES_BLOCK_SIZE, GFP_KERNEL); 329 | if (iv == NULL) { 330 | printk(KERN_ERR "scc2_aes: unable to allocate IV, aborting\n"); 331 | goto errout; 332 | } 333 | 334 | if (register_chardev() != 0) { 335 | printk(KERN_ERR "scc2_aes: character device registration failed\n"); 336 | goto errout; 337 | } 338 | 339 | scc_read_register(SCM_STATUS_REG, &status); 340 | 341 | if (status & SCM_STATUS_MSS_SEC) { 342 | printk(KERN_INFO "scc2_aes: Secure State detected\n"); 343 | } else { 344 | printk(KERN_NOTICE "scc2_aes: WARNING - not in Secure State, NIST test key in effect\n"); 345 | } 346 | 347 | return 0; 348 | 349 | errout: 350 | return -1; 351 | } 352 | 353 | static void scc2_aes_dev_exit(void) 354 | { 355 | printk(KERN_INFO "scc2_aes: shutting down\n"); 356 | 357 | unregister_chardev(); 358 | 359 | clear_iv(); 360 | } 361 | 362 | module_init(scc2_aes_dev_init); 363 | module_exit(scc2_aes_dev_exit); 364 | 365 | MODULE_LICENSE("GPL"); 366 | MODULE_AUTHOR("Inverse Path"); 367 | MODULE_DESCRIPTION("NXP Security Controller (SCCv2) character device interface"); 368 | -------------------------------------------------------------------------------- /scc2_aes_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) WithSecure Corporation 3 | * 4 | * https://github.com/usbarmory/mxc-scc2 5 | * 6 | * This program is free software: you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License as published by the Free 8 | * Software Foundation under version 3 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 | * more details. 14 | * 15 | * Permission to use, copy, modify, and distribute this software for any 16 | * purpose with or without fee is hereby granted, provided that the above 17 | * copyright notice and this permission notice appear in all copies. 18 | */ 19 | 20 | static int aes_encrypt_test(void) 21 | { 22 | int part_no, length; 23 | uint32_t part_phys; 24 | uint32_t plaintext[4]; 25 | uint32_t iv[4]; 26 | void *part_base; 27 | void *black_ram; 28 | dma_addr_t handle; 29 | 30 | scc_return_t ret; 31 | 32 | iv[0] = 0x03020100; 33 | iv[1] = 0x07060504; 34 | iv[2] = 0x0b0a0908; 35 | iv[3] = 0x0f0e0d0c; 36 | 37 | plaintext[0] = 0xe2bec16b; 38 | plaintext[1] = 0x969f402e; 39 | plaintext[2] = 0x117e3de9; 40 | plaintext[3] = 0x2a179373; 41 | length = sizeof(plaintext); 42 | 43 | // key: 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 44 | // iv: 000102030405060708090a0b0c0d0e0f 45 | // test vector: 6bc1bee22e409f96e93d7e117393172a # 1st block 46 | // cipher text: f58c4c04d6e5f1ba779eabfb5f7bfbd6 47 | // test vector: 6bc1bee22e409f96e93d7e117393172a # 2nd block 48 | // cipher text: eb2d9e942831bd84dff00db9776b8088 49 | 50 | printk(KERN_ALERT "scc2_aes_test: ---- encryption test ----\n"); 51 | 52 | black_ram = dma_alloc_coherent(NULL, length, &handle, GFP_KERNEL); 53 | 54 | if (!black_ram) { 55 | printk(KERN_ALERT "scc2_aes_test: failed to allocate black ram\n"); 56 | return 0; 57 | } 58 | 59 | ret = scc_allocate_partition(0, &part_no, &part_base, &part_phys); 60 | 61 | if (ret != SCC_RET_OK) { 62 | printk(KERN_ALERT "scc2_aes_test: failed to allocate partition, error %x\n", ret); 63 | goto out; 64 | } 65 | printk(KERN_DEBUG "scc2_aes_test: allocated part_no: %x, part_base: %p, part_phys: %x\n", 66 | part_no, part_base, part_phys); 67 | 68 | ret = scc_engage_partition(part_base, NULL, SCM_PERM_TH_READ | SCM_PERM_TH_WRITE | SCM_PERM_HD_READ | SCM_PERM_HD_WRITE); 69 | 70 | if (ret != SCC_RET_OK) { 71 | printk(KERN_ALERT "scc2_aes_test: failed to engage partition, error %x\n", ret); 72 | goto out; 73 | } 74 | printk(KERN_DEBUG "scc2_aes_test: engaged part_no: %x\n", part_no); 75 | 76 | writel(plaintext[0], (void *)(part_base + 0)); 77 | writel(plaintext[1], (void *)(part_base + 4)); 78 | writel(plaintext[2], (void *)(part_base + 8)); 79 | writel(plaintext[3], (void *)(part_base + 12)); 80 | 81 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: partition ", DUMP_PREFIX_ADDRESS, 82 | length, 1, part_base, length, false); 83 | 84 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: black pre ", DUMP_PREFIX_ADDRESS, 85 | length, 1, black_ram, length, false); 86 | 87 | // 1st block 88 | 89 | ret = scc_encrypt_region((uint32_t) part_base, 0, length, (uint8_t *) virt_to_phys(black_ram), iv, SCC_CYPHER_MODE_CBC); 90 | 91 | if (ret != SCC_RET_OK) { 92 | printk(KERN_ALERT "scc2_aes_test: failed to encrypt region, error %x\n", ret); 93 | goto out; 94 | } 95 | printk(KERN_DEBUG "scc2_aes_test: encrypted region part_base: %p\n", part_base); 96 | 97 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: black post ", DUMP_PREFIX_ADDRESS, 98 | length, 1, black_ram, length, false); 99 | 100 | // 2nd block 101 | 102 | ret = scc_encrypt_region((uint32_t) part_base, 0, length, (uint8_t *) virt_to_phys(black_ram), NULL, SCC_CYPHER_MODE_CBC); 103 | 104 | if (ret != SCC_RET_OK) { 105 | printk(KERN_ALERT "scc2_aes_test: failed to encrypt region, error %x\n", ret); 106 | goto out; 107 | } 108 | printk(KERN_DEBUG "scc2_aes_test: encrypted region part_base: %p\n", part_base); 109 | 110 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: black post ", DUMP_PREFIX_ADDRESS, 111 | length, 1, black_ram, length, false); 112 | 113 | // done 114 | 115 | ret = scc_release_partition(part_base); 116 | 117 | if (ret != SCC_RET_OK) { 118 | printk(KERN_ALERT "scc2_aes_test: failed to release partition, error %x\n", ret); 119 | goto out; 120 | } 121 | printk(KERN_DEBUG "scc2_aes_test: released part_no: %x\n", part_no); 122 | 123 | out: 124 | dma_free_coherent(NULL, length, black_ram, handle); 125 | return 0; 126 | } 127 | 128 | static int aes_decrypt_test(void) 129 | { 130 | int part_no, length; 131 | uint32_t part_phys; 132 | uint32_t ciphertext[4]; 133 | uint32_t iv[4]; 134 | void *part_base; 135 | void *black_ram; 136 | dma_addr_t handle; 137 | 138 | scc_return_t ret; 139 | 140 | iv[0] = 0x03020100; 141 | iv[1] = 0x07060504; 142 | iv[2] = 0x0b0a0908; 143 | iv[3] = 0x0f0e0d0c; 144 | 145 | ciphertext[0] = 0x044c8cf5; 146 | ciphertext[1] = 0xbaf1e5d6; 147 | ciphertext[2] = 0xfbab9e77; 148 | ciphertext[3] = 0xd6fb7b5f; 149 | length = sizeof(ciphertext); 150 | 151 | // key: 603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 152 | // iv: 000102030405060708090a0b0c0d0e0f 153 | // test vector: f58c4c04d6e5f1ba779eabfb5f7bfbd6 # 1st block 154 | // plaintext: 6bc1bee22e409f96e93d7e117393172a 155 | // test vector: eb2d9e942831bd84dff00db9776b8088 # 2nd block 156 | // plaintext: 6bc1bee22e409f96e93d7e117393172a 157 | 158 | printk(KERN_ALERT "scc2_aes_test: ---- decryption test ----\n"); 159 | 160 | black_ram = dma_alloc_coherent(NULL, length, &handle, GFP_KERNEL); 161 | 162 | if (!black_ram) { 163 | printk(KERN_ALERT "scc2_aes_test: failed to allocate black ram\n"); 164 | return 0; 165 | } 166 | 167 | ret = scc_allocate_partition(0, &part_no, &part_base, &part_phys); 168 | 169 | if (ret != SCC_RET_OK) { 170 | printk(KERN_ALERT "scc2_aes_test: failed to allocate partition, error %x\n", ret); 171 | goto out; 172 | } 173 | printk(KERN_DEBUG "scc2_aes_test: allocated part_no: %x, part_base: %p, part_phys: %x\n", 174 | part_no, part_base, part_phys); 175 | 176 | ret = scc_engage_partition(part_base, NULL, SCM_PERM_TH_READ | SCM_PERM_TH_WRITE | SCM_PERM_HD_READ | SCM_PERM_HD_WRITE); 177 | 178 | if (ret != SCC_RET_OK) { 179 | printk(KERN_ALERT "scc2_aes_test: failed to engage partition, error %x\n", ret); 180 | goto out; 181 | } 182 | printk(KERN_DEBUG "scc2_aes_test: engaged part_no: %x\n", part_no); 183 | 184 | memcpy(black_ram, ciphertext, length); 185 | 186 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: black ", DUMP_PREFIX_ADDRESS, 187 | length, 1, black_ram, length, false); 188 | 189 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: partition pre ", DUMP_PREFIX_ADDRESS, 190 | length, 1, part_base, length, false); 191 | 192 | // 1st block 193 | 194 | ret = scc_decrypt_region((uint32_t) part_base, 0, length, (uint8_t *) virt_to_phys(black_ram), iv, SCC_CYPHER_MODE_CBC); 195 | 196 | if (ret != SCC_RET_OK) { 197 | printk(KERN_ALERT "scc2_aes_test: failed to decrypt black ram, error %x\n", ret); 198 | goto out; 199 | } 200 | printk(KERN_DEBUG "scc2_aes_test: decrypted black ram to region part_base: %p\n", part_base); 201 | 202 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: partition post ", DUMP_PREFIX_ADDRESS, 203 | length, 1, part_base, length, false); 204 | 205 | // 2nd block 206 | 207 | ciphertext[0] = 0x949e2deb; 208 | ciphertext[1] = 0x84bd3128; 209 | ciphertext[2] = 0xb90df0df; 210 | ciphertext[3] = 0x88806b77; 211 | 212 | memcpy(black_ram, ciphertext, length); 213 | 214 | ret = scc_decrypt_region((uint32_t) part_base, 0, length, (uint8_t *) virt_to_phys(black_ram), NULL, SCC_CYPHER_MODE_CBC); 215 | 216 | if (ret != SCC_RET_OK) { 217 | printk(KERN_ALERT "scc2_aes_test: failed to decrypt black ram, error %x\n", ret); 218 | goto out; 219 | } 220 | printk(KERN_DEBUG "scc2_aes_test: decrypted black ram to region part_base: %p\n", part_base); 221 | 222 | print_hex_dump(KERN_DEBUG, "scc2_aes_test: partition post ", DUMP_PREFIX_ADDRESS, 223 | length, 1, part_base, length, false); 224 | 225 | // done 226 | 227 | ret = scc_release_partition(part_base); 228 | 229 | if (ret != SCC_RET_OK) { 230 | printk(KERN_ALERT "scc2_aes_test: failed to release partition, error %x\n", ret); 231 | goto out; 232 | } 233 | printk(KERN_DEBUG "scc2_aes_test: released part_no: %x\n", part_no); 234 | 235 | out: 236 | dma_free_coherent(NULL, length, black_ram, handle); 237 | return 0; 238 | } 239 | -------------------------------------------------------------------------------- /scc2_internals.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved. 3 | */ 4 | 5 | /* 6 | * The code contained herein is licensed under the GNU General Public 7 | * License. You may obtain a copy of the GNU General Public License 8 | * Version 2 or later at the following locations: 9 | * 10 | * http://www.opensource.org/licenses/gpl-license.html 11 | * http://www.gnu.org/copyleft/gpl.html 12 | */ 13 | #ifndef SCC_INTERNALS_H 14 | #define SCC_INTERNALS_H 15 | 16 | /** @file scc2_internals.h 17 | * 18 | * @brief This is intended to be the file which contains most or all of the 19 | * code or changes need to port the driver. It also includes other definitions 20 | * needed by the driver. 21 | * 22 | * This header file should only ever be included by scc2_driver.c 23 | * 24 | * Compile-time flags minimally needed: 25 | * 26 | * @li Some sort of platform flag. Currently TAHITI and MXC are understood. 27 | * @li Some start-of-SCC consideration, such as SCC_BASE_ADDR 28 | * 29 | * Some changes which could be made when porting this driver: 30 | * #SCC_SPIN_COUNT 31 | * 32 | */ 33 | 34 | #include /* Current version Linux kernel */ 35 | #include /* Basic support for loadable modules, 36 | printk */ 37 | #include /* module_init, module_exit */ 38 | #include /* General kernel system calls */ 39 | #include /* for interrupt.h */ 40 | #include 41 | 42 | #include /* ioremap() */ 43 | #include /* IRQ / interrupt definitions */ 44 | 45 | 46 | #include "mxc_scc2_driver.h" 47 | 48 | /** 49 | * Define the number of Stored Keys which the SCC driver will make available. 50 | * Value shall be from 0 to 20. Default is zero (0). 51 | */ 52 | /*#define SCC_KEY_SLOTS 20*/ 53 | 54 | 55 | /* Temporarily define compile-time flags to make Doxygen happy. */ 56 | #ifdef DOXYGEN_HACK 57 | /** @addtogroup scccompileflags */ 58 | /** @{ */ 59 | 60 | 61 | /** @def NO_SMN_INTERRUPT 62 | * The SMN interrupt is not wired to the CPU at all. 63 | */ 64 | #define NO_SMN_INTERRUPT 65 | 66 | 67 | /** 68 | * Register an interrupt handler for the SMN as well as 69 | * the SCM. In some implementations, the SMN is not connected at all (see 70 | * #NO_SMN_INTERRUPT), and in others, it is on the same interrupt line as the 71 | * SCM. When defining this flag, the SMN interrupt should be on a separate 72 | * line from the SCM interrupt. 73 | */ 74 | 75 | #define USE_SMN_INTERRUPT 76 | 77 | 78 | /** 79 | * Turn on generation of run-time operational, debug, and error messages 80 | */ 81 | #define SCC_DEBUG 82 | 83 | 84 | /** 85 | * Turn on generation of run-time logging of access to the SCM and SMN 86 | * registers. 87 | */ 88 | #define SCC_REGISTER_DEBUG 89 | 90 | 91 | /** 92 | * Turn on generation of run-time logging of access to the SCM Red and 93 | * Black memories. Will only work if #SCC_REGISTER_DEBUG is also defined. 94 | */ 95 | #define SCC_RAM_DEBUG 96 | 97 | 98 | /** 99 | * If the driver finds the SCC in HEALTH_CHECK state, go ahead and 100 | * run a quick ASC to bring it to SECURE state. 101 | */ 102 | #define SCC_BRINGUP 103 | 104 | 105 | /** 106 | * Expected to come from platform header files or compile command line. 107 | * This symbol must be the address of the SCC 108 | */ 109 | #define SCC_BASE 110 | 111 | /** 112 | * This must be the interrupt line number of the SCM interrupt. 113 | */ 114 | #define INT_SCM 115 | 116 | /** 117 | * if #USE_SMN_INTERRUPT is defined, this must be the interrupt line number of 118 | * the SMN interrupt. 119 | */ 120 | #define INT_SMN 121 | 122 | /** 123 | * Define the number of Stored Keys which the SCC driver will make available. 124 | * Value shall be from 0 to 20. Default is zero (0). 125 | */ 126 | #define SCC_KEY_SLOTS 127 | 128 | /** 129 | * Make sure that this flag is defined if compiling for a Little-Endian 130 | * platform. Linux Kernel builds provide this flag. 131 | */ 132 | #define __LITTLE_ENDIAN 133 | 134 | /** 135 | * Make sure that this flag is defined if compiling for a Big-Endian platform. 136 | * Linux Kernel builds provide this flag. 137 | */ 138 | #define __BIG_ENDIAN 139 | 140 | /** 141 | * Read a 32-bit register value from a 'peripheral'. Standard Linux/Unix 142 | * macro. 143 | * 144 | * @param offset Bus address of register to be read 145 | * 146 | * @return The value of the register 147 | */ 148 | #define readl(offset) 149 | 150 | 151 | /** 152 | * Write a 32-bit value to a register in a 'peripheral'. Standard Linux/Unix 153 | * macro. 154 | * 155 | * @param value The 32-bit value to store 156 | * @param offset Bus address of register to be written 157 | * 158 | * return (none) 159 | */ 160 | #define writel(value,offset) 161 | 162 | 163 | /** @} */ /* end group scccompileflags */ 164 | 165 | #endif /* DOXYGEN_HACK */ 166 | 167 | 168 | #ifndef SCC_KEY_SLOTS 169 | #define SCC_KEY_SLOTS 0 170 | 171 | #else 172 | 173 | #if (SCC_KEY_SLOTS < 0) || (SCC_KEY_SLOTS > 20) 174 | #error Bad value for SCC_KEY_SLOTS 175 | #endif 176 | 177 | #endif 178 | 179 | 180 | /** 181 | * Maximum length of key/secret value which can be stored in SCC. 182 | */ 183 | #define SCC_MAX_KEY_SIZE 256 184 | 185 | 186 | /** 187 | * This is the size, in bytes, of each key slot, and therefore the maximum size 188 | * of the wrapped key. 189 | */ 190 | #define SCC_KEY_SLOT_SIZE 32 191 | 192 | 193 | /* These come for free with Linux, but may need to be set in a port. */ 194 | #ifndef __BIG_ENDIAN 195 | #ifndef __LITTLE_ENDIAN 196 | #error One of __LITTLE_ENDIAN or __BIG_ENDIAN must be #defined 197 | #endif 198 | #else 199 | #ifdef __LITTLE_ENDIAN 200 | #error Exactly one of __LITTLE_ENDIAN or __BIG_ENDIAN must be #defined 201 | #endif 202 | #endif 203 | 204 | 205 | #ifndef SCC_CALLBACK_SIZE 206 | /** The number of function pointers which can be stored in #scc_callbacks. 207 | * Defaults to 4, can be overridden with compile-line argument. 208 | */ 209 | #define SCC_CALLBACK_SIZE 4 210 | #endif 211 | 212 | 213 | /** Initial CRC value for CCITT-CRC calculation. */ 214 | #define CRC_CCITT_START 0xFFFF 215 | 216 | 217 | #ifdef TAHITI 218 | 219 | /** 220 | * The SCC_BASE has to be SMN_BASE_ADDR on TAHITI, as the banks of 221 | * registers are swapped in place. 222 | */ 223 | #define SCC_BASE SMN_BASE_ADDR 224 | 225 | 226 | /** The interrupt number for the SCC (SCM only!) on Tahiti */ 227 | #define INT_SCC_SCM 62 228 | 229 | 230 | /** Tahiti does not have the SMN interrupt wired to the CPU. */ 231 | #define NO_SMN_INTERRUPT 232 | 233 | 234 | #endif /* TAHITI */ 235 | 236 | 237 | /** Number of times to spin between polling of SCC while waiting for cipher 238 | * or zeroizing function to complete. See also #SCC_CIPHER_MAX_POLL_COUNT. */ 239 | #define SCC_SPIN_COUNT 1000 240 | 241 | 242 | /** Number of times to polling SCC while waiting for cipher 243 | * or zeroizing function to complete. See also #SCC_SPIN_COUNT. */ 244 | #define SCC_CIPHER_MAX_POLL_COUNT 100 245 | 246 | 247 | /** 248 | * @def SCC_READ_REGISTER 249 | * Read a 32-bit value from an SCC register. Macro which depends upon 250 | * #scc_base. Linux readl()/writel() macros operate on 32-bit quantities, as 251 | * do SCC register reads/writes. 252 | * 253 | * @param offset Register offset within SCC. 254 | * 255 | * @return The value from the SCC's register. 256 | */ 257 | #ifndef SCC_REGISTER_DEBUG 258 | #define SCC_READ_REGISTER(offset) __raw_readl(scc_base+(offset)) 259 | #else 260 | #define SCC_READ_REGISTER(offset) dbg_scc_read_register(offset) 261 | #endif 262 | 263 | 264 | /** 265 | * Write a 32-bit value to an SCC register. Macro depends upon #scc_base. 266 | * Linux readl()/writel() macros operate on 32-bit quantities, as do SCC 267 | * register reads/writes. 268 | * 269 | * @param offset Register offset within SCC. 270 | * @param value 32-bit value to store into the register 271 | * 272 | * @return (void) 273 | */ 274 | #ifndef SCC_REGISTER_DEBUG 275 | #define SCC_WRITE_REGISTER(offset,value) \ 276 | (void)__raw_writel(value, scc_base+(offset)) 277 | #else 278 | #define SCC_WRITE_REGISTER(offset,value) \ 279 | dbg_scc_write_register(offset, value) 280 | #endif 281 | 282 | /** 283 | * Calculate the kernel virtual address of a partition from the partition number. 284 | */ 285 | #define SCM_PART_ADDRESS(part) \ 286 | (scm_ram_base + (part*scc_configuration.partition_size_bytes)) 287 | 288 | /** 289 | * Calculate the partition number from the kernel virtual address. 290 | */ 291 | #define SCM_PART_NUMBER(address) \ 292 | ((address - (uint32_t)scm_ram_base)/scc_configuration.partition_size_bytes) 293 | 294 | /** 295 | * Calculates the byte offset into a word 296 | * @param bp The byte (char*) pointer 297 | * @return The offset (0, 1, 2, or 3) 298 | */ 299 | #define SCC_BYTE_OFFSET(bp) ((uint32_t)(bp) % sizeof(uint32_t)) 300 | 301 | 302 | /** 303 | * Converts (by rounding down) a byte pointer into a word pointer 304 | * @param bp The byte (char*) pointer 305 | * @return The word (uint32_t) as though it were an aligned (uint32_t*) 306 | */ 307 | #define SCC_WORD_PTR(bp) (((uint32_t)(bp)) & ~(sizeof(uint32_t)-1)) 308 | 309 | 310 | /** 311 | * Determine number of bytes in an SCC block 312 | * 313 | * @return Bytes / block 314 | */ 315 | #define SCC_BLOCK_SIZE_BYTES() scc_configuration.block_size_bytes 316 | 317 | 318 | /** 319 | * Maximum number of additional bytes which may be added in CRC+padding mode. 320 | */ 321 | #define PADDING_BUFFER_MAX_BYTES (CRC_SIZE_BYTES + sizeof(scc_block_padding)) 322 | 323 | /** 324 | * Shorthand (clearer, anyway) for number of bytes in a CRC. 325 | */ 326 | #define CRC_SIZE_BYTES (sizeof(crc_t)) 327 | 328 | /** 329 | * The polynomial used in CCITT-CRC calculation 330 | */ 331 | #define CRC_POLYNOMIAL 0x1021 332 | 333 | /** 334 | * Calculate CRC on one byte of data 335 | * 336 | * @param[in,out] running_crc A value of type crc_t where CRC is kept. This 337 | * must be an rvalue and an lvalue. 338 | * @param[in] byte_value The byte (uint8_t, char) to be put in the CRC 339 | * 340 | * @return none 341 | */ 342 | #define CALC_CRC(byte_value,running_crc) { \ 343 | uint8_t data; \ 344 | data = (0xff&(byte_value)) ^ (running_crc >> 8); \ 345 | running_crc = scc_crc_lookup_table[data] ^ (running_crc << 8); \ 346 | } 347 | 348 | /** Value of 'beginning of padding' marker in driver-provided padding */ 349 | #define SCC_DRIVER_PAD_CHAR 0x80 350 | 351 | 352 | /** Name of the driver. Used (on Linux, anyway) when registering interrupts */ 353 | #define SCC_DRIVER_NAME "mxc_scc" 354 | 355 | 356 | /* Port -- these symbols are defined in Linux 2.6 and later. They are defined 357 | * here for backwards compatibility because this started life as a 2.4 358 | * driver, and as a guide to portation to other platforms. 359 | */ 360 | 361 | #if !defined(LINUX_VERSION_CODE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 362 | 363 | #define irqreturn_t void /* Return type of an interrupt handler */ 364 | 365 | #define IRQ_HANDLED /* Would be '1' for handled -- as in return IRQ_HANDLED; */ 366 | 367 | #define IRQ_NONE /* would be '0' for not handled -- as in return IRQ_NONE; */ 368 | 369 | #define IRQ_RETVAL(x) /* Return x==0 (not handled) or non-zero (handled) */ 370 | 371 | #endif /* LINUX earlier than 2.5 */ 372 | 373 | 374 | /* These are nice to have around */ 375 | #ifndef FALSE 376 | #define FALSE 0 377 | #endif 378 | #ifndef TRUE 379 | #define TRUE 1 380 | #endif 381 | 382 | 383 | /** Provide a typedef for the CRC which can be used in encrypt/decrypt */ 384 | typedef uint16_t crc_t; 385 | 386 | 387 | /** Gives high-level view of state of the SCC */ 388 | enum scc_status { 389 | SCC_STATUS_INITIAL, /**< State of driver before ever checking */ 390 | SCC_STATUS_CHECKING, /**< Transient state while driver loading */ 391 | SCC_STATUS_UNIMPLEMENTED, /**< SCC is non-existent or unuseable */ 392 | SCC_STATUS_OK, /**< SCC is in Secure or Default state */ 393 | SCC_STATUS_FAILED /**< In Failed state */ 394 | }; 395 | 396 | /** 397 | * Information about a key slot. 398 | */ 399 | struct scc_key_slot 400 | { 401 | uint64_t owner_id; /**< Access control value. */ 402 | uint32_t length; /**< Length of value in slot. */ 403 | uint32_t offset; /**< Offset of value from start of RAM. */ 404 | uint32_t status; /**< 0 = unassigned, 1 = assigned. */ 405 | uint32_t part_ctl; /**< for the CCMD register */ 406 | }; 407 | 408 | /* Forward-declare a number routines which are not part of user api */ 409 | static int scc_init(void); 410 | static void scc_cleanup(void); 411 | static int __init scc_driver_init(void); 412 | static void __exit scc_driver_exit(void); 413 | 414 | /* Forward defines of internal functions */ 415 | OS_DEV_ISR(scc_irq); 416 | /*static irqreturn_t scc_irq(int irq, void *dev_id);*/ 417 | /** Perform callbacks registered by #scc_monitor_security_failure(). 418 | * 419 | * Make sure callbacks only happen once... Since there may be some reason why 420 | * the interrupt isn't generated, this routine could be called from base(task) 421 | * level. 422 | * 423 | * One at a time, go through #scc_callbacks[] and call any non-null pointers. 424 | */ 425 | static void scc_perform_callbacks(void); 426 | /*static uint32_t copy_to_scc(const uint8_t* from, uint32_t to, unsigned long count_bytes, uint16_t* crc); 427 | static uint32_t copy_from_scc(const uint32_t from, uint8_t* to,unsigned long count_bytes, uint16_t* crc); 428 | static scc_return_t scc_strip_padding(uint8_t* from,unsigned* count_bytes_stripped);*/ 429 | static uint32_t scc_update_state(void); 430 | static void scc_init_ccitt_crc(void); 431 | static uint32_t scc_grab_config_values(void); 432 | static int setup_interrupt_handling(void); 433 | static uint32_t host_owns_partition(uint32_t part_no); 434 | static uint32_t partition_engaged(uint32_t part_no); 435 | 436 | static scc_return_t scc_wait_completion(uint32_t* scm_status); 437 | static int is_cipher_done(uint32_t* scm_status); 438 | static scc_return_t check_register_accessible (uint32_t offset, 439 | uint32_t smn_status, 440 | uint32_t scm_status); 441 | static scc_return_t check_register_offset(uint32_t offset); 442 | /*uint8_t make_vpu_partition(void);*/ 443 | 444 | #ifdef SCC_REGISTER_DEBUG 445 | static uint32_t dbg_scc_read_register(uint32_t offset); 446 | static void dbg_scc_write_register(uint32_t offset, uint32_t value); 447 | #endif 448 | 449 | 450 | /* For Linux kernel, export the API functions to other kernel modules */ 451 | EXPORT_SYMBOL(scc_get_configuration); 452 | EXPORT_SYMBOL(scc_zeroize_memories); 453 | /*EXPORT_SYMBOL(scc_crypt);*/ 454 | EXPORT_SYMBOL(scc_set_sw_alarm); 455 | EXPORT_SYMBOL(scc_monitor_security_failure); 456 | EXPORT_SYMBOL(scc_stop_monitoring_security_failure); 457 | EXPORT_SYMBOL(scc_read_register); 458 | EXPORT_SYMBOL(scc_write_register); 459 | EXPORT_SYMBOL(scc_allocate_partition); 460 | EXPORT_SYMBOL(scc_engage_partition); 461 | EXPORT_SYMBOL(scc_release_partition); 462 | EXPORT_SYMBOL(scc_diminish_permissions); 463 | EXPORT_SYMBOL(scc_encrypt_region); 464 | EXPORT_SYMBOL(scc_decrypt_region); 465 | EXPORT_SYMBOL(scc_partition_status); 466 | EXPORT_SYMBOL(scc_virt_to_phys); 467 | /*EXPORT_SYMBOL(make_vpu_partition);*/ 468 | 469 | 470 | /* Tell Linux this is not GPL code */ 471 | MODULE_LICENSE("GPL"); 472 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); 473 | MODULE_DESCRIPTION("Device Driver for SCC (SMN/SCM)"); 474 | 475 | 476 | #endif /* SCC_INTERNALS_H */ 477 | -------------------------------------------------------------------------------- /scc2_test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # NXP Security Controller (SCCv2) - userspace driver reference example 4 | # https://github.com/usbarmory/mxc-scc2 5 | # 6 | # This program is distributed in the hope that it will be useful, but WITHOUT 7 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 8 | # FOR A PARTICULAR PURPOSE. 9 | 10 | # The following code illustrates reference usage of the scc2_aes kernel driver 11 | # and compares AES-256-CBC encryption/decryption output between OpenSSL and the 12 | # hardware controller. 13 | # 14 | # IMPORTANT: the SCCv2 internal key is available only when Secure Boot (HAB) is 15 | # enabled, otherwise the AES-256 NIST standard test key is set. For this reason 16 | # the OpenSSL and SCCv2 output comparison of the scc2_test script matches only 17 | # on units that do not have HAB enabled. The secure operation of the SCCv2, in 18 | # production deployments, should always be paired with Secure Boot activation. 19 | 20 | require 'openssl' 21 | 22 | SCC2 = '/dev/scc2_aes' 23 | SET_MODE = 0 24 | SET_IV = 1 25 | ENCRYPT_CBC = 0 26 | DECRYPT_CBC = 1 27 | 28 | KEY = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4" 29 | IV = "000102030405060708090a0b0c0d0e0f" 30 | TV = "6bc1bee22e409f96e93d7e117393172a" 31 | 32 | def hex_to_bin(hex) 33 | hex.scan(/../).map { |x| x.to_i(16).chr }.join 34 | end 35 | 36 | def bin_to_hex(bin) 37 | bin.bytes.map { |b| b.to_s(16).rjust(2, '0') }.join 38 | end 39 | 40 | def openssl_cipher(key, iv, tv, mode = :encrypt) 41 | aes = OpenSSL::Cipher::AES.new(256, :CBC) 42 | aes.send(mode) 43 | aes.key = key 44 | aes.iv = iv 45 | aes.padding = 0 46 | 47 | aes.update(tv) + aes.final 48 | end 49 | 50 | def scc_cipher(key, iv, tv, mode = ENCRYPT_CBC) 51 | scc = File.open(SCC2, "r+") 52 | scc.ioctl(SET_MODE, mode) 53 | scc.ioctl(SET_IV, iv.dup) 54 | 55 | scc.write(tv) 56 | scc.read(tv.size) 57 | ensure 58 | scc.close unless scc.nil? 59 | end 60 | 61 | unless File.readable?(SCC2) and File.writable?(SCC2) 62 | puts "cannot access #{SCC2}, aborting" 63 | exit(1) 64 | end 65 | 66 | puts "NIST test AES-256 key: #{KEY[0..31]}" 67 | puts " #{KEY[32..63]}" 68 | puts "initialization vector: #{IV}" 69 | puts "test vector: #{TV}" 70 | puts "\n" 71 | 72 | key = hex_to_bin(KEY) 73 | iv = hex_to_bin(IV) 74 | tv = hex_to_bin(TV) 75 | 76 | openssl_enc = openssl_cipher(key, iv, tv * 2, :encrypt) 77 | scc_enc = scc_cipher(key, iv, tv * 2, ENCRYPT_CBC) 78 | 79 | openssl_dec = openssl_cipher(key, iv, openssl_enc, :decrypt) 80 | scc_dec = scc_cipher(key, iv, scc_enc, DECRYPT_CBC) 81 | 82 | puts "ciphertext block 1 (OpenSSL): #{bin_to_hex(openssl_enc[0..15])}" 83 | puts "ciphertext block 1 (SCCv2): #{bin_to_hex(scc_enc[0..15])}" 84 | puts "ciphertext block 2 (OpenSSL): #{bin_to_hex(openssl_enc[16..31])}" 85 | puts "ciphertext block 2 (SCCv2): #{bin_to_hex(scc_enc[16..31])}" 86 | puts "\t#{(openssl_enc == scc_enc) ? 'match!' : 'mismatch! (HAB on?)'}" 87 | puts "\n" 88 | 89 | puts " plaintext block 1 (OpenSSL): #{bin_to_hex(openssl_dec[0..15])}" 90 | puts " plaintext block 1 (SCCv2): #{bin_to_hex(scc_dec[0..15])}" 91 | puts " plaintext block 2 (OpenSSL): #{bin_to_hex(openssl_dec[16..31])}" 92 | puts " plaintext block 2 (SCCv2): #{bin_to_hex(scc_dec[16..31])}" 93 | puts "\t#{(openssl_dec == scc_dec) ? 'match!' : 'mismatch! (HAB on?)'}" 94 | --------------------------------------------------------------------------------