Revert "[ubicom32] remove kernel patch for now since it is incomplete and has some...
authorFelix Fietkau <nbd@openwrt.org>
Wed, 26 Aug 2009 22:46:30 +0000 (22:46 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 26 Aug 2009 22:46:30 +0000 (22:46 +0000)
There are no licensing issues with this patch

SVN-Revision: 17416

target/linux/ubicom32/Makefile
target/linux/ubicom32/patches-2.6.28/100-ubicom32_support.patch [new file with mode: 0644]

index 2901e28..fb181d6 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2006-2009 OpenWrt.org
+# Copyright (C) 2006-2008 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -13,7 +13,6 @@ ARCH:=ubicom32
 BOARD:=ubicom32
 BOARDNAME:=Ubicom IPxx
 FEATURES:=nommu ramdisk
-CFLAGS:=-Os -pipe -march=ubicom32v4 -funit-at-a-time
 
 LINUX_VERSION:=2.6.28.10
 
diff --git a/target/linux/ubicom32/patches-2.6.28/100-ubicom32_support.patch b/target/linux/ubicom32/patches-2.6.28/100-ubicom32_support.patch
new file mode 100644 (file)
index 0000000..4ec511f
--- /dev/null
@@ -0,0 +1,48922 @@
+--- /dev/null
++++ b/arch/ubicom32/crypto/aes_ubicom32.c
+@@ -0,0 +1,458 @@
++/*
++ * arch/ubicom32/crypto/aes_ubicom32.c
++ *   Ubicom32 implementation of the AES Cipher Algorithm.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#include <crypto/aes.h>
++#include <crypto/algapi.h>
++#include <linux/err.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/spinlock.h>
++#include "crypto_ubicom32.h"
++#include <asm/linkage.h>
++
++struct ubicom32_aes_ctx {
++      u8 key[AES_MAX_KEY_SIZE];
++      u32 ctrl;
++      int key_len;
++};
++
++static inline void aes_hw_set_key(const u8 *key, u8 key_len)
++{
++      /*
++       * switch case has more overhead than 4 move.4 instructions, so just copy 256 bits
++       */
++      SEC_SET_KEY_256(key);
++}
++
++static inline void aes_hw_set_iv(const u8 *iv)
++{
++      SEC_SET_IV_4W(iv);
++}
++
++static inline void aes_hw_cipher(u8 *out, const u8 *in)
++{
++      SEC_SET_INPUT_4W(in);
++
++      asm volatile (                                                
++      "       ; start AES by writing 0x40(SECURITY_BASE)      \n\t" 
++      "       move.4 0x40(%0), #0x01                          \n\t" 
++      "       pipe_flush 0                                    \n\t" 
++      "                                                       \n\t" 
++      "       ; wait for the module to calculate the output   \n\t" 
++      "       btst 0x04(%0), #0                               \n\t" 
++      "       jmpne.f .-4                                     \n\t" 
++              :                                                             
++              : "a" (SEC_BASE)                                                      
++              : "cc"
++      );
++      
++      SEC_GET_OUTPUT_4W(out);
++}
++
++static int __ocm_text aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
++                     unsigned int key_len)
++{
++      struct ubicom32_aes_ctx *uctx = crypto_tfm_ctx(tfm);
++
++      uctx->key_len = key_len;
++      memcpy(uctx->key, in_key, key_len);
++
++      /*
++       * leave out HASH_ALG (none = 0), CBC (no = 0), DIR (unknown) yet
++       */
++      switch (uctx->key_len) {
++      case 16:
++              uctx->ctrl = SEC_KEY_128_BITS | SEC_ALG_AES;
++              break;
++      case 24:
++              uctx->ctrl = SEC_KEY_192_BITS | SEC_ALG_AES;
++              break;
++      case 32:
++              uctx->ctrl = SEC_KEY_256_BITS | SEC_ALG_AES;
++              break;
++      }
++
++      return 0;
++}
++
++static inline void aes_cipher(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
++{
++      const struct ubicom32_aes_ctx *uctx = crypto_tfm_ctx(tfm);
++
++      hw_crypto_lock();
++      hw_crypto_check();
++      hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
++
++      aes_hw_set_key(uctx->key, uctx->key_len);
++      aes_hw_cipher(out, in);
++
++      hw_crypto_unlock();     
++}
++
++static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++      aes_cipher(tfm, out, in, SEC_DIR_ENCRYPT);
++}
++
++static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++      aes_cipher(tfm, out, in, SEC_DIR_DECRYPT);
++}
++
++static struct crypto_alg aes_alg = {
++      .cra_name               =       "aes",
++      .cra_driver_name        =       "aes-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER, 
++      .cra_blocksize          =       AES_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_aes_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(aes_alg.cra_list),
++      .cra_u                  =       {
++              .cipher = {
++                      .cia_min_keysize        =       AES_MIN_KEY_SIZE,
++                      .cia_max_keysize        =       AES_MAX_KEY_SIZE,
++                      .cia_setkey             =       aes_set_key,
++                      .cia_encrypt            =       aes_encrypt,
++                      .cia_decrypt            =       aes_decrypt,
++              }
++      }
++};
++
++static void __ocm_text ecb_aes_crypt_loop(u8 *out, u8 *in, unsigned int n)
++{
++      while (likely(n)) {
++              aes_hw_cipher(out, in);
++              out += AES_BLOCK_SIZE;
++              in += AES_BLOCK_SIZE;
++              n -= AES_BLOCK_SIZE;
++      }
++}
++
++static int __ocm_text ecb_aes_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, 
++                       struct scatterlist *src, unsigned int nbytes, u32 extra_flags)
++{
++      const struct ubicom32_aes_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
++      int ret;
++      
++      struct blkcipher_walk walk;
++      blkcipher_walk_init(&walk, dst, src, nbytes);
++      ret = blkcipher_walk_virt(desc, &walk);
++        if (ret) {
++                return ret;
++        }
++
++      hw_crypto_lock();
++      hw_crypto_check();
++
++        hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
++        aes_hw_set_key(uctx->key, uctx->key_len);
++      
++      while (likely((nbytes = walk.nbytes))) {
++              /* only use complete blocks */
++              unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
++              u8 *out = walk.dst.virt.addr;
++              u8 *in = walk.src.virt.addr;
++
++              /* finish n/16 blocks */
++              ecb_aes_crypt_loop(out, in, n);
++              
++              nbytes &= AES_BLOCK_SIZE - 1;
++              ret = blkcipher_walk_done(desc, &walk, nbytes);
++      }
++
++      hw_crypto_unlock();
++      return ret;
++}
++
++static int ecb_aes_encrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return ecb_aes_crypt(desc, dst, src, nbytes, SEC_DIR_ENCRYPT);
++}
++
++static int ecb_aes_decrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return ecb_aes_crypt(desc, dst, src, nbytes, SEC_DIR_DECRYPT);
++}
++
++static struct crypto_alg ecb_aes_alg = {
++      .cra_name               =       "ecb(aes)",
++      .cra_driver_name        =       "ecb-aes-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER, 
++      .cra_blocksize          =       AES_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_aes_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_type               =       &crypto_blkcipher_type,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(ecb_aes_alg.cra_list),
++      .cra_u                  =       {
++              .blkcipher = {
++                      .min_keysize            =       AES_MIN_KEY_SIZE,
++                      .max_keysize            =       AES_MAX_KEY_SIZE,
++                      .setkey                 =       aes_set_key,
++                      .encrypt                =       ecb_aes_encrypt,
++                      .decrypt                =       ecb_aes_decrypt,
++              }
++      }
++};
++
++#if CRYPTO_UBICOM32_LOOP_ASM 
++void __ocm_text cbc_aes_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      asm volatile (
++      "; set init. iv 4w                      \n\t"
++      "       move.4 0x50(%0), 0x0(%3)        \n\t"
++      "       move.4 0x54(%0), 0x4(%3)        \n\t"
++      "       move.4 0x58(%0), 0x8(%3)        \n\t"
++      "       move.4 0x5c(%0), 0xc(%3)        \n\t"
++      "                                       \n\t"
++      "; we know n > 0, so we can always      \n\t"
++      "; load the first block                 \n\t"
++      "; set input 4w                         \n\t"
++      "       move.4 0x30(%0), 0x0(%2)        \n\t"
++      "       move.4 0x34(%0), 0x4(%2)        \n\t"
++      "       move.4 0x38(%0), 0x8(%2)        \n\t"
++      "       move.4 0x3c(%0), 0xc(%2)        \n\t"
++      "                                       \n\t"
++      "; kickoff hw                           \n\t"
++      "       move.4 0x40(%0), %2             \n\t"
++      "                                       \n\t"
++      "; update n & flush                     \n\t"
++      "       add.4 %4, #-16, %4              \n\t"
++      "       pipe_flush 0                    \n\t"
++      "                                       \n\t"
++      "; while (n):  work on 2nd block        \n\t"
++      " 1:    lsl.4 d15, %4, #0x0             \n\t"
++      "       jmpeq.f 5f                      \n\t"
++      "                                       \n\t"
++      "; set input 4w (2nd)                   \n\t"
++      "       move.4 0x30(%0), 0x10(%2)       \n\t"
++      "       move.4 0x34(%0), 0x14(%2)       \n\t"
++      "       move.4 0x38(%0), 0x18(%2)       \n\t"
++      "       move.4 0x3c(%0), 0x1c(%2)       \n\t"
++      "                                       \n\t"
++      "; update n/in asap while waiting       \n\t"
++      "       add.4 %4, #-16, %4              \n\t"
++      "       move.4 d15, 16(%2)++            \n\t"
++      "                                       \n\t"
++      "; wait for the previous output         \n\t"
++      "       btst 0x04(%0), #0               \n\t"
++      "       jmpne.f -4                      \n\t"
++      "                                       \n\t"
++      "; read previous output                 \n\t"
++      "       move.4 0x0(%1), 0x50(%0)        \n\t"
++      "       move.4 0x4(%1), 0x54(%0)        \n\t"
++      "       move.4 0x8(%1), 0x58(%0)        \n\t"
++      "       move.4 0xc(%1), 0x5c(%0)        \n\t"
++      "                                       \n\t"
++      "; kick off hw for 2nd input            \n\t"
++      "       move.4 0x40(%0), %2             \n\t"
++      "                                       \n\t"
++      "; update out asap                      \n\t"
++      "       move.4 d15, 16(%1)++            \n\t"
++      "                                       \n\t"
++      "; go back to loop                      \n\t"
++      "       jmpt 1b                         \n\t"
++      "                                       \n\t"
++      "; wait for last output                 \n\t" 
++      " 5:    btst 0x04(%0), #0               \n\t"
++        "       jmpne.f -4                      \n\t"
++        "                                       \n\t"
++      "; read last output                     \n\t"
++      "       move.4 0x0(%1), 0x50(%0)        \n\t"
++      "       move.4 0x4(%1), 0x54(%0)        \n\t"
++      "       move.4 0x8(%1), 0x58(%0)        \n\t"
++      "       move.4 0xc(%1), 0x5c(%0)        \n\t"
++        "                                       \n\t"
++      "; copy out iv                          \n\t"
++      "       move.4 0x0(%3), 0x50(%0)        \n\t"
++      "       move.4 0x4(%3), 0x54(%0)        \n\t"
++      "       move.4 0x8(%3), 0x58(%0)        \n\t"
++      "       move.4 0xc(%3), 0x5c(%0)        \n\t"
++        "                                       \n\t"
++              :
++              : "a" (SEC_BASE), "a" (out), "a" (in), "a" (iv), "d" (n)
++              : "d15", "cc"
++      );
++}
++
++#else
++
++static void __ocm_text cbc_aes_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      aes_hw_set_iv(iv);
++      while (likely(n)) {
++              aes_hw_cipher(out, in);
++              out += AES_BLOCK_SIZE;
++              in += AES_BLOCK_SIZE;
++              n -= AES_BLOCK_SIZE;    
++      }
++      SEC_COPY_4W(iv, out - AES_BLOCK_SIZE);
++}
++
++#endif
++
++static void __ocm_text cbc_aes_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++        while (likely(n)) {
++                aes_hw_set_iv(iv);
++              SEC_COPY_4W(iv, in);
++                aes_hw_cipher(out, in);
++                out += AES_BLOCK_SIZE;
++                in += AES_BLOCK_SIZE;
++                n -= AES_BLOCK_SIZE;
++        }
++}
++
++static int __ocm_text cbc_aes_crypt(struct blkcipher_desc *desc, 
++                           struct scatterlist *dst, struct scatterlist *src,
++                           unsigned int nbytes, u32 extra_flags)
++{
++      struct ubicom32_aes_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
++      int ret;
++
++        struct blkcipher_walk walk;
++        blkcipher_walk_init(&walk, dst, src, nbytes);
++      ret = blkcipher_walk_virt(desc, &walk);
++      if (unlikely(ret)) {
++              return ret;
++      }
++      
++        hw_crypto_lock();
++      hw_crypto_check();
++
++        hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
++        aes_hw_set_key(uctx->key, uctx->key_len);
++
++      while (likely((nbytes = walk.nbytes))) {
++                /* only use complete blocks */
++                unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
++              if (likely(n)) {
++                      u8 *out = walk.dst.virt.addr;
++                      u8 *in = walk.src.virt.addr;
++
++                      if (extra_flags & SEC_DIR_ENCRYPT) {
++                              cbc_aes_encrypt_loop(out, in, walk.iv, n);
++                      } else {
++                              cbc_aes_decrypt_loop(out, in, walk.iv, n);
++                      }
++              }
++
++              nbytes &= AES_BLOCK_SIZE - 1;
++                ret = blkcipher_walk_done(desc, &walk, nbytes);
++      }
++      hw_crypto_unlock();
++
++      return ret;
++}
++
++static int __ocm_text cbc_aes_encrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return cbc_aes_crypt(desc, dst, src, nbytes, SEC_DIR_ENCRYPT | SEC_CBC_SET);
++}
++
++static int __ocm_text cbc_aes_decrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return cbc_aes_crypt(desc, dst, src, nbytes, SEC_DIR_DECRYPT | SEC_CBC_SET);
++}
++
++static struct crypto_alg cbc_aes_alg = {
++      .cra_name               =       "cbc(aes)",
++      .cra_driver_name        =       "cbc-aes-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER, 
++      .cra_blocksize          =       AES_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_aes_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_type               =       &crypto_blkcipher_type,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(cbc_aes_alg.cra_list),
++      .cra_u                  =       {
++              .blkcipher = {
++                      .min_keysize            =       AES_MIN_KEY_SIZE,
++                      .max_keysize            =       AES_MAX_KEY_SIZE,
++                      .ivsize                 =       AES_BLOCK_SIZE,
++                      .setkey                 =       aes_set_key,
++                      .encrypt                =       cbc_aes_encrypt,
++                      .decrypt                =       cbc_aes_decrypt,
++              }
++      }
++};
++
++static int __init aes_init(void)
++{
++      int ret;
++
++      hw_crypto_init();
++
++      ret = crypto_register_alg(&aes_alg);
++      if (ret)
++              goto aes_err;
++
++      ret = crypto_register_alg(&ecb_aes_alg);
++      if (ret)
++              goto ecb_aes_err;
++
++      ret = crypto_register_alg(&cbc_aes_alg);
++      if (ret)
++              goto cbc_aes_err;
++
++out:
++      return ret;
++
++cbc_aes_err:
++      crypto_unregister_alg(&ecb_aes_alg);
++ecb_aes_err:
++      crypto_unregister_alg(&aes_alg);
++aes_err:
++      goto out;
++}
++
++static void __exit aes_fini(void)
++{
++      crypto_unregister_alg(&cbc_aes_alg);
++      crypto_unregister_alg(&ecb_aes_alg);
++      crypto_unregister_alg(&aes_alg);
++}
++
++module_init(aes_init);
++module_exit(aes_fini);
++
++MODULE_ALIAS("aes");
++
++MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/arch/ubicom32/crypto/crypto_des.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/crypto/crypto_des.h
++ *   Function for checking keys for the DES and Triple DES Encryption
++ *   algorithms.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef __CRYPTO_DES_H__
++#define __CRYPTO_DES_H__
++
++extern int crypto_des_check_key(const u8*, unsigned int, u32*);
++
++#endif /* __CRYPTO_DES_H__ */
+--- /dev/null
++++ b/arch/ubicom32/crypto/crypto_ubicom32.c
+@@ -0,0 +1,50 @@
++/*
++ * arch/ubicom32/crypto/crypto_ubicom32.c
++ *   Generic code to support ubicom32 hardware crypto accelerator
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#include "crypto_ubicom32.h"
++
++spinlock_t crypto_ubicom32_lock;
++bool crypto_ubicom32_inited = false;
++volatile bool crypto_ubicom32_on = false;
++volatile unsigned long crypto_ubicom32_last_use;
++
++struct timer_list crypto_ubicom32_ps_timer;
++void crypto_ubicom32_ps_check(unsigned long data)
++{
++      unsigned long idle_time = msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS);
++
++      BUG_ON(!crypto_ubicom32_on);
++
++      if (((jiffies - crypto_ubicom32_last_use) > idle_time) && spin_trylock_bh(&crypto_ubicom32_lock)) {
++                hw_crypto_turn_off();
++                spin_unlock_bh(&crypto_ubicom32_lock);
++              return;
++      }
++
++      /* keep monitoring */
++      hw_crypto_ps_start();
++}
+--- /dev/null
++++ b/arch/ubicom32/crypto/crypto_ubicom32.h
+@@ -0,0 +1,346 @@
++/*
++ * arch/ubicom32/crypto/crypto_ubicom32.h
++ *   Support for Ubicom32 cryptographic instructions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _CRYPTO_ARCH_UBICOM32_CRYPT_H
++#define _CRYPTO_ARCH_UBICOM32_CRYPT_H
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/jiffies.h>
++#include <linux/timer.h>
++#include <linux/spinlock.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/ip5000.h>
++
++#define CRYPTO_UBICOM32_LOOP_ASM 1
++#define CRYPTO_UBICOM32_ALIGNMENT 4
++#define SEC_ALIGNED(p) (((u32)p & 3) == 0)
++
++#define SEC_BASE              SECURITY_BASE
++#define SEC_KEY_OFFSET                SECURITY_KEY_VALUE(0)
++#define SEC_INPUT_OFFSET      SECURITY_KEY_IN(0)
++#define SEC_OUTPUT_OFFSET     SECURITY_KEY_OUT(0)
++#define SEC_HASH_OFFSET               SECURITY_KEY_HASH(0)
++
++#define SEC_KEY_128_BITS      SECURITY_CTRL_KEY_SIZE(0)
++#define SEC_KEY_192_BITS      SECURITY_CTRL_KEY_SIZE(1)
++#define SEC_KEY_256_BITS      SECURITY_CTRL_KEY_SIZE(2)
++
++#define SEC_HASH_NONE         SECURITY_CTRL_HASH_ALG_NONE
++#define SEC_HASH_MD5          SECURITY_CTRL_HASH_ALG_MD5
++#define SEC_HASH_SHA1         SECURITY_CTRL_HASH_ALG_SHA1
++
++#define SEC_CBC_SET           SECURITY_CTRL_CBC
++#define SEC_CBC_NONE          0
++
++#define SEC_ALG_AES           SECURITY_CTRL_CIPHER_ALG_AES
++#define SEC_ALG_NONE          SECURITY_CTRL_CIPHER_ALG_NONE
++#define SEC_ALG_DES           SECURITY_CTRL_CIPHER_ALG_DES
++#define SEC_ALG_3DES          SECURITY_CTRL_CIPHER_ALG_3DES
++
++#define SEC_DIR_ENCRYPT               SECURITY_CTRL_ENCIPHER
++#define SEC_DIR_DECRYPT               0
++
++#define CRYPTO_UBICOM32_PRIORITY 300
++#define CRYPTO_UBICOM32_COMPOSITE_PRIORITY 400
++
++#define HW_CRYPTO_PS_MAX_IDLE_MS 100    /* idle time (ms) before shuting down sm */
++
++extern spinlock_t crypto_ubicom32_lock;
++extern bool crypto_ubicom32_inited;
++extern volatile bool crypto_ubicom32_on;
++extern volatile unsigned long crypto_ubicom32_last_use;
++extern struct timer_list crypto_ubicom32_ps_timer;
++extern void crypto_ubicom32_ps_check(unsigned long data);
++
++#define SEC_COPY_2W(t, s)                             \
++      asm volatile (                                  \
++      "       move.4 0(%0), 0(%1)             \n\t"   \
++      "       move.4 4(%0), 4(%1)             \n\t"   \
++                                                      \
++              :                                       \
++              : "a" (t), "a" (s)                      \
++      )
++
++#define SEC_COPY_4W(t, s)                             \
++      asm volatile (                                  \
++      "       move.4 0(%0), 0(%1)             \n\t"   \
++      "       move.4 4(%0), 4(%1)             \n\t"   \
++      "       move.4 8(%0), 8(%1)             \n\t"   \
++      "       move.4 12(%0), 12(%1)           \n\t"   \
++              :                                       \
++              : "a" (t), "a" (s)                      \
++      )
++
++#define SEC_COPY_5W(t, s)                             \
++      asm volatile (                                  \
++      "       move.4 0(%0), 0(%1)             \n\t"   \
++      "       move.4 4(%0), 4(%1)             \n\t"   \
++      "       move.4 8(%0), 8(%1)             \n\t"   \
++      "       move.4 12(%0), 12(%1)           \n\t"   \
++      "       move.4 16(%0), 16(%1)           \n\t"   \
++              :                                       \
++              : "a" (t), "a" (s)                      \
++      )
++
++#define SEC_SET_KEY_2W(x)                             \
++      asm volatile (                                  \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0x10(%0), 0(%1)          \n\t"   \
++      "       move.4 0x14(%0), 4(%1)          \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_SET_KEY_4W(x) \
++      asm volatile ( \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0x10(%0), 0(%1)          \n\t"   \
++      "       move.4 0x14(%0), 4(%1)          \n\t"   \
++      "       move.4 0x18(%0), 8(%1)          \n\t"   \
++      "       move.4 0x1c(%0), 12(%1)         \n\t"   \
++              :                                       \
++              : "a"(SECURITY_BASE), "a"(x)            \
++      )
++
++#define SEC_SET_KEY_6W(x)                             \
++      asm volatile (                                  \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0x10(%0), 0(%1)          \n\t"   \
++      "       move.4 0x14(%0), 4(%1)          \n\t"   \
++      "       move.4 0x18(%0), 8(%1)          \n\t"   \
++      "       move.4 0x1c(%0), 12(%1)         \n\t"   \
++      "       move.4 0x20(%0), 16(%1)         \n\t"   \
++      "       move.4 0x24(%0), 20(%1)         \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_SET_KEY_8W(x)                             \
++      asm volatile (                                  \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0x10(%0), 0(%1)          \n\t"   \
++      "       move.4 0x14(%0), 4(%1)          \n\t"   \
++      "       move.4 0x18(%0), 8(%1)          \n\t"   \
++      "       move.4 0x1c(%0), 12(%1)         \n\t"   \
++      "       move.4 0x20(%0), 16(%1)         \n\t"   \
++      "       move.4 0x24(%0), 20(%1)         \n\t"   \
++      "       move.4 0x28(%0), 24(%1)         \n\t"   \
++      "       move.4 0x2c(%0), 28(%1)         \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_SET_KEY_64(k)     SEC_SET_KEY_2W(k)
++#define SEC_SET_KEY_128(k)    SEC_SET_KEY_4W(k)
++#define SEC_SET_KEY_192(k)    SEC_SET_KEY_6W(k)
++#define SEC_SET_KEY_256(k)    SEC_SET_KEY_8W(k)
++
++#define DES_SET_KEY(x)                SEC_SET_KEY_64(x) 
++#define DES3_SET_KEY(x)       SEC_SET_KEY_192(x)
++
++#define SEC_SET_INPUT_2W(x)                           \
++      asm volatile (                                  \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0x30(%0), 0(%1)          \n\t"   \
++      "       move.4 0x34(%0), 4(%1)          \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_GET_OUTPUT_2W(x)                          \
++      asm volatile (                                  \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0(%1), 0x50(%0)          \n\t"   \
++      "       move.4 4(%1), 0x54(%0)          \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_SET_INPUT_4W(x) \
++      asm volatile ( \
++      "       ; write key to Security Keyblock \n\t"  \
++      "       move.4 0x30(%0), 0(%1)          \n\t"   \
++      "       move.4 0x34(%0), 4(%1)          \n\t"   \
++      "       move.4 0x38(%0), 8(%1)          \n\t"   \
++      "       move.4 0x3c(%0), 12(%1)         \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_GET_OUTPUT_4W(x)                          \
++      asm volatile (                                  \
++      "       ; read output from Security Keyblock \n\t" \
++      "       move.4 0(%1), 0x50(%0)          \n\t"   \
++      "       move.4 4(%1), 0x54(%0)          \n\t"   \
++      "       move.4 8(%1), 0x58(%0)          \n\t"   \
++      "       move.4 12(%1), 0x5c(%0)         \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_SET_IV_4W(x)                              \
++      asm volatile (                                  \
++      "       ; write IV to Security Keyblock  \n\t"  \
++      "       move.4 0x50(%0), 0(%1)          \n\t"   \
++      "       move.4 0x54(%0), 4(%1)          \n\t"   \
++      "       move.4 0x58(%0), 8(%1)          \n\t"   \
++      "       move.4 0x5c(%0), 12(%1)         \n\t"   \
++              :                                       \
++              : "a" (SECURITY_BASE), "a" (x)          \
++      )
++
++#define SEC_PIPE_FLUSH() asm volatile ( " pipe_flush 0 \n\t" )
++
++static inline void hw_crypto_set_ctrl(uint32_t c)
++{
++      asm volatile (                                  
++      "       move.4  0(%0), %1               \n\t"   
++              :                                       
++              : "a" (SECURITY_BASE + SECURITY_CTRL), "d" (c)  
++      );
++}
++
++static inline void hw_crypto_ps_start(void)
++{
++      crypto_ubicom32_ps_timer.expires = jiffies + msecs_to_jiffies(HW_CRYPTO_PS_MAX_IDLE_MS >> 1);
++      add_timer(&crypto_ubicom32_ps_timer);
++}
++
++static inline void hw_crypto_turn_on(void)
++{
++      asm volatile (                            
++      "       moveai  A4, %0                  \n\t" 
++      "       bset    0x0(A4), 0x0(A4), %1    \n\t"
++      "       cycles 11                       \n\t" 
++              :                                               
++              : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO) 
++              : "a4", "cc"
++      );
++      crypto_ubicom32_on = true;
++}
++
++static inline void hw_crypto_turn_off(void)
++{
++      asm volatile (                            
++      "       moveai  A4, %0                  \n\t" 
++      "       bclr    0x0(A4), 0x0(A4), %1    \n\t" 
++              :                                               
++              : "i" (OCP_BASE >> 7), "i" (GEN_CLK_PLL_SECURITY_BIT_NO)    
++              : "a4", "cc"
++      );
++      crypto_ubicom32_on = false;
++}
++
++/*
++ * hw_crypto_check
++ *    Most probably hw crypto is called in clusters and it makes no sense to turn it off
++ *    and on and waster 13 cycles every time.
++ */
++static inline void hw_crypto_check(void)
++{
++      if (likely(crypto_ubicom32_on)) {
++              return;
++      }
++      crypto_ubicom32_last_use = jiffies;
++      hw_crypto_turn_on();
++      hw_crypto_ps_start();
++}
++
++/*
++ * hw_crypto_ps_init
++ *    Init power save timer
++ */
++static inline void hw_crypto_ps_init(void)
++{
++      init_timer_deferrable(&crypto_ubicom32_ps_timer);
++      crypto_ubicom32_ps_timer.function = crypto_ubicom32_ps_check;
++      crypto_ubicom32_ps_timer.data = 0;
++}
++
++/*
++ * hw_crypto_init()
++ *      Initialize OCP security module lock and disables its clock.
++ */
++static inline void hw_crypto_init(void)
++{
++      if (!crypto_ubicom32_inited) {
++              crypto_ubicom32_inited = true;
++              spin_lock_init(&crypto_ubicom32_lock);
++              hw_crypto_ps_init();
++              hw_crypto_turn_off();
++      }
++}
++
++/*
++ * hw_crypto_lock()
++ *      Locks the OCP security module and enables its clock.
++ */
++static inline void hw_crypto_lock(void)
++{
++      spin_lock_bh(&crypto_ubicom32_lock);
++}
++
++/*
++ * hw_crypto_unlock()
++ *      Unlocks the OCP security module and disables its clock.
++ */
++static inline void hw_crypto_unlock(void)
++{
++      crypto_ubicom32_last_use = jiffies;
++      spin_unlock_bh(&crypto_ubicom32_lock);
++}
++
++#define CONFIG_CRYPTO_UBICOM32_DEBUG 1
++
++#ifdef CONFIG_CRYPTO_UBICOM32_DEBUG
++static inline void hex_dump(void *buf, int b_size, const char *msg)
++{
++      u8 *b = (u8 *)buf;
++      int i;
++      if (msg) {
++              printk("%s:\t", msg);
++      }
++
++      for (i=0; i < b_size; i++) {
++              printk("%02x ", b[i]);
++              if ((i & 3) == 3) {
++                      printk(" ");
++              }
++              if ((i & 31) == 31) {
++                      printk("\n");
++              }
++      }
++      printk("\n");
++}
++#define UBICOM32_SEC_DUMP(a, b, c) hex_dump(a, b, c)
++#else
++#define UBICOM32_SEC_DUMP(a, b, c)
++#endif
++
++#endif        /* _CRYPTO_ARCH_UBICOM32_CRYPT_H */
+--- /dev/null
++++ b/arch/ubicom32/crypto/des_check_key.c
+@@ -0,0 +1,148 @@
++/*
++ * arch/ubicom32/crypto/des_check_key.c
++ *   Ubicom32 architecture function for checking keys for the DES and
++ *   Tripple DES Encryption algorithms.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
++ * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
++ * Derived from Cryptoapi and Nettle implementations, adapted for in-place
++ * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
++ *
++ * s390 Version:
++ *   Copyright IBM Corp. 2003
++ *   Author(s): Thomas Spatzier
++ *            Jan Glauber (jan.glauber@de.ibm.com)
++ *
++ * Derived from "crypto/des.c"
++ *   Copyright (c) 1992 Dana L. How.
++ *   Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de>
++ *   Copyright (c) Gisle Sflensminde <gisle@ii.uib.no>
++ *   Copyright (C) 2001 Niels Mvller.
++ *   Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/crypto.h>
++#include "crypto_des.h"
++
++#define ROR(d,c,o)    ((d) = (d) >> (c) | (d) << (o))
++
++static const u8 parity[] = {
++      8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
++      0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
++      0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
++      8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
++      0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
++      8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
++      8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
++      4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
++};
++
++/*
++ * RFC2451: Weak key checks SHOULD be performed.
++ */
++int
++crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags)
++{
++      u32 n, w;
++
++      n  = parity[key[0]]; n <<= 4;
++      n |= parity[key[1]]; n <<= 4;
++      n |= parity[key[2]]; n <<= 4;
++      n |= parity[key[3]]; n <<= 4;
++      n |= parity[key[4]]; n <<= 4;
++      n |= parity[key[5]]; n <<= 4;
++      n |= parity[key[6]]; n <<= 4;
++      n |= parity[key[7]];
++      w = 0x88888888L;
++
++      if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
++          && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
++              if (n < 0x41415151) {
++                      if (n < 0x31312121) {
++                              if (n < 0x14141515) {
++                                      /* 01 01 01 01 01 01 01 01 */
++                                      if (n == 0x11111111) goto weak;
++                                      /* 01 1F 01 1F 01 0E 01 0E */
++                                      if (n == 0x13131212) goto weak;
++                              } else {
++                                      /* 01 E0 01 E0 01 F1 01 F1 */
++                                      if (n == 0x14141515) goto weak;
++                                      /* 01 FE 01 FE 01 FE 01 FE */
++                                      if (n == 0x16161616) goto weak;
++                              }
++                      } else {
++                              if (n < 0x34342525) {
++                                      /* 1F 01 1F 01 0E 01 0E 01 */
++                                      if (n == 0x31312121) goto weak;
++                                      /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
++                                      if (n == 0x33332222) goto weak;
++                              } else {
++                                      /* 1F E0 1F E0 0E F1 0E F1 */
++                                      if (n == 0x34342525) goto weak;
++                                      /* 1F FE 1F FE 0E FE 0E FE */
++                                      if (n == 0x36362626) goto weak;
++                              }
++                      }
++              } else {
++                      if (n < 0x61616161) {
++                              if (n < 0x44445555) {
++                                      /* E0 01 E0 01 F1 01 F1 01 */
++                                      if (n == 0x41415151) goto weak;
++                                      /* E0 1F E0 1F F1 0E F1 0E */
++                                      if (n == 0x43435252) goto weak;
++                              } else {
++                                      /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
++                                      if (n == 0x44445555) goto weak;
++                                      /* E0 FE E0 FE F1 FE F1 FE */
++                                      if (n == 0x46465656) goto weak;
++                              }
++                      } else {
++                              if (n < 0x64646565) {
++                                      /* FE 01 FE 01 FE 01 FE 01 */
++                                      if (n == 0x61616161) goto weak;
++                                      /* FE 1F FE 1F FE 0E FE 0E */
++                                      if (n == 0x63636262) goto weak;
++                              } else {
++                                      /* FE E0 FE E0 FE F1 FE F1 */
++                                      if (n == 0x64646565) goto weak;
++                                      /* FE FE FE FE FE FE FE FE */
++                                      if (n == 0x66666666) goto weak;
++                              }
++                      }
++              }
++      }
++      return 0;
++weak:
++      *flags |= CRYPTO_TFM_RES_WEAK_KEY;
++      return -EINVAL;
++}
++
++EXPORT_SYMBOL(crypto_des_check_key);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Key Check function for DES &  DES3 Cipher Algorithms");
+--- /dev/null
++++ b/arch/ubicom32/crypto/des_ubicom32.c
+@@ -0,0 +1,761 @@
++/*
++ * arch/ubicom32/crypto/des_ubicom32.c
++ *   Ubicom32 implementation of the DES Cipher Algorithm.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#include <crypto/algapi.h>
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include "crypto_ubicom32.h"
++extern int crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags);
++
++#define DES_BLOCK_SIZE 8
++#define DES_KEY_SIZE 8
++
++#define DES3_192_KEY_SIZE     (3 * DES_KEY_SIZE)
++#define DES3_192_BLOCK_SIZE   DES_BLOCK_SIZE
++
++#define DES3_SUB_KEY(key, i)  (((u8 *)key) + (i * DES_KEY_SIZE))
++
++enum des_ops {
++      DES_ENCRYPT,
++      DES_DECRYPT,
++
++      DES3_EDE_ENCRYPT,
++      DES3_EDE_DECRYPT,
++
++#ifdef DES3_EEE
++      DES3_EEE_ENCRYPT,
++      DES3_EEE_DECRYPT,
++#endif
++};
++
++struct ubicom32_des_ctx {
++      u8 key[3 * DES_KEY_SIZE];
++      u32 ctrl;
++      int key_len;
++};
++
++static inline void des_hw_set_key(const u8 *key, u8 key_len)
++{
++      /*
++       * HW 3DES is not tested yet, use DES just as ipOS
++       */
++      DES_SET_KEY(key);
++}
++
++static inline void des_hw_cipher(u8 *out, const u8 *in)
++{
++      SEC_SET_INPUT_2W(in);
++
++      asm volatile (
++      "       ; start DES by writing 0x38(SECURITY_BASE)      \n\t" 
++      "       move.4 0x38(%0), #0x01                          \n\t" 
++      "       pipe_flush 0                                    \n\t" 
++      "                                                       \n\t" 
++      "       ; wait for the module to calculate the output   \n\t" 
++      "       btst 0x04(%0), #0                               \n\t" 
++      "       jmpne.f .-4                                     \n\t" 
++              :
++              : "a" (SEC_BASE)
++              : "cc"
++      );
++      
++      SEC_GET_OUTPUT_2W(out);
++}
++
++
++static void inline des3_hw_ede_encrypt(u8 *keys, u8 *out, const u8 *in)
++{
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 0), DES_KEY_SIZE);
++      des_hw_cipher(out, in);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 1), DES_KEY_SIZE);
++      des_hw_cipher(out, out);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 2), DES_KEY_SIZE);
++      des_hw_cipher(out, out);
++}
++
++static void inline des3_hw_ede_decrypt(u8 *keys, u8 *out, const u8 *in)
++{
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 2), DES_KEY_SIZE);
++      des_hw_cipher(out, in);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 1), DES_KEY_SIZE);
++      des_hw_cipher(out, out);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 0), DES_KEY_SIZE);
++      des_hw_cipher(out, out);
++}
++
++#ifdef DES3_EEE
++static void inline des3_hw_eee_encrypt(u8 *keys, u8 *out, const u8 *in)
++{
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 0), 2);
++      des_hw_cipher(out, in);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 1), 2);
++      des_hw_cipher(out, out);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 2), 2);
++      des_hw_cipher(out, out);
++}
++
++static void inline des3_hw_eee_decrypt(u8 *keys, u8 *out, const u8 *in)
++{
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 2), 2);
++      des_hw_cipher(out, in);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 1), 2);
++      des_hw_cipher(out, out);
++
++      hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++      des_hw_set_key(DES3_SUB_KEY(keys, 0), 2);
++      des_hw_cipher(out, out);
++}
++#endif
++
++static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
++                    unsigned int keylen)
++{
++      struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
++      u32 *flags = &tfm->crt_flags;
++      int ret;
++
++      /* test if key is valid (not a weak key) */
++      ret = crypto_des_check_key(key, keylen, flags);
++      if (ret == 0) {
++              memcpy(dctx->key, key, keylen);
++              dctx->key_len = keylen;
++              //dctx->ctrl = (keylen == DES_KEY_SIZE) ? SEC_ALG_DES : SEC_ALG_3DES
++              /* 2DES and 3DES are both implemented with DES hw function */
++              dctx->ctrl = SEC_ALG_DES;
++      }
++      return ret;
++}
++
++static inline void des_cipher_1b(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
++{
++      const struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
++
++      hw_crypto_lock();
++      hw_crypto_check();
++      hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
++
++      des_hw_set_key(uctx->key, uctx->key_len);
++      des_hw_cipher(out, in);
++
++      hw_crypto_unlock();     
++}
++
++static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++      des_cipher_1b(tfm, out, in, SEC_DIR_ENCRYPT);
++}
++
++static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
++{
++      des_cipher_1b(tfm, out, in, SEC_DIR_DECRYPT);
++}
++
++static struct crypto_alg des_alg = {
++      .cra_name               =       "des",
++      .cra_driver_name        =       "des-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
++      .cra_blocksize          =       DES_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(des_alg.cra_list),
++      .cra_u                  = {
++              .cipher = {
++                      .cia_min_keysize        =       DES_KEY_SIZE,
++                      .cia_max_keysize        =       DES_KEY_SIZE,
++                      .cia_setkey             =       des_setkey,
++                      .cia_encrypt            =       des_encrypt,
++                      .cia_decrypt            =       des_decrypt,
++              }
++      }
++};
++
++static void ecb_des_ciper_loop(u8 *out, u8 *in, unsigned int n)
++{
++      while (likely(n)) {
++              des_hw_cipher(out, in);
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void ecb_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
++{
++      while (likely(n)) {
++              des3_hw_ede_encrypt(keys, out, in);
++              
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void ecb_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
++{
++      while (likely(n)) {
++              des3_hw_ede_decrypt(keys, out, in);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++#ifdef DES3_EEE
++static void ecb_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
++{
++      while (likely(n)) {
++              des3_hw_eee_encrypt(keys, out, in);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void ecb_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
++{
++      while (likely(n)) {
++              des3_hw_eee_decrypt(keys, out, in);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++#endif
++
++static inline void ecb_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, unsigned int n)
++{
++      switch (op) {
++      case DES_ENCRYPT:
++      case DES_DECRYPT:
++              /* set the right algo, direction and key once */
++              hw_crypto_set_ctrl(SEC_ALG_DES | (op == DES_ENCRYPT ? SEC_DIR_ENCRYPT : 0));
++              des_hw_set_key(uctx->key, uctx->key_len);
++              ecb_des_ciper_loop(out, in, n);
++              break;
++
++      case DES3_EDE_ENCRYPT:
++              ecb_des3_ede_encrypt_loop(uctx->key, out, in, n);
++              break;
++
++      case DES3_EDE_DECRYPT:
++              ecb_des3_ede_decrypt_loop(uctx->key, out, in, n);
++              break;
++
++#ifdef DES3_EEE
++      case DES3_EEE_ENCRYPT:
++              ecb_des3_eee_encrypt_loop(uctx->key, out, in, n);
++              break;
++
++      case DES3_EEE_DECRYPT:
++              ecb_des3_eee_decrypt_loop(uctx->key, out, in, n);
++              break;
++#endif
++      }
++}
++
++static inline void des_xor_2w(u32 *data, u32 *iv)
++{
++      data[0] ^= iv[0];
++      data[1] ^= iv[1];
++}
++
++static void cbc_des_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      while (likely(n)) {
++              des_xor_2w((u32 *)in, (u32 *)iv);
++              des_hw_cipher(out, in);
++              SEC_COPY_2W(iv, out);
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void cbc_des_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      u8 next_iv[DES_BLOCK_SIZE];
++      while (likely(n)) {
++              SEC_COPY_2W(next_iv, in);
++              des_hw_cipher(out, in);
++              des_xor_2w((u32 *)out, (u32 *)iv);
++              SEC_COPY_2W(iv, next_iv);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void cbc_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      while (likely(n)) {
++              des_xor_2w((u32 *)in, (u32 *)iv);
++              des3_hw_ede_encrypt(keys, out, in);
++              SEC_COPY_2W(iv, out);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void cbc_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      u8 next_iv[DES_BLOCK_SIZE];
++      while (likely(n)) {
++              SEC_COPY_2W(next_iv, in);
++              des3_hw_ede_decrypt(keys, out, in);
++              des_xor_2w((u32 *)out, (u32 *)iv);
++              SEC_COPY_2W(iv, next_iv);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++#ifdef DES3_EEE
++static void cbc_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      while (likely(n)) {
++              des_xor_2w((u32 *)in, (u32 *)iv);
++              des3_hw_eee_encrypt(keys, out, in);
++              SEC_COPY_2W(iv, out);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++
++static void cbc_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      u8 next_iv[DES_BLOCK_SIZE];
++      while (likely(n)) {
++              SEC_COPY_2W(next_iv, in);
++              des3_hw_eee_decrypt(keys, out, in);
++              des_xor_2w((u32 *)out, (u32 *)iv);
++              SEC_COPY_2W(iv, next_iv);
++
++              out += DES_BLOCK_SIZE;
++              in += DES_BLOCK_SIZE;
++              n -= DES_BLOCK_SIZE;
++      }
++}
++#endif
++
++static inline void cbc_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, u8 *iv, unsigned int n)
++{
++      switch (op) {
++      case DES_ENCRYPT:
++              hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
++              des_hw_set_key(uctx->key, uctx->key_len);
++              cbc_des_encrypt_loop(out, in, iv, n);
++              break;
++              
++      case DES_DECRYPT:
++              /* set the right algo, direction and key once */
++              hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
++              des_hw_set_key(uctx->key, uctx->key_len);
++              cbc_des_decrypt_loop(out, in, iv, n);
++              break;
++
++      case DES3_EDE_ENCRYPT:
++              cbc_des3_ede_encrypt_loop(uctx->key, out, in, iv, n);
++              break;
++
++      case DES3_EDE_DECRYPT:
++              cbc_des3_ede_decrypt_loop(uctx->key, out, in, iv, n);
++              break;
++
++#ifdef DES3_EEE
++      case DES3_EEE_ENCRYPT:
++              cbc_des3_eee_encrypt_loop(uctx->key, out, in, iv, n);
++              break;
++
++      case DES3_EEE_DECRYPT:
++              cbc_des3_eee_decrypt_loop(uctx->key, out, in, iv, n);
++              break;
++#endif
++      }
++}
++
++static int des_cipher(struct blkcipher_desc *desc, struct scatterlist *dst, 
++                    struct scatterlist *src, unsigned int nbytes, u32 extra_flags, enum des_ops op)
++{
++      struct ubicom32_des_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
++      int ret;
++      
++      struct blkcipher_walk walk;
++      blkcipher_walk_init(&walk, dst, src, nbytes);
++      ret = blkcipher_walk_virt(desc, &walk);
++      if (ret) {
++              return ret;
++      }
++
++      hw_crypto_lock();
++      hw_crypto_check();
++
++      while ((nbytes = walk.nbytes)) {
++              /* only use complete blocks */
++              unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
++              u8 *out = walk.dst.virt.addr;
++              u8 *in = walk.src.virt.addr;
++
++              /* finish n/16 blocks */
++              if (extra_flags & SEC_CBC_SET) {
++                      cbc_des_cipher_n(uctx, op, out, in, walk.iv, n);
++              } else {
++                      ecb_des_cipher_n(uctx, op, out, in, n);
++              }
++
++              nbytes &= DES_BLOCK_SIZE - 1;
++              ret = blkcipher_walk_done(desc, &walk, nbytes);
++      }
++
++      hw_crypto_unlock();
++      return ret;
++}
++
++static int ecb_des_encrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_ENCRYPT);
++}
++
++static int ecb_des_decrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_DECRYPT);
++}
++
++static struct crypto_alg ecb_des_alg = {
++      .cra_name               =       "ecb(des)",
++      .cra_driver_name        =       "ecb-des-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
++      .cra_blocksize          =       DES_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_type               =       &crypto_blkcipher_type,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(ecb_des_alg.cra_list),
++      .cra_u                  = {
++              .blkcipher = {
++                      .min_keysize            =       DES_KEY_SIZE,
++                      .max_keysize            =       DES_KEY_SIZE,
++                      .setkey                 =       des_setkey,
++                      .encrypt                =       ecb_des_encrypt,
++                      .decrypt                =       ecb_des_decrypt,
++              }
++      }
++};
++
++static int cbc_des_encrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_ENCRYPT);
++}
++
++static int cbc_des_decrypt(struct blkcipher_desc *desc,
++                         struct scatterlist *dst, struct scatterlist *src,
++                         unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_DECRYPT);
++}
++
++static struct crypto_alg cbc_des_alg = {
++      .cra_name               =       "cbc(des)",
++      .cra_driver_name        =       "cbc-des-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
++      .cra_blocksize          =       DES_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_type               =       &crypto_blkcipher_type,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(cbc_des_alg.cra_list),
++      .cra_u                  = {
++              .blkcipher = {
++                      .min_keysize            =       DES_KEY_SIZE,
++                      .max_keysize            =       DES_KEY_SIZE,
++                      .ivsize                 =       DES_BLOCK_SIZE,
++                      .setkey                 =       des_setkey,
++                      .encrypt                =       cbc_des_encrypt,
++                      .decrypt                =       cbc_des_decrypt,
++              }
++      }
++};
++
++/*
++ * RFC2451:
++ *
++ *   For DES-EDE3, there is no known need to reject weak or
++ *   complementation keys.  Any weakness is obviated by the use of
++ *   multiple keys.
++ *
++ *   However, if the first two or last two independent 64-bit keys are
++ *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
++ *   same as DES.  Implementers MUST reject keys that exhibit this
++ *   property.
++ *
++ */
++static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
++                         unsigned int keylen)
++{
++      int i, ret;
++      struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
++      const u8 *temp_key = key;
++      u32 *flags = &tfm->crt_flags;
++
++      if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
++          memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
++                 DES_KEY_SIZE))) {
++
++              *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
++              return -EINVAL;
++      }
++      for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
++              ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
++              if (ret < 0)
++                      return ret;
++      }
++      memcpy(dctx->key, key, keylen);
++      dctx->ctrl = SEC_ALG_DES;       //hw 3DES not working yet
++      dctx->key_len = keylen;
++      return 0;
++}
++
++static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
++{
++      struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
++
++      hw_crypto_lock();
++      hw_crypto_check();
++
++      des3_hw_ede_encrypt(uctx->key, dst, src);
++
++      hw_crypto_unlock();     
++}
++
++static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
++{
++      struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
++
++      hw_crypto_lock();
++      hw_crypto_check();
++
++      des3_hw_ede_decrypt(uctx->key, dst, src);
++
++      hw_crypto_unlock();     
++}
++
++static struct crypto_alg des3_192_alg = {
++      .cra_name               =       "des3_ede",
++      .cra_driver_name        =       "des3_ede-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
++      .cra_blocksize          =       DES3_192_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(des3_192_alg.cra_list),
++      .cra_u                  = {
++              .cipher = {
++                      .cia_min_keysize        =       DES3_192_KEY_SIZE,
++                      .cia_max_keysize        =       DES3_192_KEY_SIZE,
++                      .cia_setkey             =       des3_192_setkey,
++                      .cia_encrypt            =       des3_192_encrypt,
++                      .cia_decrypt            =       des3_192_decrypt,
++              }
++      }
++};
++
++static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
++                              struct scatterlist *dst,
++                              struct scatterlist *src, unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_ENCRYPT);
++}
++
++static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
++                              struct scatterlist *dst,
++                              struct scatterlist *src, unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_DECRYPT);
++}
++
++static struct crypto_alg ecb_des3_192_alg = {
++      .cra_name               =       "ecb(des3_ede)",
++      .cra_driver_name        =       "ecb-des3_ede-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
++      .cra_blocksize          =       DES3_192_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_type               =       &crypto_blkcipher_type,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(
++                                              ecb_des3_192_alg.cra_list),
++      .cra_u                  = {
++              .blkcipher = {
++                      .min_keysize            =       DES3_192_KEY_SIZE,
++                      .max_keysize            =       DES3_192_KEY_SIZE,
++                      .setkey                 =       des3_192_setkey,
++                      .encrypt                =       ecb_des3_192_encrypt,
++                      .decrypt                =       ecb_des3_192_decrypt,
++              }
++      }
++};
++
++static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
++                              struct scatterlist *dst,
++                              struct scatterlist *src, unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_ENCRYPT);
++}
++
++static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
++                              struct scatterlist *dst,
++                              struct scatterlist *src, unsigned int nbytes)
++{
++      return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_DECRYPT);
++}
++
++static struct crypto_alg cbc_des3_192_alg = {
++      .cra_name               =       "cbc(des3_ede)",
++      .cra_driver_name        =       "cbc-des3_ede-ubicom32",
++      .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
++      .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
++      .cra_blocksize          =       DES3_192_BLOCK_SIZE,
++      .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
++      .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
++      .cra_type               =       &crypto_blkcipher_type,
++      .cra_module             =       THIS_MODULE,
++      .cra_list               =       LIST_HEAD_INIT(
++                                              cbc_des3_192_alg.cra_list),
++      .cra_u                  = {
++              .blkcipher = {
++                      .min_keysize            =       DES3_192_KEY_SIZE,
++                      .max_keysize            =       DES3_192_KEY_SIZE,
++                      .ivsize                 =       DES3_192_BLOCK_SIZE,
++                      .setkey                 =       des3_192_setkey,
++                      .encrypt                =       cbc_des3_192_encrypt,
++                      .decrypt                =       cbc_des3_192_decrypt,
++              }
++      }
++};
++
++static int init(void)
++{
++      int ret = 0;
++
++      hw_crypto_init();
++
++      ret = crypto_register_alg(&des_alg);
++      if (ret)
++              goto des_err;
++      ret = crypto_register_alg(&ecb_des_alg);
++      if (ret)
++              goto ecb_des_err;
++      ret = crypto_register_alg(&cbc_des_alg);
++      if (ret)
++              goto cbc_des_err;
++
++      ret = crypto_register_alg(&des3_192_alg);
++      if (ret)
++              goto des3_192_err;
++      ret = crypto_register_alg(&ecb_des3_192_alg);
++      if (ret)
++              goto ecb_des3_192_err;
++      ret = crypto_register_alg(&cbc_des3_192_alg);
++      if (ret)
++              goto cbc_des3_192_err;
++
++out:
++      return ret;
++
++cbc_des3_192_err:
++      crypto_unregister_alg(&ecb_des3_192_alg);
++ecb_des3_192_err:
++      crypto_unregister_alg(&des3_192_alg);
++des3_192_err:
++      crypto_unregister_alg(&cbc_des_alg);
++cbc_des_err:
++      crypto_unregister_alg(&ecb_des_alg);
++ecb_des_err:
++      crypto_unregister_alg(&des_alg);
++des_err:
++      goto out;
++}
++
++static void __exit fini(void)
++{
++      crypto_unregister_alg(&cbc_des3_192_alg);
++      crypto_unregister_alg(&ecb_des3_192_alg);
++      crypto_unregister_alg(&des3_192_alg);
++      crypto_unregister_alg(&cbc_des_alg);
++      crypto_unregister_alg(&ecb_des_alg);
++      crypto_unregister_alg(&des_alg);
++}
++
++module_init(init);
++module_exit(fini);
++
++MODULE_ALIAS("des");
++MODULE_ALIAS("des3_ede");
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
+--- /dev/null
++++ b/arch/ubicom32/crypto/Makefile
+@@ -0,0 +1,36 @@
++#
++# arch/ubicom32/crypto/Makefile
++#     <TODO: Replace with short file description>
++#
++# (C) Copyright 2009, Ubicom, Inc.
++#
++# This file is part of the Ubicom32 Linux Kernel Port.
++#
++# The Ubicom32 Linux Kernel Port is free software: you can redistribute
++# it and/or modify it under the terms of the GNU General Public License
++# as published by the Free Software Foundation, either version 2 of the
++# License, or (at your option) any later version.
++#
++# The Ubicom32 Linux Kernel Port is distributed in the hope that it
++# will be useful, but WITHOUT ANY WARRANTY; without even the implied
++# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++# the GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with the Ubicom32 Linux Kernel Port.  If not, 
++# see <http://www.gnu.org/licenses/>.
++#
++# Ubicom32 implementation derived from (with many thanks):
++#   arch/m68knommu
++#   arch/blackfin
++#   arch/parisc
++#
++obj-$(CONFIG_CRYPTO_UBICOM32) += crypto_ubicom32.o
++obj-$(CONFIG_CRYPTO_AES_UBICOM32) += aes_ubicom32.o
++obj-$(CONFIG_CRYPTO_DES_UBICOM32) += des.o
++obj-$(CONFIG_CRYPTO_MD5_UBICOM32) += md5.o
++obj-$(CONFIG_CRYPTO_SHA1_UBICOM32) += sha1.o
++
++des-y := des_ubicom32.o des_check_key.o
++md5-y := md5_ubicom32.o md5_ubicom32_asm.o
++sha1-y := sha1_ubicom32.o 
+--- /dev/null
++++ b/arch/ubicom32/crypto/md5_ubicom32_asm.S
+@@ -0,0 +1,235 @@
++/*
++ * arch/ubicom32/crypto/md5_ubicom32_asm.S
++ *    MD5 (Message Digest 5) support for Ubicom32 v3 architecture
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#define __ASM__
++#include <asm/ip5000.h>
++
++#ifndef RP
++#define RP A5
++#endif
++
++;*****************************************************************************************
++; The function prototypes
++;*****************************************************************************************
++; void md5_ip5k_init(void)
++; void md5_ip5k_transform(u32_t *data_input)
++; void md5_get_digest(u32_t *digest)
++
++;*****************************************************************************************
++; Inputs
++;*****************************************************************************************;
++; data_input is the pointer to the block of data over which the digest will be calculated.
++;     It should be word aligned.
++;
++; digest is the pointer to the block of data into which the digest (the output) will be written.
++;     It should be word aligned.
++;
++
++;*****************************************************************************************
++; Outputs
++;*****************************************************************************************
++; None
++
++;*****************************************************************************************
++; An: Address Registers
++;*****************************************************************************************
++#define an_digest A3
++#define an_data_input A3
++#define an_security_block A4
++
++;*****************************************************************************************
++; Hash Constants
++;*****************************************************************************************
++#define HASH_MD5_IN0 0x01234567
++#define HASH_MD5_IN1 0x89abcdef
++#define HASH_MD5_IN2 0xfedcba98
++#define HASH_MD5_IN3 0x76543210
++
++#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2
++#define HASH_SECURITY_BLOCK_CONTROL_INIT_MD5 ((1 << 4) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION)
++
++;*****************************************************************************************
++; Hash related defines
++;*****************************************************************************************
++#define hash_control 0x00(an_security_block)
++#define hash_control_low 0x02(an_security_block)
++#define hash_status 0x04(an_security_block)
++
++#define hash_input_0 0x30(an_security_block)
++#define hash_input_1 0x34(an_security_block)
++#define hash_input_2 0x38(an_security_block)
++#define hash_input_3 0x3c(an_security_block)
++#define hash_input_4 0x40(an_security_block)
++
++#define hash_output_0 0x70(an_security_block)
++#define hash_output_0_low 0x72(an_security_block)
++#define hash_output_1 0x74(an_security_block)
++#define hash_output_1_low 0x76(an_security_block)
++#define hash_output_2 0x78(an_security_block)
++#define hash_output_2_low 0x7a(an_security_block)
++#define hash_output_3 0x7c(an_security_block)
++#define hash_output_3_low 0x7e(an_security_block)
++
++;*****************************************************************************************
++; Assembly macros
++;*****************************************************************************************
++      ; C compiler reserves RP (A5) for return address during subroutine call.
++      ; Use RP to return to caller
++.macro        call_return_macro
++      calli   RP, 0(RP)
++.endm
++
++#if 0
++;*****************************************************************************************
++;     void md5_ip5k_init(void)
++;             initialize the output registers of the hash module
++;
++      ;.section .text.md5_ip5k_init,"ax",@progbits
++      .section .text
++      .global _md5_ip5k_init
++      .func md5_ip5k_init, _md5_ip5k_init
++
++_md5_ip5k_init:
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
++      movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
++
++      movei hash_output_0, #%hi(HASH_MD5_IN0)
++      movei hash_output_0_low, #%lo(HASH_MD5_IN0)
++
++      movei hash_output_1, #%hi(HASH_MD5_IN1)
++      movei hash_output_1_low, #%lo(HASH_MD5_IN1)
++
++      movei hash_output_2, #%hi(HASH_MD5_IN2)
++      movei hash_output_2_low, #%lo(HASH_MD5_IN2)
++
++      movei hash_output_3, #%hi(HASH_MD5_IN3)
++      movei hash_output_3_low, #%lo(HASH_MD5_IN3)
++
++      call_return_macro
++      .endfunc
++#endif
++
++;*****************************************************************************************
++;     void md5_ip5k_init_digest(u32_t *hash_input)
++;             initialize the output registers of the hash module
++
++      ;.section .text.md5_ip5k_init_digest,"ax",@progbits
++      .section .text
++      .global _md5_ip5k_init_digest
++      .func md5_ip5k_init_digest, _md5_ip5k_init_digest
++
++_md5_ip5k_init_digest:
++      movea an_data_input, D0
++
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
++      movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_MD5)
++
++      move.4 hash_output_0, (an_data_input)4++
++      move.4 hash_output_1, (an_data_input)4++
++      move.4 hash_output_2, (an_data_input)4++
++      move.4 hash_output_3, (an_data_input)4++
++
++      call_return_macro
++      .endfunc
++
++;*****************************************************************************************
++;     void md5_ip5k_transform(u32_t *data_input)
++;             performs intermediate transformation step for the hash calculation
++;
++      ;.sect .text.md5_ip5k_transform,"ax",@progbits
++      .section .text
++      .global _md5_ip5k_transform
++      .func md5_ip5k_transform, _md5_ip5k_transform
++
++_md5_ip5k_transform:
++      movea an_data_input, D0
++
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      ; Write the first 128bits (16 bytes)
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      pipe_flush 0
++
++md5_ip5k_transform_wait:
++      ; wait for the module to calculate the output hash
++      btst hash_status, #0
++      jmpne.f md5_ip5k_transform_wait
++
++      call_return_macro
++      .endfunc
++
++;*****************************************************************************************
++;     void md5_ip5k_get_digest(u32_t *digest)
++;             Return the hash of the input data
++;
++      ;.sect .text.md5_get_digest,"ax",@progbits
++      .section .text
++      .global _md5_ip5k_get_digest
++      .func md5_ip5k_get_digest, _md5_ip5k_get_digest
++
++_md5_ip5k_get_digest:
++      movea an_digest, D0
++
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      ; we have finished
++      move.4 0(an_digest), hash_output_0
++      move.4 4(an_digest), hash_output_1
++      move.4 8(an_digest), hash_output_2
++      move.4 12(an_digest), hash_output_3
++
++      call_return_macro
++      .endfunc
++
+--- /dev/null
++++ b/arch/ubicom32/crypto/md5_ubicom32.c
+@@ -0,0 +1,200 @@
++/*
++ * arch/ubicom32/crypto/md5_ubicom32.c
++ *   Ubicom32 implementation of the MD5 Secure Hash Algorithm
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/crypto.h>
++
++#include "crypto_ubicom32.h"
++
++#define MD5_DIGEST_SIZE       16
++#define MD5_BLOCK_SIZE        64
++#define MD5_HASH_WORDS        4
++
++extern void _md5_ip5k_init_digest(u32_t *digest);
++extern void _md5_ip5k_transform(u32_t *data_input);
++extern void _md5_ip5k_get_digest(u32_t *digest);
++
++struct ubicom32_md5_ctx {
++      u64 count;              /* message length */
++      u32 state[MD5_HASH_WORDS];
++      u8 buf[2 * MD5_BLOCK_SIZE];
++};
++
++static void md5_init(struct crypto_tfm *tfm)
++{
++      struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
++      mctx->state[0] = 0x01234567;
++      mctx->state[1] = 0x89abcdef;
++      mctx->state[2] = 0xfedcba98;
++      mctx->state[3] = 0x76543210;
++
++      mctx->count = 0;
++}
++
++static inline void _md5_process(u32 *digest, const u8 *data)
++{
++      _md5_ip5k_transform((u32 *)data);
++}
++
++static void md5_update(struct crypto_tfm *tfm, const u8 *data,
++                      unsigned int len)
++{
++      struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
++      int index, clen;
++
++      /* how much is already in the buffer? */
++      index = mctx->count & 0x3f;
++
++      mctx->count += len;
++
++      if (index + len < MD5_BLOCK_SIZE) {
++              goto store_only;
++      }
++
++      hw_crypto_lock();
++      hw_crypto_check();
++
++      /* init digest set ctrl register too */
++      _md5_ip5k_init_digest(mctx->state);
++
++      if (unlikely(index == 0 && SEC_ALIGNED(data))) {
++fast_process:
++              while (len >= MD5_BLOCK_SIZE) {
++                      _md5_process(mctx->state, data);
++                      data += MD5_BLOCK_SIZE;
++                      len -= MD5_BLOCK_SIZE;
++              }
++              goto store;
++      }
++
++      /* process one stored block */
++      if (index) {
++              clen = MD5_BLOCK_SIZE - index;
++              memcpy(mctx->buf + index, data, clen);
++              _md5_process(mctx->state, mctx->buf);
++              data += clen;
++              len -= clen;
++              index = 0;
++      }
++
++      if (likely(SEC_ALIGNED(data))) {
++              goto fast_process;
++      }
++
++      /* process as many blocks as possible */
++      while (len >= MD5_BLOCK_SIZE) {
++              memcpy(mctx->buf, data, MD5_BLOCK_SIZE);
++              _md5_process(mctx->state, mctx->buf);
++              data += MD5_BLOCK_SIZE;
++              len -= MD5_BLOCK_SIZE;
++      }
++
++store:
++      _md5_ip5k_get_digest(mctx->state);
++      hw_crypto_unlock();
++
++store_only:
++      /* anything left? */
++      if (len)
++              memcpy(mctx->buf + index , data, len);
++}
++
++/* Add padding and return the message digest. */
++static void md5_final(struct crypto_tfm *tfm, u8 *out)
++{
++      struct ubicom32_md5_ctx *mctx = crypto_tfm_ctx(tfm);
++      u32 bits[2];
++      unsigned int index, end;
++
++      /* must perform manual padding */
++      index = mctx->count & 0x3f;
++      end =  (index < 56) ? MD5_BLOCK_SIZE : (2 * MD5_BLOCK_SIZE);
++
++      /* start pad with 1 */
++      mctx->buf[index] = 0x80;
++
++      /* pad with zeros */
++      index++;
++      memset(mctx->buf + index, 0x00, end - index - 8);
++
++      /* append message length */
++      bits[0] = mctx->count << 3;
++      bits[1] = mctx->count >> 29;
++      __cpu_to_le32s(bits);
++      __cpu_to_le32s(bits + 1);
++
++      memcpy(mctx->buf + end - 8, &bits, sizeof(bits));
++
++      /* force to use the mctx->buf and ignore the partial buf */
++      mctx->count = mctx->count & ~0x3f;
++      md5_update(tfm, mctx->buf, end);
++
++      /* copy digest to out */
++      memcpy(out, mctx->state, MD5_DIGEST_SIZE);
++
++      /* wipe context */
++      memset(mctx, 0, sizeof *mctx);
++}
++
++static struct crypto_alg alg = {
++      .cra_name       =       "md5",
++      .cra_driver_name=       "md5-ubicom32",
++      .cra_priority   =       CRYPTO_UBICOM32_PRIORITY,
++      .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
++      .cra_blocksize  =       MD5_BLOCK_SIZE,
++      .cra_ctxsize    =       sizeof(struct ubicom32_md5_ctx),
++      .cra_module     =       THIS_MODULE,
++      .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
++      .cra_u = {
++              .digest = {
++                      .dia_digestsize =       MD5_DIGEST_SIZE,
++                      .dia_init       =       md5_init,
++                      .dia_update     =       md5_update,
++                      .dia_final      =       md5_final,
++              }
++      }
++};
++
++static int __init init(void)
++{
++      hw_crypto_init();
++      return crypto_register_alg(&alg);
++}
++
++static void __exit fini(void)
++{
++      crypto_unregister_alg(&alg);
++}
++
++module_init(init);
++module_exit(fini);
++
++MODULE_ALIAS("md5");
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("MD5 Secure Hash Algorithm");
+--- /dev/null
++++ b/arch/ubicom32/crypto/sha1_ubicom32_asm.S
+@@ -0,0 +1,244 @@
++/*
++ * arch/ubicom32/crypto/sha1_ubicom32_asm.S
++ *    SHA1 hash support for Ubicom32 architecture V3.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#define __ASM__
++#include <asm/ip5000.h>
++
++#ifndef RP
++#define RP A5
++#endif
++
++;*****************************************************************************************
++; The function prototype
++;*****************************************************************************************
++; void sha1_ip5k_init(void)
++; void sha1_ip5k_transform(u32_t *data_input)
++; void sha1_ip5k_output(u32_t *digest)
++
++;*****************************************************************************************
++; Inputs
++;*****************************************************************************************
++; data_input is the pointer to the block of data over which the digest will be calculated.
++;     It should be word aligned.
++;
++; digest is the pointer to the block of data into which the digest (the output) will be written.
++;     It should be word aligned.
++;
++
++;*****************************************************************************************
++; Outputs
++;*****************************************************************************************
++; None
++
++;*****************************************************************************************
++; Hash Constants
++;*****************************************************************************************
++#define HASH_SHA1_IN0 0x67452301
++#define HASH_SHA1_IN1 0xefcdab89
++#define HASH_SHA1_IN2 0x98badcfe
++#define HASH_SHA1_IN3 0x10325476
++#define HASH_SHA1_IN4 0xc3d2e1f0
++
++#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2
++#define HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1 ((1 << 5) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION)
++
++;*****************************************************************************************
++; An: Address Registers
++;*****************************************************************************************
++#define an_digest a4
++#define an_data_input a4
++#define an_security_block a3
++
++;*****************************************************************************************
++; Hash related defines
++;*****************************************************************************************
++#define hash_control 0x00(an_security_block)
++#define hash_control_low 0x02(an_security_block)
++#define hash_status 0x04(an_security_block)
++
++#define hash_input_0 0x30(an_security_block)
++#define hash_input_1 0x34(an_security_block)
++#define hash_input_2 0x38(an_security_block)
++#define hash_input_3 0x3c(an_security_block)
++#define hash_input_4 0x40(an_security_block)
++
++#define hash_output_0 0x70(an_security_block)
++#define hash_output_0_low 0x72(an_security_block)
++#define hash_output_1 0x74(an_security_block)
++#define hash_output_1_low 0x76(an_security_block)
++#define hash_output_2 0x78(an_security_block)
++#define hash_output_2_low 0x7a(an_security_block)
++#define hash_output_3 0x7c(an_security_block)
++#define hash_output_3_low 0x7e(an_security_block)
++#define hash_output_4 0x80(an_security_block)
++#define hash_output_4_low 0x82(an_security_block)
++
++;*****************************************************************************************
++; Assembly macros
++;*****************************************************************************************
++      ; C compiler reserves RP (A5) for return address during subroutine call.
++      ; Use RP to return to caller
++.macro        call_return_macro
++      calli   RP, 0(RP)
++.endm
++
++;*****************************************************************************************
++;     void sha1_ip5k_init(void)
++;             initialize the output registers of the hash module
++
++      ;.section .text.sha1_ip5k_init,"ax",@progbits
++      .section .ocm_text,"ax",@progbits
++      .global _sha1_ip5k_init
++      .func sha1_ip5k_init, _sha1_ip5k_init
++
++_sha1_ip5k_init:
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
++      movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
++
++      movei hash_output_0, #%hi(HASH_SHA1_IN0)
++      movei hash_output_0_low, #%lo(HASH_SHA1_IN0)
++
++      movei hash_output_1, #%hi(HASH_SHA1_IN1)
++      movei hash_output_1_low, #%lo(HASH_SHA1_IN1)
++
++      movei hash_output_2, #%hi(HASH_SHA1_IN2)
++      movei hash_output_2_low, #%lo(HASH_SHA1_IN2)
++
++      movei hash_output_3, #%hi(HASH_SHA1_IN3)
++      movei hash_output_3_low, #%lo(HASH_SHA1_IN3)
++
++      movei hash_output_4, #%hi(HASH_SHA1_IN4)
++      movei hash_output_4_low, #%lo(HASH_SHA1_IN4)
++
++      call_return_macro
++      .endfunc
++
++;*****************************************************************************************
++;     void sha1_ip5k_init_digest(u32_t *hash_input)
++;             initialize the output registers of the hash module
++
++      ;.section .text.sha1_ip5k_init_digest,"ax",@progbits
++      .section .ocm_text,"ax",@progbits
++      .global _sha1_ip5k_init_digest
++      .func sha1_ip5k_init_digest, _sha1_ip5k_init_digest
++
++_sha1_ip5k_init_digest:
++      movea an_data_input, D0
++
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      movei hash_control, #%hi(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
++      movei hash_control_low, #%lo(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1)
++
++      move.4 hash_output_0, (an_data_input)4++
++      move.4 hash_output_1, (an_data_input)4++
++      move.4 hash_output_2, (an_data_input)4++
++      move.4 hash_output_3, (an_data_input)4++
++      move.4 hash_output_4, (an_data_input)4++
++
++      call_return_macro
++      .endfunc
++
++;*****************************************************************************************
++;     void sha1_ip5k_transform(u32_t *data_input)
++;             performs intermediate transformation step for the hash calculation
++
++      ;.section .text.sha1_ip5k_transform,"ax",@progbits
++      .section .ocm_text,"ax",@progbits
++      .global _sha1_ip5k_transform
++      .func sha1_ip5k_transform, _sha1_ip5k_transform
++
++_sha1_ip5k_transform:
++      movea an_data_input, D0
++
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      ; Write the first 128bits (16 bytes)
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      move.4 hash_input_0, (an_data_input)4++
++      move.4 hash_input_1, (an_data_input)4++
++      move.4 hash_input_2, (an_data_input)4++
++      move.4 hash_input_3, (an_data_input)4++
++      move.4 hash_input_4, D0
++
++      pipe_flush 0
++
++sha1_ip5k_transform_wait:
++      ; wait for the module to calculate the output hash
++      btst hash_status, #0
++      jmpne.f sha1_ip5k_transform_wait
++
++      call_return_macro
++      .endfunc
++
++;*****************************************************************************************
++;     void sha1_ip5k_output(u32_t *digest)
++;             Return the hash of the input data
++
++      ;.section .text.sha1_ip5k_output,"ax",@progbits
++      .section .ocm_text,"ax",@progbits
++      .global _sha1_ip5k_output
++      .func sha1_ip5k_output, _sha1_ip5k_output
++
++_sha1_ip5k_output:
++      movea an_digest, D0
++
++      moveai an_security_block, #SECURITY_BASE_EFFECTIVE_ADDRESS
++
++      ; we have finished
++      move.4 0(an_digest), hash_output_0
++      move.4 4(an_digest), hash_output_1
++      move.4 8(an_digest), hash_output_2
++      move.4 12(an_digest), hash_output_3
++      move.4 16(an_digest), hash_output_4
++
++      call_return_macro
++      .endfunc
++
++;*****************************************************************************************
++;END                  ;End of program code
++;*****************************************************************************************
+--- /dev/null
++++ b/arch/ubicom32/crypto/sha1_ubicom32.c
+@@ -0,0 +1,354 @@
++/*
++ * arch/ubicom32/crypto/sha1_ubicom32.c
++ *   Ubicom32 implementation of the SHA1 Secure Hash Algorithm.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/crypto.h>
++#include <crypto/sha.h>
++#include <asm/linkage.h>
++
++#include "crypto_ubicom32.h"
++#define HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION 2
++#define HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1 ((1 << 5) | HASH_SECURITY_BLOCK_CONTROL_INIT_NO_ENCYPTION)
++
++struct ubicom32_sha1_ctx {
++      u64 count;              /* message length */
++      u32 state[5];
++      u8 buf[2 * SHA1_BLOCK_SIZE];
++};
++
++static inline void sha1_clear_2ws(u8 *buf, int wc)
++{
++      asm volatile (
++      "1:     move.4  (%0)4++, #0             \n\t"
++      "       move.4  (%0)4++, #0             \n\t"
++      "       sub.4   %1, #2, %1              \n\t"
++      "       jmple.f 1b                      \n\t"
++              :
++              : "a" (buf), "d" (wc)
++              : "cc"
++      );
++}
++
++/* only wipe out count, state, and 1st half of buf - 9 bytes at most */
++#define sha1_wipe_out(sctx) sha1_clear_2ws((u8 *)sctx, 2 + 5 + 16 - 2)
++
++static inline void sha1_init_digest(u32 *digest)
++{
++      hw_crypto_set_ctrl(HASH_SECURITY_BLOCK_CONTROL_INIT_SHA1);
++      asm volatile (
++      "       ; move digests to hash_output regs      \n\t"
++      "       move.4  0x70(%0), 0x0(%1)               \n\t"
++      "       move.4  0x74(%0), 0x4(%1)               \n\t"
++      "       move.4  0x78(%0), 0x8(%1)               \n\t"
++      "       move.4  0x7c(%0), 0xc(%1)               \n\t"
++      "       move.4  0x80(%0), 0x10(%1)              \n\t"
++              :
++              : "a" (SEC_BASE), "a" (digest)
++      );
++}
++
++static inline void sha1_transform_feed(const u8 *in)
++{
++      asm volatile (
++      "       ; write the 1st 16 bytes        \n\t"
++      "       move.4  0x30(%0), 0x0(%1)       \n\t"
++      "       move.4  0x34(%0), 0x4(%1)       \n\t"
++      "       move.4  0x38(%0), 0x8(%1)       \n\t"
++      "       move.4  0x3c(%0), 0xc(%1)       \n\t"
++      "       move.4  0x40(%0), %1            \n\t"
++      "       ; write the 2nd 16 bytes        \n\t"
++      "       move.4  0x30(%0), 0x10(%1)      \n\t"
++      "       move.4  0x34(%0), 0x14(%1)      \n\t"
++      "       move.4  0x38(%0), 0x18(%1)      \n\t"
++      "       move.4  0x3c(%0), 0x1c(%1)      \n\t"
++      "       move.4  0x40(%0), %1            \n\t"
++      "       ; write the 3rd 16 bytes        \n\t"
++      "       move.4  0x30(%0), 0x20(%1)      \n\t"
++      "       move.4  0x34(%0), 0x24(%1)      \n\t"
++      "       move.4  0x38(%0), 0x28(%1)      \n\t"
++      "       move.4  0x3c(%0), 0x2c(%1)      \n\t"
++      "       move.4  0x40(%0), %1            \n\t"
++      "       ; write the 4th 16 bytes        \n\t"
++      "       move.4  0x30(%0), 0x30(%1)      \n\t"
++      "       move.4  0x34(%0), 0x34(%1)      \n\t"
++      "       move.4  0x38(%0), 0x38(%1)      \n\t"
++      "       move.4  0x3c(%0), 0x3c(%1)      \n\t"
++      "       move.4  0x40(%0), %1            \n\t"
++      "       pipe_flush 0                    \n\t" 
++              :
++              : "a"(SEC_BASE), "a"(in)
++      );
++}
++
++static inline void sha1_transform_wait(void)
++{
++      asm volatile (
++      "       btst    0x04(%0), #0            \n\t"
++      "       jmpne.f -4                      \n\t"
++              :
++              : "a"(SEC_BASE)
++              : "cc"
++      );
++}
++
++static inline void sha1_output_digest(u32 *digest)
++{
++      asm volatile (
++      "       move.4  0x0(%1), 0x70(%0)               \n\t"
++      "       move.4  0x4(%1), 0x74(%0)               \n\t"
++      "       move.4  0x8(%1), 0x78(%0)               \n\t"
++      "       move.4  0xc(%1), 0x7c(%0)               \n\t"
++      "       move.4  0x10(%1), 0x80(%0)              \n\t"
++              : 
++              : "a" (SEC_BASE), "a" (digest)
++      );
++}
++
++static __ocm_text void sha1_init(struct crypto_tfm *tfm)
++{
++      struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
++
++      sctx->state[0] = SHA1_H0;
++      sctx->state[1] = SHA1_H1;
++      sctx->state[2] = SHA1_H2;
++      sctx->state[3] = SHA1_H3;
++      sctx->state[4] = SHA1_H4;
++      sctx->count = 0;
++}
++
++static void __ocm_text sha1_update(struct crypto_tfm *tfm, const u8 *data,
++                      unsigned int len)
++{
++      struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
++      int index, clen;
++
++      /* how much is already in the buffer? */
++      index = sctx->count & 0x3f;
++
++      sctx->count += len;
++
++      if (index + len < SHA1_BLOCK_SIZE) {
++              goto store_only;
++      }
++
++      hw_crypto_lock();
++      hw_crypto_check();
++
++      /* init digest set ctrl register too */
++      sha1_init_digest(sctx->state);
++
++      if (unlikely(index == 0 && SEC_ALIGNED(data))) {
++fast_process:
++#if CRYPTO_UBICOM32_LOOP_ASM 
++              if (likely(len >= SHA1_BLOCK_SIZE)) {
++                      register unsigned int cnt = len >> 6;   // loop = len / 64;
++                      sha1_transform_feed(data);
++                      data += SHA1_BLOCK_SIZE;
++
++                      /* cnt is pre-decremented in the loop */
++                      asm volatile (
++                      "; while (--loop):  work on 2nd block   \n\t"
++                      "1:     add.4   %2, #-1, %2             \n\t"
++                      "       jmpeq.f 5f                      \n\t"
++                      "                                       \n\t"
++                      "       ; write the 1st 16 bytes        \n\t"
++                      "       move.4  0x30(%1), (%0)4++       \n\t"
++                      "       move.4  0x34(%1), (%0)4++       \n\t"
++                      "       move.4  0x38(%1), (%0)4++       \n\t"
++                      "       move.4  0x3c(%1), (%0)4++       \n\t"
++                      "       ; can not kick off hw before it \n\t"
++                      "       ; is done with the prev block   \n\t"
++                      "                                       \n\t"
++                      "       btst    0x04(%1), #0            \n\t"
++                      "       jmpne.f -4                      \n\t"
++                      "                                       \n\t"
++                      "       ; tell hw to load 1st 16 bytes  \n\t"
++                      "       move.4  0x40(%1), %2            \n\t"
++                      "                                       \n\t"
++                      "       ; write the 2nd 16 bytes        \n\t"
++                      "       move.4  0x30(%1), (%0)4++       \n\t"
++                      "       move.4  0x34(%1), (%0)4++       \n\t"
++                      "       move.4  0x38(%1), (%0)4++       \n\t"
++                      "       move.4  0x3c(%1), (%0)4++       \n\t"
++                      "       move.4  0x40(%1), %2            \n\t"
++                      "                                       \n\t"
++                      "       ; write the 3rd 16 bytes        \n\t"
++                      "       move.4  0x30(%1), (%0)4++       \n\t"
++                      "       move.4  0x34(%1), (%0)4++       \n\t"
++                      "       move.4  0x38(%1), (%0)4++       \n\t"
++                      "       move.4  0x3c(%1), (%0)4++       \n\t"
++                      "       move.4  0x40(%1), %2            \n\t"
++                      "                                       \n\t"
++                      "       ; write the 4th 16 bytes        \n\t"
++                      "       move.4  0x30(%1), (%0)4++       \n\t"
++                      "       move.4  0x34(%1), (%0)4++       \n\t"
++                      "       move.4  0x38(%1), (%0)4++       \n\t"
++                      "       move.4  0x3c(%1), (%0)4++       \n\t"
++                      "       move.4  0x40(%1), %2            \n\t"
++                      "                                       \n\t"
++                      "; no need flush, enough insts          \n\t"
++                      "; before next hw wait                  \n\t"
++                      "                                       \n\t"
++                      "; go back to loop                      \n\t"
++                      "       jmpt 1b                         \n\t"
++                      "                                       \n\t"
++                      "; wait hw for last block               \n\t"
++                      "5:     btst 0x04(%1), #0               \n\t"
++                      "       jmpne.f -4                      \n\t"
++                      "                                       \n\t"
++                              : "+a" (data)
++                              : "a"( SEC_BASE), "d" (cnt)
++                              : "cc"
++                      );
++
++                      len = len & (64 - 1);
++              }
++#else
++              while (likely(len >= SHA1_BLOCK_SIZE)) {
++                      sha1_transform_feed(data);
++                      data += SHA1_BLOCK_SIZE;
++                      len -= SHA1_BLOCK_SIZE;
++                      sha1_transform_wait();
++              }
++#endif
++              goto store;
++      }
++
++      /* process one stored block */
++      if (index) {
++              clen = SHA1_BLOCK_SIZE - index;
++              memcpy(sctx->buf + index, data, clen);
++              sha1_transform_feed(sctx->buf);
++              data += clen;
++              len -= clen;
++              index = 0;
++              sha1_transform_wait();
++      }
++
++      if (likely(SEC_ALIGNED(data))) {
++              goto fast_process;
++      }
++
++      /* process as many blocks as possible */
++      if (likely(len >= SHA1_BLOCK_SIZE)) {
++              memcpy(sctx->buf, data, SHA1_BLOCK_SIZE);
++              do {
++                      sha1_transform_feed(sctx->buf);
++                      data += SHA1_BLOCK_SIZE;
++                      len -= SHA1_BLOCK_SIZE;
++                      if (likely(len >= SHA1_BLOCK_SIZE)) {
++                              memcpy(sctx->buf, data, SHA1_BLOCK_SIZE);
++                              sha1_transform_wait();
++                              continue;
++                      }
++                      /* it is the last block */      
++                      sha1_transform_wait();
++                      break;
++              } while (1);
++      }
++
++store:
++      sha1_output_digest(sctx->state);
++      hw_crypto_unlock();
++
++store_only:
++      /* anything left? */
++      if (len)
++              memcpy(sctx->buf + index , data, len);
++}
++
++/* Add padding and return the message digest. */
++static void __ocm_text sha1_final(struct crypto_tfm *tfm, u8 *out)
++{
++      struct ubicom32_sha1_ctx *sctx = crypto_tfm_ctx(tfm);
++      u64 bits;
++      unsigned int index, end;
++
++      /* must perform manual padding */
++      index = sctx->count & 0x3f;
++      end =  (index < 56) ? SHA1_BLOCK_SIZE : (2 * SHA1_BLOCK_SIZE);
++
++      /* start pad with 1 */
++      sctx->buf[index] = 0x80;
++
++      /* pad with zeros */
++      index++;
++      memset(sctx->buf + index, 0x00, end - index - 8);
++
++      /* append message length */
++      bits = sctx->count << 3 ;
++      SEC_COPY_2W(sctx->buf + end - 8, &bits);
++
++      /* force to use the sctx->buf and ignore the partial buf */
++      sctx->count = sctx->count & ~0x3f;
++      sha1_update(tfm, sctx->buf, end);
++
++      /* copy digest to out */
++      SEC_COPY_5W(out, sctx->state);
++
++      /* wipe context */
++      sha1_wipe_out(sctx);
++}
++
++static struct crypto_alg alg = {
++      .cra_name       =       "sha1",
++      .cra_driver_name=       "sha1-ubicom32",
++      .cra_priority   =       CRYPTO_UBICOM32_PRIORITY,
++      .cra_flags      =       CRYPTO_ALG_TYPE_DIGEST,
++      .cra_blocksize  =       SHA1_BLOCK_SIZE,
++      .cra_ctxsize    =       sizeof(struct ubicom32_sha1_ctx),
++      .cra_module     =       THIS_MODULE,
++      .cra_list       =       LIST_HEAD_INIT(alg.cra_list),
++      .cra_u    = {
++              .digest = {
++                      .dia_digestsize =       SHA1_DIGEST_SIZE,
++                      .dia_init       =       sha1_init,
++                      .dia_update     =       sha1_update,
++                      .dia_final      =       sha1_final,
++              }
++      }
++};
++
++static int __init init(void)
++{
++      hw_crypto_init();
++      return crypto_register_alg(&alg);
++}
++
++static void __exit fini(void)
++{
++      crypto_unregister_alg(&alg);
++}
++
++module_init(init);
++module_exit(fini);
++
++MODULE_ALIAS("sha1");
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
+--- /dev/null
++++ b/arch/ubicom32/include/asm/a.out.h
+@@ -0,0 +1,47 @@
++/*
++ * arch/ubicom32/include/asm/a.out.h
++ *   Definitions for Ubicom32 a.out executable format.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_A_OUT_H
++#define _ASM_UBICOM32_A_OUT_H
++
++struct exec
++{
++  unsigned long a_info;               /* Use macros N_MAGIC, etc for access */
++  unsigned a_text;            /* length of text, in bytes */
++  unsigned a_data;            /* length of data, in bytes */
++  unsigned a_bss;             /* length of uninitialized data area for file, in bytes */
++  unsigned a_syms;            /* length of symbol table data in file, in bytes */
++  unsigned a_entry;           /* start address */
++  unsigned a_trsize;          /* length of relocation info for text, in bytes */
++  unsigned a_drsize;          /* length of relocation info for data, in bytes */
++};
++
++#define N_TRSIZE(a)   ((a).a_trsize)
++#define N_DRSIZE(a)   ((a).a_drsize)
++#define N_SYMSIZE(a)  ((a).a_syms)
++
++#endif /* _ASM_UBICOM32_A_OUT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/atomic.h
+@@ -0,0 +1,352 @@
++/*
++ * arch/ubicom32/include/asm/atomic.h
++ *   Atomic operations definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ATOMIC_H
++#define _ASM_UBICOM32_ATOMIC_H
++
++#include <asm/system.h>
++#include <asm/ubicom32-common.h>
++#include <asm/types.h>
++
++/*
++ * Most instructions on the Ubicom32 processor are atomic in that they
++ * execute in one clock cycle.  However, Linux has several operations
++ * (e.g. compare and swap) which will require more than a single instruction
++ * to perform.   To achieve this, the Ubicom32 processor uses a single
++ * global bit in a scratchpad register as a critical section lock. All
++ * atomic operations acquire this lock.
++ *
++ * NOTE: To AVOID DEADLOCK(s), the atomic lock must only be used for atomic
++ * operations or by the ldsr to avoid disabling a thread performing an atomic
++ * operation.
++ *
++ * Do not attempt to disable interrupts while holding the atomic operations
++ * lock or you will DEADLOCK the system.
++ */
++
++typedef struct {
++      volatile int counter;
++} atomic_t;
++
++#define ATOMIC_INIT(i)        { (i) }
++
++/*
++ * __atomic_add()
++ *    Add i to v and return the result.
++ */
++static inline void __atomic_add(int i, atomic_t *v)
++{
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      vt->counter += i;
++      __atomic_lock_release();
++}
++
++/*
++ * __atomic_sub()
++ *    Subtract i from v and return the result.
++ */
++static inline void __atomic_sub(int i, atomic_t *v)
++{
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      vt->counter -= i;
++      __atomic_lock_release();
++}
++
++/*
++ * __atomic_add_return()
++ *    Add i to v and return the result.
++ *
++ * The implementation here looks rather odd because we appear to be doing
++ * the addition twice.  In fact that's exactly what we're doing but with
++ * the ubicom32 instruction set we can do the inner load and add with two
++ * instructions whereas generating both the atomic result and the "ret"
++ * result requires three instructions.  The second add is generally only as
++ * costly as a move instruction and in cases where we compare the result
++ * with a constant the compiler can fold two constant values and do a
++ * single instruction, thus saving an instruction overall!
++ *
++ * At the worst we save one instruction inside the atomic lock.
++ */
++static inline int __atomic_add_return(int i, atomic_t *v)
++{
++      int ret;
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      ret = vt->counter;
++      vt->counter = ret + i;
++      __atomic_lock_release();
++
++      return ret + i;
++}
++
++/*
++ * __atomic_sub_return()
++ *    Subtract i from v and return the result.
++ *
++ * The implementation here looks rather odd because we appear to be doing
++ * the subtraction twice.  In fact that's exactly what we're doing but with
++ * the ubicom32 instruction set we can do the inner load and sub with two
++ * instructions whereas generating both the atomic result and the "ret"
++ * result requires three instructions.  The second sub is generally only as
++ * costly as a move instruction and in cases where we compare the result
++ * with a constant the compiler can fold two constant values and do a
++ * single instruction, thus saving an instruction overall!
++ *
++ * At the worst we save one instruction inside the atomic lock.
++ */
++static inline int __atomic_sub_return(int i, atomic_t *v)
++{
++      int ret;
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      ret = vt->counter;
++      vt->counter = ret - i;
++      __atomic_lock_release();
++
++      return ret - i;
++}
++
++/*
++ * PUBLIC API FOR ATOMIC!
++ */
++#define atomic_add(i,v)       (__atomic_add( ((int)i),(v)))
++#define atomic_sub(i,v)       (__atomic_sub( ((int)i),(v)))
++#define atomic_inc(v) (__atomic_add(   1,(v)))
++#define atomic_dec(v) (__atomic_sub(   1,(v)))
++#define atomic_add_return(i,v)        (__atomic_add_return( ((int)i),(v)))
++#define atomic_sub_return(i,v)        (__atomic_sub_return( ((int)i),(v)))
++#define atomic_inc_return(v)  (__atomic_add_return(   1,(v)))
++#define atomic_dec_return(v)  (__atomic_sub_return(   1,(v)))
++#define atomic_inc_and_test(v)        (atomic_inc_return(v) == 0)
++#define atomic_dec_and_test(v)        (atomic_dec_return(v) == 0)
++#define atomic_add_negative(a, v)     (atomic_add_return((a), (v)) < 0)
++#define atomic_sub_and_test(i,v)      (atomic_sub_return((i),(v)) == 0)
++
++/*
++ * atomic_read()
++ *    Acquire the atomic lock and read the variable.
++ */
++static inline int atomic_read(const atomic_t *v)
++{
++      int ret;
++      const atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      ret = vt->counter;
++      __atomic_lock_release();
++
++      return ret;
++}
++
++/*
++ * atomic_set()
++ *    Acquire the atomic lock and set the variable.
++ */
++static inline void atomic_set(atomic_t *v, int i)
++{
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      vt->counter = i;
++      __atomic_lock_release();
++}
++
++/*
++ * atomic_cmpxchg
++ *    Acquire the atomic lock and exchange if current == old.
++ */
++static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
++{
++      int prev;
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      prev = vt->counter;
++      if (prev == old) {
++              vt->counter = new;
++      }
++      __atomic_lock_release();
++
++      return prev;
++}
++
++/*
++ * atomic_xchg()
++ *    Acquire the atomic lock and exchange values.
++ */
++static inline int atomic_xchg(atomic_t *v, int new)
++{
++      int prev;
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      prev = vt->counter;
++      vt->counter = new;
++      __atomic_lock_release();
++
++      return prev;
++}
++
++/*
++ * atomic_add_unless()
++ *    Acquire the atomic lock and add a unless the value is u.
++ */
++static inline int atomic_add_unless(atomic_t *v, int a, int u)
++{
++      int prev;
++      atomic_t *vt = v;
++
++      __atomic_lock_acquire();
++      prev = vt->counter;
++      if (prev != u) {
++              vt->counter += a;
++              __atomic_lock_release();
++              return 1;
++      }
++
++      __atomic_lock_release();
++      return 0;
++}
++
++#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
++
++#include <asm-generic/atomic.h>
++
++/* 
++ * The following is not a real function.  The compiler should remove the function
++ * call as long as the user does not pass in a size that __xchg and __cmpxchg
++ * are not prepared for.  If the user does pass in an unknown size, the user
++ * will get a link time error.
++ *
++ * The no return is to prevent a compiler error that can occur when dealing with
++ * uninitialized variables. Given that the function doesn't exist there is no
++ * net effect (and if it did it would not return).
++ */
++extern void __xchg_called_with_bad_pointer(void) __attribute__((noreturn));
++
++/*
++ * __xchg()
++ *    Xchange *ptr for x atomically.
++ *
++ * Must be both locally atomic and atomic on SMP. Ubicom32 does not have an
++ * atomic exchange instruction so we use the global atomic_lock.
++ */
++static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
++{
++      unsigned long ret;
++
++      __atomic_lock_acquire();
++
++      switch (size) {
++      case 1:
++              ret = *(volatile unsigned char *)ptr;
++              *(volatile unsigned char *)ptr = x;
++              break;
++
++      case 2:
++              ret = *(volatile unsigned short *)ptr;
++              *(volatile unsigned short *)ptr = x;
++              break;
++
++      case 4:
++              ret = *(volatile unsigned int *)ptr;
++              *(volatile unsigned int *)ptr = x;
++              break;
++
++      default:
++              __xchg_called_with_bad_pointer();
++              break;
++      }
++      __atomic_lock_release();
++      return ret;
++}
++
++#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
++
++/*
++ * __cmpxchg()
++ *    Compare and Xchange *ptr for x atomically.
++ *
++ * Must be both locally atomic and atomic on SMP. Ubicom32 does not have an
++ * atomic exchange instruction so we use the global atomic_lock.
++ */
++static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long next, int size)
++{
++      unsigned long prev;
++
++      __atomic_lock_acquire();
++      switch (size) {
++      case 1: 
++              prev = *(u8 *)ptr;
++              if (prev == old) {
++                      *(u8 *)ptr = (u8)next;
++              }
++              break;
++
++      case 2: 
++              prev = *(u16 *)ptr;
++              if (prev == old) {
++                      *(u16 *)ptr = (u16)next;
++              }
++              break;
++
++      case 4: 
++              prev = *(u32 *)ptr;
++              if (prev == old) {
++                      *(u32 *)ptr = (u32)next;
++              }
++              break;
++
++      default:
++              __xchg_called_with_bad_pointer();
++              break;
++      }
++      __atomic_lock_release();
++      return prev;
++}
++
++/*
++ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
++ * them available.
++ */
++#define cmpxchg_local(ptr, o, n) \
++      ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
++
++#define cmpxchg(ptr, o, n) __cmpxchg((ptr), (o), (n), sizeof(*(ptr)))
++
++#define smp_mb__before_atomic_inc() asm volatile ("" : : : "memory")
++#define smp_mb__after_atomic_inc() asm volatile ("" : : : "memory")
++#define smp_mb__before_atomic_dec() asm volatile ("" : : : "memory")
++#define smp_mb__after_atomic_dec() asm volatile ("" : : : "memory")
++
++#endif /* _ASM_UBICOM32_ATOMIC_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/audio_tio.h
+@@ -0,0 +1,124 @@
++/*
++ * arch/ubicom32/include/asm/audio_tio.h
++ *    AudioTIO include file
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef _AUDIO_TIO_H
++#define _AUDIO_TIO_H
++
++#include <asm/devtree.h>
++#include <asm/ubi32-pcm.h>
++
++#define UBI32_AUDIO_INT_FLAG_MORE_SAMPLES 0x00000001
++#define UBI32_AUDIO_INT_FLAG_COMMAND      0x00000002
++
++/*
++ * Commands the Primary OS sends to the audio device
++ */
++enum ubi32_audio_command {
++      UBI32_AUDIO_CMD_NONE,
++      UBI32_AUDIO_CMD_START,
++      UBI32_AUDIO_CMD_STOP,
++      UBI32_AUDIO_CMD_PAUSE,
++      UBI32_AUDIO_CMD_RESUME,
++      UBI32_AUDIO_CMD_MUTE,
++      UBI32_AUDIO_CMD_UNMUTE,
++      UBI32_AUDIO_CMD_SETUP,
++      UBI32_AUDIO_CMD_ENABLE,
++      UBI32_AUDIO_CMD_DISABLE,
++};
++
++/*
++ * Flag bits passed in the registers
++ */
++#define UBI32_CMD_SETUP_FLAG_LE               (1 << 0)        /* Use Little Endian Mode */
++
++/*
++ * Status bits that audio device can set to indicate reason
++ * for interrupting the Primary OS
++ */
++#define UBI32_AUDIO_STATUS_PLAY_DMA0_REQUEST (1 << 0) /* Audio device needs samples in DMA0 for playback */
++#define UBI32_AUDIO_STATUS_PLAY_DMA1_REQUEST (1 << 1) /* Audio device needs samples in DMA1 for playback */
++
++struct ubi32_audio_dma {
++      /*
++       * NOTE: The active flag shall only be SET by the producer and CLEARED
++       * by the consumer, NEVER the other way around.  For playback, the
++       * Primary OS sets this flag and ipAudioTIO clears it.
++       *
++       * The producer shall not modify the ptr or ctr fields when the transfer
++       * is marked as active, as these are used by the consumer to do the
++       * transfer.
++       */
++      volatile uint32_t active;               /* Nonzero if data in ptr/ctr ready to be transferred */
++      //volatile u32_t active;                /* Nonzero if data in ptr/ctr ready to be transferred */
++      volatile void *ptr;             /* Pointer to data to be transferred */
++      volatile uint32_t ctr;  /* Counter: number of data units to transfer */
++      //volatile u32_t ctr;           /* Counter: number of data units to transfer */
++};
++
++#define AUDIOTIONODE_CAP_BE   (1 << 0)
++#define AUDIOTIONODE_CAP_LE   (1 << 1)
++
++/*
++ * Resource indices used to access IRQs via platform_get_resource
++ */
++#define AUDIOTIO_MEM_RESOURCE         0
++#define AUDIOTIO_TX_IRQ_RESOURCE      0
++#define AUDIOTIO_RX_IRQ_RESOURCE      1
++
++#define AUDIOTIONODE_VERSION  5
++struct audiotionode {
++      struct devtree_node dn;
++      uint32_t version;                               /* Version of this node */
++      struct audiotioregs *regs;
++};
++
++#define AUDIOTIOREGS_VERSION  3
++struct audiotioregs {
++      uint32_t version;
++      uint32_t caps;                                  /* Capabilities of the driver */
++      u32_t *sample_rates;                            /* Sample Rates supported by this driver */
++      u32_t n_sample_rates;                           /* Number of sample rates supported by this driver */
++      u32_t channel_mask;                             /* The channel configs supported by this driver (bit 1 = 1 channel, etc) */
++      volatile uint32_t int_flags;                    /* Reason for interrupting audio device */
++      volatile enum ubi32_audio_command command;      /* Command from Primary OS */
++      volatile uint32_t flags;                        /* Flag bits for this command */
++      volatile uint32_t channels;                     /* Number of channels in stream */
++      volatile uint32_t sample_rate;                  /* Sample rate */
++      volatile uint32_t status;                       /* Status bits sent from AudioTIO to Primary OS */
++      volatile void *current_read_pos;                /* Position of next sample to be removed from Primary OS sample buffer */
++
++      /*
++       * These are the transfer requests.  They are used in alternating
++       * order so that when ipAudioTIO is processing one request, the
++       * Primary OS can fill in the other one.
++       *
++       * NOTE: The active bit shall always be SET by the producer and
++       * CLEARED by the consumer, NEVER the other way around.
++       */
++      struct ubi32_audio_dma playback_xfer_requests[2];
++};
++
++extern struct platform_device * __init audio_tio_alloc(const char *driver_name, const char *node_name, int priv_size);
++
++#define audio_tio_priv(pdev) (((struct ubi32pcm_platform_data *)(((struct platform_device *)(pdev))->dev.platform_data))->priv_data)
++#endif
+--- /dev/null
++++ b/arch/ubicom32/include/asm/auxvec.h
+@@ -0,0 +1,32 @@
++/*
++ * arch/ubicom32/include/asm/auxvec.h
++ *   Symbolic values for the entries in the auxiliary table
++ *   put on the initial stack.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_AUXVEC_H
++#define _ASM_UBICOM32_AUXVEC_H
++
++#endif /* _ASM_UBICOM32_AUXVEC_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/bitops.h
+@@ -0,0 +1,171 @@
++/*
++ * arch/ubicom32/include/asm/bitops.h
++ *   Bit manipulation definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BITOPS_H
++#define _ASM_UBICOM32_BITOPS_H
++
++/*
++ * Copyright 1992, Linus Torvalds.
++ */
++
++#include <linux/compiler.h>
++#include <asm/byteorder.h>    /* swab32 */
++
++#ifdef __KERNEL__
++
++#ifndef _LINUX_BITOPS_H
++#error only <linux/bitops.h> can be included directly
++#endif
++
++#include <asm-generic/bitops/ffs.h>
++#include <asm-generic/bitops/__ffs.h>
++
++#include <asm-generic/bitops/sched.h>
++#include <asm-generic/bitops/ffz.h>
++
++#include <asm/ubicom32-common.h>
++
++static inline void set_bit(int bit, volatile unsigned long *p)
++{
++      unsigned long mask = 1UL << (bit & 31);
++
++      p += bit >> 5;
++
++      __atomic_lock_acquire();
++      *p |= mask;
++      __atomic_lock_release();
++}
++
++static inline void clear_bit(int bit, volatile unsigned long *p)
++{
++      unsigned long mask = 1UL << (bit & 31);
++
++      p += bit >> 5;
++
++      __atomic_lock_acquire();
++      *p &= ~mask;
++      __atomic_lock_release();
++}
++
++/*
++ * clear_bit() doesn't provide any barrier for the compiler.
++ */
++#define smp_mb__before_clear_bit()    barrier()
++#define smp_mb__after_clear_bit()     barrier()
++
++static inline void change_bit(int bit, volatile unsigned long *p)
++{
++      unsigned long mask = 1UL << (bit & 31);
++
++      p += bit >> 5;
++
++      __atomic_lock_acquire();
++      *p ^= mask;
++      __atomic_lock_release();
++}
++
++static inline int test_and_set_bit(int bit, volatile unsigned long *p)
++{
++      unsigned int res;
++      unsigned long mask = 1UL << (bit & 31);
++
++      p += bit >> 5;
++
++      __atomic_lock_acquire();
++      res = *p;
++      *p = res | mask;
++      __atomic_lock_release();
++
++      return res & mask;
++}
++
++static inline int test_and_clear_bit(int bit, volatile unsigned long *p)
++{
++      unsigned int res;
++      unsigned long mask = 1UL << (bit & 31);
++
++      p += bit >> 5;
++
++      __atomic_lock_acquire();
++      res = *p;
++      *p = res & ~mask;
++      __atomic_lock_release();
++
++      return res & mask;
++}
++
++static inline int test_and_change_bit(int bit, volatile unsigned long *p)
++{
++      unsigned int res;
++      unsigned long mask = 1UL << (bit & 31);
++
++      p += bit >> 5;
++
++      __atomic_lock_acquire();
++      res = *p;
++      *p = res ^ mask;
++      __atomic_lock_release();
++
++      return res & mask;
++}
++
++#include <asm-generic/bitops/non-atomic.h>
++
++/*
++ * This routine doesn't need to be atomic.
++ */
++static inline int __constant_test_bit(int nr, const volatile unsigned long *addr)
++{
++      return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
++}
++
++static inline int __test_bit(int nr, const volatile unsigned long *addr)
++{
++      int     * a = (int *) addr;
++      int     mask;
++
++      a += nr >> 5;
++      mask = 1 << (nr & 0x1f);
++      return ((mask & *a) != 0);
++}
++
++#define test_bit(nr,addr) (__builtin_constant_p(nr) ?  __constant_test_bit((nr),(addr)) :  __test_bit((nr),(addr)))
++
++#include <asm-generic/bitops/find.h>
++#include <asm-generic/bitops/hweight.h>
++#include <asm-generic/bitops/lock.h>
++
++#include <asm-generic/bitops/ext2-non-atomic.h>
++#include <asm-generic/bitops/ext2-atomic.h>
++#include <asm-generic/bitops/minix.h>
++
++#endif /* __KERNEL__ */
++
++#include <asm-generic/bitops/fls.h>
++#include <asm-generic/bitops/fls64.h>
++
++#endif /* _ASM_UBICOM32_BITOPS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/board.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/board.h
++ *   Board init and revision definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BOARD_H
++#define _ASM_UBICOM32_BOARD_H
++
++extern const char *board_get_revision(void);
++extern void __init board_init(void);
++
++#endif /* _ASM_UBICOM32_BOARD_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/bootargs.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/bootargs.h
++ *   Kernel command line via the devtree API.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BOOTARGS_H
++#define _ASM_UBICOM32_BOOTARGS_H
++
++extern const char *bootargs_get_cmdline(void);
++extern void __init bootargs_init(void);
++
++#endif /* _ASM_UBICOM32_BOOTARGS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/bootinfo.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/bootinfo.h
++ *   Definitions of firmware boot parameters passed to the kernel.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_BOOTINFO_H
++#define _ASM_UBICOM32_BOOTINFO_H
++
++/* Nothing for ubicom32 */
++
++#endif /* _ASM_UBICOM32_BOOTINFO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/bug.h
+@@ -0,0 +1,53 @@
++/*
++ * arch/ubicom32/include/asm/bug.h
++ *   Generic bug.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BUG_H
++#define _ASM_UBICOM32_BUG_H
++
++#include <linux/kernel.h>
++#include <asm/thread.h>
++
++#if defined(CONFIG_STOP_ON_BUG)
++/*
++ *  __BUG_ON()
++ *    Stall all threads to enable debugging.
++ */
++static inline void __BUG_ON(unsigned long c)
++{
++      if (unlikely(c)) {
++              THREAD_STALL;
++      }
++      return;
++}
++
++#define BUG_ON(c) __BUG_ON((unsigned long)(c))
++#define HAVE_ARCH_BUG_ON
++#endif
++
++#include <asm-generic/bug.h>
++
++#endif /* _ASM_UBICOM32_BUG_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/bugs.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/ubicom32/include/asm/bugs.h
++ *   Definition of check_bugs() for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 1994  Linus Torvalds
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++/*
++ * This is included by init/main.c to check for architecture-dependent bugs.
++ *
++ * Needs:
++ *    void check_bugs(void);
++ */
++
++#ifndef _ASM_UBICOM32_BUGS_H
++#define _ASM_UBICOM32_BUGS_H
++
++static void check_bugs(void)
++{
++}
++
++#endif /* _ASM_UBICOM32_BUGS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/byteorder.h
+@@ -0,0 +1,48 @@
++/*
++ * arch/ubicom32/include/asm/byteorder.h
++ *   Byte order swapping utility routines.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BYTEORDER_H
++#define _ASM_UBICOM32_BYTEORDER_H
++
++#include <linux/types.h>
++
++#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
++#  define __BYTEORDER_HAS_U64__
++#  define __SWAB_64_THRU_32__
++#endif
++
++#if defined(IP7000) || defined(IP7000_REV2)
++
++#define __arch__swab16 __builtin_ubicom32_swapb_2
++#define __arch__swab32 __builtin_ubicom32_swapb_4
++
++#endif /* IP7000 */
++
++#include <linux/byteorder/big_endian.h>
++
++#endif /* _ASM_UBICOM32_BYTEORDER_H */
++
+--- /dev/null
++++ b/arch/ubicom32/include/asm/cachectl.h
+@@ -0,0 +1,39 @@
++/*
++ * arch/ubicom32/include/asm/cachectl.h
++ *   Ubicom32 cache control definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CACHECTL_H
++#define _ASM_UBICOM32_CACHECTL_H
++
++#include <asm/ip5000.h>
++
++/*
++ * mem_cache_control()
++ *    Special cache control operation
++ */
++extern void mem_cache_control(unsigned long cc, unsigned long begin_addr, unsigned long end_addr, unsigned long op);
++
++#endif /* _ASM_UBICOM32_CACHECTL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/cacheflush.h
+@@ -0,0 +1,104 @@
++/*
++ * arch/ubicom32/include/asm/cacheflush.h
++ *   Cache flushing definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CACHEFLUSH_H
++#define _ASM_UBICOM32_CACHEFLUSH_H
++
++/*
++ * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com>
++ */
++#include <linux/mm.h>
++#include <asm/cachectl.h>
++#include <asm/ip5000.h>
++
++#define flush_cache_all()                     __flush_cache_all()
++#define flush_cache_mm(mm)                    do { } while (0)
++#define flush_cache_dup_mm(mm)                        do { } while (0)
++#define flush_cache_range(vma, start, end)    __flush_cache_all()
++#define flush_cache_page(vma, vmaddr)         do { } while (0)
++#define flush_dcache_page(page)                       do { } while (0)
++#define flush_dcache_mmap_lock(mapping)               do { } while (0)
++#define flush_dcache_mmap_unlock(mapping)     do { } while (0)
++
++#define flush_dcache_range(start, end)                                        \
++do {                                                                  \
++      /* Flush the data cache and invalidate the I cache. */          \
++      local_irq_disable();                                            \
++      mem_cache_control(DCCR_BASE, start, end, CCR_CTRL_FLUSH_ADDR);  \
++      mem_cache_control(ICCR_BASE, start, end, CCR_CTRL_INV_ADDR);    \
++      local_irq_enable();                                             \
++} while (0)
++
++#define flush_icache_range(start, end)                                        \
++do {                                                                  \
++      /* Flush the data cache and invalidate the I cache. */          \
++      local_irq_disable();                                            \
++      mem_cache_control(DCCR_BASE, start, end, CCR_CTRL_FLUSH_ADDR);  \
++      mem_cache_control(ICCR_BASE, start, end, CCR_CTRL_INV_ADDR);    \
++      local_irq_enable();                                             \
++} while (0)
++
++#define flush_icache_page(vma,pg)             do { } while (0)
++#define flush_icache_user_range(vma,pg,adr,len)       do { } while (0)
++#define flush_cache_vmap(start, end)          do { } while (0)
++#define flush_cache_vunmap(start, end)                do { } while (0)
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
++      memcpy(dst, src, len)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
++      memcpy(dst, src, len)
++
++/*
++ * Cache handling for IP5000
++ */
++extern inline void mem_cache_invalidate_all(unsigned long cc)
++{
++      asm volatile (
++      "       bset    "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_RESET)"      \n\t"
++      "       nop                                                                     \n\t"
++      "       bclr    "D(CCR_CTRL)"(%0), "D(CCR_CTRL)"(%0), #"D(CCR_CTRL_RESET)"      \n\t"
++      "       pipe_flush 0                                                            \n\t"
++              :
++              : "a"(cc)
++              : "cc"
++      );
++}
++
++static inline void __flush_cache_all(void)
++{
++      /*
++       * Flush Icache
++       */
++      mem_cache_invalidate_all(ICCR_BASE);
++
++      /*
++       * Flush Dcache
++       */
++      mem_cache_invalidate_all(DCCR_BASE);
++}
++
++#endif /* _ASM_UBICOM32_CACHEFLUSH_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/cache.h
+@@ -0,0 +1,40 @@
++/*
++ * arch/ubicom32/include/asm/cache.h
++ *   Cache line definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CACHE_H
++#define _ASM_UBICOM32_CACHE_H
++
++/*
++ * bytes per L1 cache line
++ */
++#define L1_CACHE_SHIFT  5
++#define L1_CACHE_BYTES  (1 << L1_CACHE_SHIFT)
++
++#define __cacheline_aligned
++#define ____cacheline_aligned
++
++#endif /* _ASM_UBICOM32_CACHE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/checksum.h
+@@ -0,0 +1,149 @@
++/*
++ * arch/ubicom32/include/asm/checksum.h
++ *   Checksum utilities for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CHECKSUM_H
++#define _ASM_UBICOM32_CHECKSUM_H
++
++#include <linux/in6.h>
++
++/*
++ * computes the checksum of a memory block at buff, length len,
++ * and adds in "sum" (32-bit)
++ *
++ * returns a 32-bit number suitable for feeding into itself
++ * or csum_tcpudp_magic
++ *
++ * this function must be called with even lengths, except
++ * for the last fragment, which may be odd
++ *
++ * it's best to have buff aligned on a 32-bit boundary
++ */
++__wsum csum_partial(const void *buff, int len, __wsum sum);
++
++/*
++ * the same as csum_partial, but copies from src while it
++ * checksums
++ *
++ * here even more important to align src and dst on a 32-bit (or even
++ * better 64-bit) boundary
++ */
++
++__wsum csum_partial_copy_nocheck(const void *src, void *dst,
++      int len, __wsum sum);
++
++
++/*
++ * the same as csum_partial_copy, but copies from user space.
++ *
++ * here even more important to align src and dst on a 32-bit (or even
++ * better 64-bit) boundary
++ */
++
++extern __wsum csum_partial_copy_from_user(const void __user *src,
++      void *dst, int len, __wsum sum, int *csum_err);
++
++__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
++
++/*
++ *    Fold a partial checksum
++ */
++
++static inline __sum16 csum_fold(__wsum sum)
++{
++      asm volatile (
++      "       lsr.4   d15, %0, #16    \n\t"
++      "       bfextu  %0, %0, #16     \n\t"
++      "       add.4   %0, d15, %0     \n\t"
++      "       lsr.4   d15, %0, #16    \n\t"
++      "       bfextu  %0, %0, #16     \n\t"
++      "       add.4   %0, d15, %0     \n\t"
++              : "=&d" (sum)
++              : "0"(sum)
++              : "d15"
++      );
++      return (__force __sum16)~sum;
++}
++
++
++/*
++ * computes the checksum of the TCP/UDP pseudo-header
++ * returns a 16-bit checksum, already complemented
++ */
++
++static inline __wsum
++csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
++                unsigned short proto, __wsum sum)
++{
++      asm volatile (
++      "       add.4   %0, %2, %0      \n\t"
++      "       addc    %0, %3, %0      \n\t"
++      "       addc    %0, %4, %0      \n\t"
++      "       addc    %0, %5, %0      \n\t"
++      "       addc    %0, #0, %0      \n\t"
++              : "=&d" (sum)
++              : "0"(sum), "r" (saddr), "r" (daddr), "r" (len), "r"(proto)
++      );
++      return sum;
++}
++
++static inline __sum16
++csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
++                unsigned short proto, __wsum sum)
++{
++      return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
++}
++
++/*
++ * this routine is used for miscellaneous IP-like checksums, mainly
++ * in icmp.c
++ */
++extern __sum16 ip_compute_csum(const void *buff, int len);
++
++#define _HAVE_ARCH_IPV6_CSUM
++
++static __inline__ __sum16
++csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
++              __u32 len, unsigned short proto, __wsum sum)
++{
++      asm volatile (
++      "       add.4   %0, 0(%2), %0   \n\t"
++      "       addc    %0, 4(%2), %0   \n\t"
++      "       addc    %0, 8(%2), %0   \n\t"
++      "       addc    %0, 12(%2), %0  \n\t"
++      "       addc    %0, 0(%3), %0   \n\t"
++      "       addc    %0, 4(%3), %0   \n\t"
++      "       addc    %0, 8(%3), %0   \n\t"
++      "       addc    %0, 12(%3), %0  \n\t"
++      "       addc    %0, %4, %0      \n\t"
++      "       addc    %0, #0, %0      \n\t"
++              : "=&d" (sum)
++              : "0" (sum), "a" (saddr), "a" (daddr), "d" (len + proto)
++      );
++      return csum_fold(sum);
++}
++
++#endif /* _ASM_UBICOM32_CHECKSUM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/cpu.h
+@@ -0,0 +1,45 @@
++/*
++ * arch/ubicom32/include/asm/cpu.h
++ *   CPU definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 2004-2005 ARM Ltd.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CPU_H
++#define _ASM_UBICOM32_CPU_H
++
++#include <linux/percpu.h>
++
++struct cpuinfo_ubicom32 {
++      unsigned long tid;                      /* Hardware thread number */
++
++#ifdef CONFIG_SMP
++      volatile unsigned long ipi_pending;     /* Bit map of operations to execute */
++      unsigned long ipi_count;                /* Number of IPI(s) taken on this cpu */
++#endif
++};
++
++DECLARE_PER_CPU(struct cpuinfo_ubicom32, cpu_data);
++
++#endif /* _ASM_UBICOM32_CPU_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/cputime.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/cputime.h
++ *   Generic cputime.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CPUTIME_H
++#define _ASM_UBICOM32_CPUTIME_H
++
++#include <asm-generic/cputime.h>
++
++#endif /* _ASM_UBICOM32_CPUTIME_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/current.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/ubicom32/include/asm/current.h
++ *   Definition of get_current() for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * (C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
++ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CURRENT_H
++#define _ASM_UBICOM32_CURRENT_H
++
++#include <linux/thread_info.h>
++
++struct task_struct;
++
++static inline struct task_struct *get_current(void)
++{
++      return(current_thread_info()->task);
++}
++
++#define       current get_current()
++
++#endif /* _ASM_UBICOM32_CURRENT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/delay.h
+@@ -0,0 +1,75 @@
++/*
++ * arch/ubicom32/include/asm/delay.h
++ *   Definition of delay routines for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DELAY_H
++#define _ASM_UBICOM32_DELAY_H
++
++#include <asm/param.h>
++#include <asm/ip5000.h>
++
++static inline void __delay(unsigned long loops)
++{
++      if (loops == 0) {
++              return;
++      }
++
++      asm volatile (
++      "1:     add.4   %0, #-1, %0             \n\t"
++      "       jmpne.t 1b                      \n\t"
++      : "+d" (loops)
++      );
++}
++
++/*
++ *    Ubicom32 processor uses fixed 12MHz external OSC.
++ *    So we use that as reference to count 12 cycles/us
++ */
++
++extern unsigned long loops_per_jiffy;
++
++static inline void _udelay(unsigned long usecs)
++{
++#if defined(CONFIG_UBICOM32_V4) || defined(CONFIG_UBICOM32_V3)
++      asm volatile (
++              "       add.4           d15, 0(%0), %1                  \n\t"
++              "       sub.4           #0, 0(%0), d15                  \n\t"
++              "       jmpmi.w.f       .-4                             \n\t"
++              :
++              : "a"(TIMER_BASE + TIMER_MPTVAL), "d"(usecs * (12000000/1000000))
++              : "d15"
++      );
++#else
++      BUG();
++#endif
++}
++
++/*
++ *    Moved the udelay() function into library code, no longer inlined.
++ */
++extern void udelay(unsigned long usecs);
++
++#endif /* _ASM_UBICOM32_DELAY_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/device.h
+@@ -0,0 +1,35 @@
++/*
++ * arch/ubicom32/include/asm/device.h
++ *   Generic device.h for Ubicom32 architecture.
++ *
++ *   Used for arch specific extensions to struct device
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DEVICE_H
++#define _ASM_UBICOM32_DEVICE_H
++
++#include <asm-generic/device.h>
++
++#endif /* _ASM_UBICOM32_DEVICE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/devtree.h
+@@ -0,0 +1,52 @@
++/*
++ * arch/ubicom32/include/asm/devtree.h
++ *   Device Tree Header File (Shared between ultra and the Host OS)
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_DEVTREE_H
++#define _ASM_UBICOM32_DEVTREE_H
++
++#define DEVTREE_MAX_NAME 32
++#define DEVTREE_IRQ_NONE 0xff
++#define DEVTREE_IRQ_DONTCARE 0xff
++#define DEVTREE_NODE_MAGIC 0x10203040
++
++struct devtree_node {
++      struct devtree_node *next;
++      unsigned char sendirq;
++      unsigned char recvirq;
++      char name[DEVTREE_MAX_NAME];
++      unsigned int magic;
++};
++
++extern struct devtree_node *devtree;
++extern struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq);
++extern struct devtree_node *devtree_find_node(const char *str);
++extern struct devtree_node *devtree_find_next(struct devtree_node **cur);
++extern int devtree_irq(struct devtree_node *dn, unsigned char *sendirq, unsigned char *recvirq);
++extern void devtree_print(void);
++
++#endif /* _ASM_UBICOM32_DEVTREE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/div64.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/div64.h
++ *   Generic div64.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DIV64_H
++#define _ASM_UBICOM32_DIV64_H
++
++#include <asm-generic/div64.h>
++
++#endif /* _ASM_UBICOM32_DIV64_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/dma.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/dma.h
++ *   DMA definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DMA_H
++#define _ASM_UBICOM32_DMA_H
++
++/* Nothing so far */
++#define MAX_DMA_ADDRESS 0x00  /* This is quite suspicious */
++
++#endif /* _ASM_UBICOM32_DMA_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/dma-mapping.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/dma-mapping.h
++ *   Generic dma-mapping.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DMA_MAPPING_H
++#define _ASM_UBICOM32_DMA_MAPPING_H
++
++#include <linux/scatterlist.h>
++#include <asm-generic/dma-mapping.h>
++
++#endif /* _ASM_UBICOM32_DMA_MAPPING_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/elf.h
+@@ -0,0 +1,167 @@
++/*
++ * arch/ubicom32/include/asm/elf.h
++ *   Definitions for elf executable format for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ELF_H
++#define _ASM_UBICOM32_ELF_H
++
++/*
++ * ELF register definitions..
++ */
++
++#include <asm/ptrace.h>
++#include <asm/user.h>
++
++/*
++ * Processor specific flags for the ELF header e_flags field.
++ */
++#define EF_UBICOM32_V3                0x00000001      /* -fmarch=ubicom32v3 */
++#define EF_UBICOM32_V4                0x00000002      /* -fmarch=ubicom32v4 */
++#define EF_UBICOM32_PIC               0x80000000      /* -fpic */
++#define EF_UBICOM32_FDPIC     0x40000000      /* -mfdpic */
++
++/*
++ * Ubicom32 ELF relocation types
++ */
++#define R_UBICOM32_NONE                       0
++#define R_UBICOM32_16                 1
++#define R_UBICOM32_32                 2
++#define R_UBICOM32_LO16                       3
++#define R_UBICOM32_HI16                       4
++#define R_UBICOM32_21_PCREL           5
++#define R_UBICOM32_24_PCREL           6
++#define R_UBICOM32_HI24                       7
++#define R_UBICOM32_LO7_S              8
++#define R_UBICOM32_LO7_2_S            9
++#define R_UBICOM32_LO7_4_S            10
++#define R_UBICOM32_LO7_D              11
++#define R_UBICOM32_LO7_2_D            12
++#define R_UBICOM32_LO7_4_D            13
++#define R_UBICOM32_32_HARVARD         14
++#define R_UBICOM32_LO7_CALLI          15
++#define R_UBICOM32_LO16_CALLI         16
++#define R_UBICOM32_GOT_HI24           17
++#define R_UBICOM32_GOT_LO7_S          18
++#define R_UBICOM32_GOT_LO7_2_S                19
++#define R_UBICOM32_GOT_LO7_4_S                20
++#define R_UBICOM32_GOT_LO7_D          21
++#define R_UBICOM32_GOT_LO7_2_D                22
++#define R_UBICOM32_GOT_LO7_4_D                23
++#define R_UBICOM32_FUNCDESC_GOT_HI24    24
++#define R_UBICOM32_FUNCDESC_GOT_LO7_S   25
++#define R_UBICOM32_FUNCDESC_GOT_LO7_2_S 26
++#define R_UBICOM32_FUNCDESC_GOT_LO7_4_S 27
++#define R_UBICOM32_FUNCDESC_GOT_LO7_D   28
++#define R_UBICOM32_FUNCDESC_GOT_LO7_2_D 29
++#define R_UBICOM32_FUNCDESC_GOT_LO7_4_D 30
++#define R_UBICOM32_GOT_LO7_CALLI        31
++#define R_UBICOM32_FUNCDESC_GOT_LO7_CALLI 32
++#define R_UBICOM32_FUNCDESC_VALUE       33
++#define R_UBICOM32_FUNCDESC             34
++#define R_UBICOM32_GOTOFFSET_LO         35
++#define R_UBICOM32_GOTOFFSET_HI         36
++#define R_UBICOM32_FUNCDESC_GOTOFFSET_LO 37
++#define R_UBICOM32_FUNCDESC_GOTOFFSET_HI 38
++#define R_UBICOM32_GNU_VTINHERIT        200
++#define R_UBICOM32_GNU_VTENTRY          201
++
++typedef unsigned long elf_greg_t;
++
++#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++typedef struct user_ubicom32fp_struct elf_fpregset_t;
++
++/*
++ * This is used to ensure we don't load something for the wrong architecture.
++ */
++#define elf_check_arch(x) ((x)->e_machine == EM_UBICOM32)
++
++#define elf_check_fdpic(x) ((x)->e_flags & EF_UBICOM32_FDPIC)
++
++#define elf_check_const_displacement(x) ((x)->e_flags & EF_UBICOM32_PIC)
++
++/*
++ * These are used to set parameters in the core dumps.
++ */
++#define ELF_CLASS     ELFCLASS32
++#define ELF_DATA      ELFDATA2MSB
++#define ELF_ARCH      EM_UBICOM32
++
++/* For SVR4/m68k the function pointer to be registered with `atexit' is
++   passed in %a1.  Although my copy of the ABI has no such statement, it
++   is actually used on ASV.  */
++#define ELF_PLAT_INIT(_r, load_addr)  _r->a1 = 0
++
++#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr,  \
++                          _dynamic_addr)                              \
++      do {                                                            \
++              _regs->dn[1]    = _exec_map_addr;                       \
++              _regs->dn[2]    = _interp_map_addr;                     \
++              _regs->dn[3]    = _dynamic_addr;                        \
++              _regs->an[1]    = 0; /* dl_fini will be set by ldso */  \
++      } while (0)
++
++#define USE_ELF_CORE_DUMP
++#define ELF_EXEC_PAGESIZE     4096
++
++#ifdef __KERNEL__
++#ifdef CONFIG_UBICOM32_V4
++#define ELF_FDPIC_CORE_EFLAGS (EF_UBICOM32_FDPIC | EF_UBICOM32_V4)
++#elif defined CONFIG_UBICOM32_V3
++#define ELF_FDPIC_CORE_EFLAGS (EF_UBICOM32_FDPIC | EF_UBICOM32_V3)
++#else
++#error Unknown/Unsupported ubicom32 architecture.
++#endif
++#endif
++
++/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
++   use of this is to invoke "./ld.so someprog" to test out a new version of
++   the loader.  We need to make sure that it is out of the way of the program
++   that it will "exec", and that there is sufficient room for the brk.  */
++
++#define ELF_ET_DYN_BASE         0xD0000000UL
++
++/*
++ * For Ubicom32, the elf_gregset_t and struct pt_regs are the same size
++ * data structure so a copy is performed instead of providing the
++ * ELF_CORE_COPY_REGS macro.
++ */
++
++/* This yields a mask that user programs can use to figure out what
++   instruction set this cpu supports.  */
++
++#define ELF_HWCAP     (0)
++
++/* This yields a string that ld.so will use to load implementation
++   specific libraries for optimization.  This is more specific in
++   intent than poking at uname or /proc/cpuinfo.  */
++
++#define ELF_PLATFORM  (NULL)
++
++#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
++
++#endif /* _ASM_UBICOM32_ELF_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/elf.h~
+@@ -0,0 +1,165 @@
++/*
++ * arch/ubicom32/include/asm/elf.h
++ *   Definitions for elf executable format for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ELF_H
++#define _ASM_UBICOM32_ELF_H
++
++/*
++ * ELF register definitions..
++ */
++
++#include <asm/ptrace.h>
++#include <asm/user.h>
++
++/*
++ * Processor specific flags for the ELF header e_flags field.
++ */
++#define EF_UBICOM32_V3                0x00000001      /* -fmarch=ubicom32v3 */
++#define EF_UBICOM32_V4                0x00000002      /* -fmarch=ubicom32v4 */
++#define EF_UBICOM32_PIC               0x80000000      /* -fpic */
++#define EF_UBICOM32_FDPIC     0x40000000      /* -mfdpic */
++
++/*
++ * Ubicom32 ELF relocation types
++ */
++#define R_UBICOM32_NONE                       0
++#define R_UBICOM32_16                 1
++#define R_UBICOM32_32                 2
++#define R_UBICOM32_LO16                       3
++#define R_UBICOM32_HI16                       4
++#define R_UBICOM32_21_PCREL           5
++#define R_UBICOM32_24_PCREL           6
++#define R_UBICOM32_HI24                       7
++#define R_UBICOM32_LO7_S              8
++#define R_UBICOM32_LO7_2_S            9
++#define R_UBICOM32_LO7_4_S            10
++#define R_UBICOM32_LO7_D              11
++#define R_UBICOM32_LO7_2_D            12
++#define R_UBICOM32_LO7_4_D            13
++#define R_UBICOM32_32_HARVARD         14
++#define R_UBICOM32_LO7_CALLI          15
++#define R_UBICOM32_LO16_CALLI         16
++#define R_UBICOM32_GOT_HI24           17
++#define R_UBICOM32_GOT_LO7_S          18
++#define R_UBICOM32_GOT_LO7_2_S                19
++#define R_UBICOM32_GOT_LO7_4_S                20
++#define R_UBICOM32_GOT_LO7_D          21
++#define R_UBICOM32_GOT_LO7_2_D                22
++#define R_UBICOM32_GOT_LO7_4_D                23
++#define R_UBICOM32_FUNCDESC_GOT_HI24    24
++#define R_UBICOM32_FUNCDESC_GOT_LO7_S   25
++#define R_UBICOM32_FUNCDESC_GOT_LO7_2_S 26
++#define R_UBICOM32_FUNCDESC_GOT_LO7_4_S 27
++#define R_UBICOM32_FUNCDESC_GOT_LO7_D   28
++#define R_UBICOM32_FUNCDESC_GOT_LO7_2_D 29
++#define R_UBICOM32_FUNCDESC_GOT_LO7_4_D 30
++#define R_UBICOM32_GOT_LO7_CALLI        31
++#define R_UBICOM32_FUNCDESC_GOT_LO7_CALLI 32
++#define R_UBICOM32_FUNCDESC_VALUE       33
++#define R_UBICOM32_FUNCDESC             34
++#define R_UBICOM32_GOTOFFSET_LO         35
++#define R_UBICOM32_GOTOFFSET_HI         36
++#define R_UBICOM32_FUNCDESC_GOTOFFSET_LO 37
++#define R_UBICOM32_FUNCDESC_GOTOFFSET_HI 38
++#define R_UBICOM32_GNU_VTINHERIT        200
++#define R_UBICOM32_GNU_VTENTRY          201
++
++typedef unsigned long elf_greg_t;
++
++#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++typedef struct user_ubicom32fp_struct elf_fpregset_t;
++
++/*
++ * This is used to ensure we don't load something for the wrong architecture.
++ */
++#define elf_check_arch(x) ((x)->e_machine == EM_UBICOM32)
++
++#define elf_check_fdpic(x) ((x)->e_flags & EF_UBICOM32_FDPIC)
++
++#define elf_check_const_displacement(x) ((x)->e_flags & EF_UBICOM32_PIC)
++
++/*
++ * These are used to set parameters in the core dumps.
++ */
++#define ELF_CLASS     ELFCLASS32
++#define ELF_DATA      ELFDATA2MSB
++#define ELF_ARCH      EM_UBICOM32
++
++/* For SVR4/m68k the function pointer to be registered with `atexit' is
++   passed in %a1.  Although my copy of the ABI has no such statement, it
++   is actually used on ASV.  */
++#define ELF_PLAT_INIT(_r, load_addr)  _r->a1 = 0
++
++#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr,  \
++                          _dynamic_addr)                              \
++      do {                                                            \
++              _regs->dn[1]    = _exec_map_addr;                       \
++              _regs->dn[2]    = _interp_map_addr;                     \
++              _regs->dn[3]    = _dynamic_addr;                        \
++              _regs->an[1]    = 0; /* dl_fini will be set by ldso */  \
++      } while (0)
++
++#define USE_ELF_CORE_DUMP
++#define ELF_EXEC_PAGESIZE     4096
++
++#ifdef CONFIG_UBICOM32_V4
++#define ELF_FDPIC_CORE_EFLAGS (EF_UBICOM32_FDPIC | EF_UBICOM32_V4)
++#elif defined CONFIG_UBICOM32_V3
++#define ELF_FDPIC_CORE_EFLAGS (EF_UBICOM32_FDPIC | EF_UBICOM32_V3)
++#else
++#error Unknown/Unsupported ubicom32 architecture.
++#endif
++
++/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
++   use of this is to invoke "./ld.so someprog" to test out a new version of
++   the loader.  We need to make sure that it is out of the way of the program
++   that it will "exec", and that there is sufficient room for the brk.  */
++
++#define ELF_ET_DYN_BASE         0xD0000000UL
++
++/*
++ * For Ubicom32, the elf_gregset_t and struct pt_regs are the same size
++ * data structure so a copy is performed instead of providing the
++ * ELF_CORE_COPY_REGS macro.
++ */
++
++/* This yields a mask that user programs can use to figure out what
++   instruction set this cpu supports.  */
++
++#define ELF_HWCAP     (0)
++
++/* This yields a string that ld.so will use to load implementation
++   specific libraries for optimization.  This is more specific in
++   intent than poking at uname or /proc/cpuinfo.  */
++
++#define ELF_PLATFORM  (NULL)
++
++#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
++
++#endif /* _ASM_UBICOM32_ELF_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/emergency-restart.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/emergency-restart.h
++ *   Generic emergency-restart.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_EMERGENCY_RESTART_H
++#define _ASM_UBICOM32_EMERGENCY_RESTART_H
++
++#include <asm-generic/emergency-restart.h>
++
++#endif /* _ASM_UBICOM32_EMERGENCY_RESTART_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/entry.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/entry.h
++ *   Entry register/stack definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ENTRY_H
++#define _ASM_UBICOM32_ENTRY_H
++
++#include <asm/setup.h>
++#include <asm/page.h>
++
++#endif /* _ASM_UBICOM32_ENTRY_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/errno.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/errno.h
++ *   Generic errno.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ERRNO_H
++#define _ASM_UBICOM32_ERRNO_H
++
++#include <asm-generic/errno.h>
++
++#endif /* _ASM_UBICOM32_ERRNO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/fb.h
+@@ -0,0 +1,39 @@
++/*
++ * arch/ubicom32/include/asm/fb.h
++ *   Definition of fb_is_primary_device() for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_FB_H
++#define _ASM_UBICOM32_FB_H
++#include <linux/fb.h>
++
++#define fb_pgprotect(...) do {} while (0)
++
++static inline int fb_is_primary_device(struct fb_info *info)
++{
++      return 0;
++}
++
++#endif /* _ASM_UBICOM32_FB_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/fcntl.h
+@@ -0,0 +1,38 @@
++/*
++ * arch/ubicom32/include/asm/fcntl.h
++ *   File control bit definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_FCNTL_H
++#define _ASM_UBICOM32_FCNTL_H
++
++#define O_DIRECTORY   040000  /* must be a directory */
++#define O_NOFOLLOW    0100000 /* don't follow links */
++#define O_DIRECT      0200000 /* direct disk access hint - currently ignored */
++#define O_LARGEFILE   0400000
++
++#include <asm-generic/fcntl.h>
++
++#endif /* _ASM_UBICOM32_FCNTL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/flat.h
+@@ -0,0 +1,73 @@
++/*
++ * arch/ubicom32/include/asm/flat.h
++ *   Definitions to support flat-format executables.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_FLAT_H
++#define _ASM_UBICOM32_FLAT_H
++
++#define ARCH_FLAT_ALIGN 0x80
++#define ARCH_FLAT_ALIGN_TEXT 1
++
++#define  R_UBICOM32_32                2
++#define  R_UBICOM32_HI24      7
++#define  R_UBICOM32_LO7_S     8
++#define  R_UBICOM32_LO7_2_S   9
++#define  R_UBICOM32_LO7_4_S   10
++#define  R_UBICOM32_LO7_D     11
++#define  R_UBICOM32_LO7_2_D   12
++#define  R_UBICOM32_LO7_4_D   13
++#define  R_UBICOM32_LO7_CALLI 15
++#define  R_UBICOM32_LO16_CALLI        16
++
++extern void ubicom32_flat_put_addr_at_rp(unsigned long *rp, u32_t val, u32_t rval, unsigned long  *p);
++extern unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp, u32_t relval, u32_t flags, unsigned long *p);
++
++#define       flat_stack_align(sp)                    /* nothing needed */
++#define       flat_argvp_envp_on_stack()              1
++#define       flat_old_ram_flag(flags)                (flags)
++#define       flat_reloc_valid(reloc, size)           ((reloc) <= (size))
++#define       flat_get_addr_from_rp(rp, relval, flags, p)     (ubicom32_flat_get_addr_from_rp(rp, relval,flags, p))
++#define       flat_put_addr_at_rp(rp, val, relval)    do {ubicom32_flat_put_addr_at_rp(rp, val, relval, &persistent);} while(0)
++#define       flat_get_relocate_addr(rel)             ((persistent) ? (persistent & 0x07ffffff) : (rel & 0x07ffffff))
++
++static inline int flat_set_persistent(unsigned int relval, unsigned long *p)
++{
++      if (*p) {
++              return 0;
++      } else {
++              if ((relval >> 27) != R_UBICOM32_32) {
++                      /*
++                       * Something other than UBICOM32_32. The next entry has the relocation.
++                       */
++                      *p = relval;
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++#endif /* _ASM_UBICOM32_FLAT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/fpu.h
+@@ -0,0 +1,37 @@
++/*
++ * arch/ubicom32/include/asm/fpu.h
++ *   Floating point state definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_FPU_H
++#define _ASM_UBICOM32_FPU_H
++
++/*
++ * MAX floating point unit state size (FSAVE/FRESTORE)
++ */
++/* No FP unit present then... */
++#define FPSTATESIZE (2) /* dummy size */
++
++#endif /* _ASM_UBICOM32_FPU_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/futex.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/futex.h
++ *   Generic futex.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_FUTEX_H
++#define _ASM_UBICOM32_FUTEX_H
++
++#include <asm-generic/futex.h>
++
++#endif /* _ASM_UBICOM32_FUTEX_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/.gitignore
+@@ -0,0 +1 @@
++/ocm_size.h
+--- /dev/null
++++ b/arch/ubicom32/include/asm/gpio.h
+@@ -0,0 +1,451 @@
++/*
++ * arch/ubicom32/include/asm/gpio.h
++ *   Definitions for GPIO operations on Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_GPIO_H
++#define _ASM_UBICOM32_GPIO_H
++
++#include <linux/compiler.h>
++#include <asm/irq.h>
++
++#include <asm/ip5000.h>
++
++#define ARCH_NR_GPIOS          512
++#define MAX_UBICOM_ONCHIP_GPIO   (9 * 32)
++
++/*
++ * Macros for manipulating GPIO numbers
++ */
++#define gpio_bit(gn)                  (1 << (gn & 0x1f))
++#define gpio_bank(gn)                 (gn >> 5)
++
++#define gpio_pin_index(gn)            (gn & 0x1f)
++#define gpio_port_index(gn)           (gn >> 5)
++
++#define GPIO_RA_0    ((32 * 0) + 0)
++#define GPIO_RA_1    ((32 * 0) + 1)
++#define GPIO_RA_2    ((32 * 0) + 2)
++#define GPIO_RA_3    ((32 * 0) + 3)
++#define GPIO_RA_4    ((32 * 0) + 4)
++#define GPIO_RA_5    ((32 * 0) + 5)
++#define GPIO_RA_6    ((32 * 0) + 6)
++#define GPIO_RA_7    ((32 * 0) + 7)
++
++#define GPIO_RB_0    ((32 * 1) + 0)
++#define GPIO_RB_1    ((32 * 1) + 1)
++#define GPIO_RB_2    ((32 * 1) + 2)
++#define GPIO_RB_3    ((32 * 1) + 3)
++#define GPIO_RB_4    ((32 * 1) + 4)
++#define GPIO_RB_5    ((32 * 1) + 5)
++#define GPIO_RB_6    ((32 * 1) + 6)
++#define GPIO_RB_7    ((32 * 1) + 7)
++#define GPIO_RB_8    ((32 * 1) + 8)
++#define GPIO_RB_9    ((32 * 1) + 9)
++#define GPIO_RB_10   ((32 * 1) + 10)
++#define GPIO_RB_11   ((32 * 1) + 11)
++#define GPIO_RB_12   ((32 * 1) + 12)
++#define GPIO_RB_13   ((32 * 1) + 13)
++#define GPIO_RB_14   ((32 * 1) + 14)
++#define GPIO_RB_15   ((32 * 1) + 15)
++#define GPIO_RB_16   ((32 * 1) + 16)
++#define GPIO_RB_17   ((32 * 1) + 17)
++#define GPIO_RB_18   ((32 * 1) + 18)
++#define GPIO_RB_19   ((32 * 1) + 19)
++
++#define GPIO_RC_0    ((32 * 2) + 0)
++#define GPIO_RC_1    ((32 * 2) + 1)
++#define GPIO_RC_2    ((32 * 2) + 2)
++#define GPIO_RC_3    ((32 * 2) + 3)
++#define GPIO_RC_4    ((32 * 2) + 4)
++#define GPIO_RC_5    ((32 * 2) + 5)
++#define GPIO_RC_6    ((32 * 2) + 6)
++#define GPIO_RC_7    ((32 * 2) + 7)
++#define GPIO_RC_8    ((32 * 2) + 8)
++#define GPIO_RC_9    ((32 * 2) + 9)
++#define GPIO_RC_10   ((32 * 2) + 10)
++#define GPIO_RC_11   ((32 * 2) + 11)
++#define GPIO_RC_12   ((32 * 2) + 12)
++#define GPIO_RC_13   ((32 * 2) + 13)
++#define GPIO_RC_14   ((32 * 2) + 14)
++#define GPIO_RC_15   ((32 * 2) + 15)
++#define GPIO_RC_16   ((32 * 2) + 16)
++#define GPIO_RC_17   ((32 * 2) + 17)
++#define GPIO_RC_18   ((32 * 2) + 18)
++#define GPIO_RC_19   ((32 * 2) + 19)
++#define GPIO_RC_20   ((32 * 2) + 20)
++#define GPIO_RC_21   ((32 * 2) + 21)
++#define GPIO_RC_22   ((32 * 2) + 22)
++#define GPIO_RC_23   ((32 * 2) + 23)
++#define GPIO_RC_24   ((32 * 2) + 24)
++#define GPIO_RC_25   ((32 * 2) + 25)
++#define GPIO_RC_26   ((32 * 2) + 26)
++#define GPIO_RC_27   ((32 * 2) + 27)
++#define GPIO_RC_28   ((32 * 2) + 28)
++#define GPIO_RC_29   ((32 * 2) + 29)
++#define GPIO_RC_30   ((32 * 2) + 30)
++#define GPIO_RC_31   ((32 * 2) + 31)
++
++#define GPIO_RD_0    ((32 * 3) + 0)
++#define GPIO_RD_1    ((32 * 3) + 1)
++#define GPIO_RD_2    ((32 * 3) + 2)
++#define GPIO_RD_3    ((32 * 3) + 3)
++#define GPIO_RD_4    ((32 * 3) + 4)
++#define GPIO_RD_5    ((32 * 3) + 5)
++#define GPIO_RD_6    ((32 * 3) + 6)
++#define GPIO_RD_7    ((32 * 3) + 7)
++#define GPIO_RD_8    ((32 * 3) + 8)
++#define GPIO_RD_9    ((32 * 3) + 9)
++#define GPIO_RD_10   ((32 * 3) + 10)
++#define GPIO_RD_11   ((32 * 3) + 11)
++
++#define GPIO_RE_0    ((32 * 4) + 0)
++#define GPIO_RE_1    ((32 * 4) + 1)
++#define GPIO_RE_2    ((32 * 4) + 2)
++#define GPIO_RE_3    ((32 * 4) + 3)
++#define GPIO_RE_4    ((32 * 4) + 4)
++#define GPIO_RE_5    ((32 * 4) + 5)
++#define GPIO_RE_6    ((32 * 4) + 6)
++#define GPIO_RE_7    ((32 * 4) + 7)
++
++#define GPIO_RF_0    ((32 * 5) + 0)
++#define GPIO_RF_1    ((32 * 5) + 1)
++#define GPIO_RF_2    ((32 * 5) + 2)
++#define GPIO_RF_3    ((32 * 5) + 3)
++#define GPIO_RF_4    ((32 * 5) + 4)
++#define GPIO_RF_5    ((32 * 5) + 5)
++#define GPIO_RF_6    ((32 * 5) + 6)
++#define GPIO_RF_7    ((32 * 5) + 7)
++#define GPIO_RF_8    ((32 * 5) + 8)
++#define GPIO_RF_9    ((32 * 5) + 9)
++#define GPIO_RF_10   ((32 * 5) + 10)
++#define GPIO_RF_11   ((32 * 5) + 11)
++#define GPIO_RF_12   ((32 * 5) + 12)
++#define GPIO_RF_13   ((32 * 5) + 13)
++#define GPIO_RF_14   ((32 * 5) + 14)
++#define GPIO_RF_15   ((32 * 5) + 15)
++
++#define GPIO_RG_0    ((32 * 6) + 0)
++#define GPIO_RG_1    ((32 * 6) + 1)
++#define GPIO_RG_2    ((32 * 6) + 2)
++#define GPIO_RG_3    ((32 * 6) + 3)
++#define GPIO_RG_4    ((32 * 6) + 4)
++#define GPIO_RG_5    ((32 * 6) + 5)
++#define GPIO_RG_6    ((32 * 6) + 6)
++#define GPIO_RG_7    ((32 * 6) + 7)
++#define GPIO_RG_8    ((32 * 6) + 8)
++#define GPIO_RG_9    ((32 * 6) + 9)
++#define GPIO_RG_10   ((32 * 6) + 10)
++#define GPIO_RG_11   ((32 * 6) + 11)
++#define GPIO_RG_12   ((32 * 6) + 12)
++#define GPIO_RG_13   ((32 * 6) + 13)
++#define GPIO_RG_14   ((32 * 6) + 14)
++#define GPIO_RG_15   ((32 * 6) + 15)
++#define GPIO_RG_16   ((32 * 6) + 16)
++#define GPIO_RG_17   ((32 * 6) + 17)
++#define GPIO_RG_18   ((32 * 6) + 18)
++#define GPIO_RG_19   ((32 * 6) + 19)
++#define GPIO_RG_20   ((32 * 6) + 20)
++#define GPIO_RG_21   ((32 * 6) + 21)
++#define GPIO_RG_22   ((32 * 6) + 22)
++#define GPIO_RG_23   ((32 * 6) + 23)
++#define GPIO_RG_24   ((32 * 6) + 24)
++#define GPIO_RG_25   ((32 * 6) + 25)
++#define GPIO_RG_26   ((32 * 6) + 26)
++#define GPIO_RG_27   ((32 * 6) + 27)
++#define GPIO_RG_28   ((32 * 6) + 28)
++#define GPIO_RG_29   ((32 * 6) + 29)
++#define GPIO_RG_30   ((32 * 6) + 30)
++#define GPIO_RG_31   ((32 * 6) + 31)
++
++#define GPIO_RH_0    ((32 * 7) + 0)
++#define GPIO_RH_1    ((32 * 7) + 1)
++#define GPIO_RH_2    ((32 * 7) + 2)
++#define GPIO_RH_3    ((32 * 7) + 3)
++#define GPIO_RH_4    ((32 * 7) + 4)
++#define GPIO_RH_5    ((32 * 7) + 5)
++#define GPIO_RH_6    ((32 * 7) + 6)
++#define GPIO_RH_7    ((32 * 7) + 7)
++#define GPIO_RH_8    ((32 * 7) + 8)
++#define GPIO_RH_9    ((32 * 7) + 9)
++
++#define GPIO_RI_0    ((32 * 8) + 0)
++#define GPIO_RI_1    ((32 * 8) + 1)
++#define GPIO_RI_2    ((32 * 8) + 2)
++#define GPIO_RI_3    ((32 * 8) + 3)
++#define GPIO_RI_4    ((32 * 8) + 4)
++#define GPIO_RI_5    ((32 * 8) + 5)
++#define GPIO_RI_6    ((32 * 8) + 6)
++#define GPIO_RI_7    ((32 * 8) + 7)
++#define GPIO_RI_8    ((32 * 8) + 8)
++#define GPIO_RI_9    ((32 * 8) + 9)
++#define GPIO_RI_10   ((32 * 8) + 10)
++#define GPIO_RI_11   ((32 * 8) + 11)
++#define GPIO_RI_12   ((32 * 8) + 12)
++#define GPIO_RI_13   ((32 * 8) + 13)
++
++/*
++ * The following section defines extra GPIO available to some boards.
++ * These GPIO are generally external to the processor (i.e. SPI/I2C
++ * expander chips).
++ *
++ * Note that these defines show all possible GPIO available, however,
++ * depending on the actual board configuration, some GPIO are not
++ * available for use.
++ */
++#ifdef CONFIG_IP7500MEDIA
++/*
++ * U15
++ */
++#define IP7500MEDIA_U15_BASE  (32 * 10)
++#define IP7500MEDIA_IO0               (IP7500MEDIA_U15_BASE + 0)
++#define IP7500MEDIA_IO1               (IP7500MEDIA_U15_BASE + 1)
++#define IP7500MEDIA_IO2               (IP7500MEDIA_U15_BASE + 2)
++#define IP7500MEDIA_IO3               (IP7500MEDIA_U15_BASE + 3)
++#define IP7500MEDIA_IO4               (IP7500MEDIA_U15_BASE + 4)
++#define IP7500MEDIA_IO5               (IP7500MEDIA_U15_BASE + 5)
++#define IP7500MEDIA_IO6               (IP7500MEDIA_U15_BASE + 6)
++#define IP7500MEDIA_IO7               (IP7500MEDIA_U15_BASE + 7)
++
++/*
++ * U16
++ */
++#define IP7500MEDIA_U16_BASE  (32 * 11)
++#define IP7500MEDIA_IO8               (IP7500MEDIA_U16_BASE + 0)
++#define IP7500MEDIA_IO9               (IP7500MEDIA_U16_BASE + 1)
++#define IP7500MEDIA_IO10      (IP7500MEDIA_U16_BASE + 2)
++#define IP7500MEDIA_IO11      (IP7500MEDIA_U16_BASE + 3)
++#define IP7500MEDIA_IO12      (IP7500MEDIA_U16_BASE + 4)
++#define IP7500MEDIA_IO13      (IP7500MEDIA_U16_BASE + 5)
++#define IP7500MEDIA_IO14      (IP7500MEDIA_U16_BASE + 6)
++#define IP7500MEDIA_IO15      (IP7500MEDIA_U16_BASE + 7)
++
++/*
++ * U17
++ */
++#define IP7500MEDIA_U17_BASE  (32 * 12)
++#define IP7500MEDIA_IO16      (IP7500MEDIA_U17_BASE + 0)
++#define IP7500MEDIA_IO17      (IP7500MEDIA_U17_BASE + 1)
++#define IP7500MEDIA_IO18      (IP7500MEDIA_U17_BASE + 2)
++#define IP7500MEDIA_IO19      (IP7500MEDIA_U17_BASE + 3)
++#define IP7500MEDIA_IO20      (IP7500MEDIA_U17_BASE + 4)
++#define IP7500MEDIA_IO21      (IP7500MEDIA_U17_BASE + 5)
++#define IP7500MEDIA_IO22      (IP7500MEDIA_U17_BASE + 6)
++#define IP7500MEDIA_IO23      (IP7500MEDIA_U17_BASE + 7)
++
++/*
++ * U18
++ */
++#define IP7500MEDIA_U18_BASE  (32 * 13)
++#define IP7500MEDIA_IO24      (IP7500MEDIA_U18_BASE + 0)
++#define IP7500MEDIA_IO25      (IP7500MEDIA_U18_BASE + 1)
++#define IP7500MEDIA_IO26      (IP7500MEDIA_U18_BASE + 2)
++#define IP7500MEDIA_IO27      (IP7500MEDIA_U18_BASE + 3)
++#define IP7500MEDIA_IO28      (IP7500MEDIA_U18_BASE + 4)
++#define IP7500MEDIA_IO29      (IP7500MEDIA_U18_BASE + 5)
++#define IP7500MEDIA_IO30      (IP7500MEDIA_U18_BASE + 6)
++#define IP7500MEDIA_IO31      (IP7500MEDIA_U18_BASE + 7)
++#endif
++
++#ifdef CONFIG_IP7145DPF
++/*
++ * U48
++ */
++#define IP7145DPF_U48_BASE    (32 * 10)
++#define IP7145DPF_IO0         (IP7145DPF_U48_BASE + 0)
++#define IP7145DPF_IO1         (IP7145DPF_U48_BASE + 1)
++#define IP7145DPF_IO2         (IP7145DPF_U48_BASE + 2)
++#define IP7145DPF_IO3         (IP7145DPF_U48_BASE + 3)
++#define IP7145DPF_IO4         (IP7145DPF_U48_BASE + 4)
++#define IP7145DPF_IO5         (IP7145DPF_U48_BASE + 5)
++#define IP7145DPF_IO6         (IP7145DPF_U48_BASE + 6)
++#define IP7145DPF_IO7         (IP7145DPF_U48_BASE + 7)
++
++/*
++ * U72
++ */
++#define IP7145DPF_U72_BASE    (32 * 11)
++#define IP7145DPF_IOB0                (IP7145DPF_U72_BASE + 0)
++#define IP7145DPF_IOB1                (IP7145DPF_U72_BASE + 1)
++#define IP7145DPF_IOB2                (IP7145DPF_U72_BASE + 2)
++#define IP7145DPF_IOB3                (IP7145DPF_U72_BASE + 3)
++#define IP7145DPF_IOB4                (IP7145DPF_U72_BASE + 4)
++#define IP7145DPF_IOB5                (IP7145DPF_U72_BASE + 5)
++#define IP7145DPF_IOB6                (IP7145DPF_U72_BASE + 6)
++#define IP7145DPF_IOB7                (IP7145DPF_U72_BASE + 7)
++#endif
++
++#include <asm-generic/gpio.h>
++
++/*
++ * The following macros bypass gpiolib to generate direct references
++ * to the port registers.  These assume, minimally, that either
++ * gpio_direction_input() or gpio_direction_output() have already been
++ * called to setup the pin direction and to enable the pin function to
++ * be gpio.  These macros generate the hardware port address based on
++ * the assumption that all ports are 32 bits wide (even though we know
++ * they are not).  This is so we can efficiently turn pin numbers into
++ * port addresses without a lookup.
++ *
++ * These operations must be done in one instruction to prevent clobbering
++ * other thread's accesses to the same port.
++ */
++#define UBICOM32_GPIO_ENABLE(pin)                             \
++      do {                                                    \
++              asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask),  \
++                                [mask] "d" (gpio_bit(pin))                                                    \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_DISABLE(pin)                            \
++      do {                                                    \
++              asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_mask),  \
++                                [mask] "d" (~gpio_bit(pin))                                                   \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_SET_PIN_INPUT(pin)                      \
++      do {                                                    \
++              asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl),   \
++                                [mask] "d" (~gpio_bit(pin))                                                   \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_SET_PIN_OUTPUT(pin)                     \
++      do {                                                    \
++              asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_ctl),   \
++                                [mask] "d" (gpio_bit(pin))                                                    \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_SET_PIN_TOGGLE(pin)                     \
++      do {                                                    \
++              asm volatile ("xor.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
++                                [mask] "d" (gpio_bit(pin))                                                    \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_SET_PIN_HIGH(pin)                               \
++      do {                                                    \
++              asm volatile ("or.4 (%[port]), (%[port]), %[mask]\n\t"                                          \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
++                                [mask] "d" (gpio_bit(pin))                                                    \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_SET_PIN_LOW(pin)                                \
++      do {                                                    \
++              asm volatile ("and.4 (%[port]), (%[port]), %[mask]\n\t"                                         \
++                              :                                                                               \
++                              : [port] "a" (&UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_out),   \
++                                [mask] "d" (~gpio_bit(pin))                                                   \
++                              : "cc", "memory"                                                                \
++              );                                                                                              \
++      } while (0);
++
++#define UBICOM32_GPIO_SET_PIN(pin, val) \
++  if ( val ) {                          \
++    UBICOM32_GPIO_SET_PIN_HIGH(pin);    \
++  } else {                              \
++    UBICOM32_GPIO_SET_PIN_LOW(pin);   \
++  }
++
++#define UBICOM32_GPIO_GET_PIN(pin)                                    \
++  (0 != (UBICOM32_IO_PORT(IO_BASE + (gpio_bank(pin) << 12))->gpio_in  \
++       & gpio_bit(pin)))
++
++
++static inline int gpio_get_value(unsigned gpio) 
++{
++  if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
++    return UBICOM32_GPIO_GET_PIN(gpio);
++  else
++    return __gpio_get_value(gpio);
++}
++
++static inline void gpio_set_value(unsigned gpio, int value)
++{
++  if (gpio <= MAX_UBICOM_ONCHIP_GPIO)
++    {
++      UBICOM32_GPIO_SET_PIN(gpio, value);
++    }
++  else
++    {
++      __gpio_set_value(gpio, value);
++    }
++}
++
++static inline int gpio_cansleep(unsigned gpio)
++{
++  return __gpio_cansleep(gpio);
++}
++
++static inline int gpio_to_irq(unsigned gpio)
++{
++#if defined(IP5000) || defined(IP5000_REV2)
++  if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
++    return 25;
++  else
++    return -ENXIO;
++
++#elif defined(IP7000) || defined(IP7000_REV2)
++  if ((gpio >= GPIO_RA_4) && (gpio <= GPIO_RA_6))
++    return 44 + (gpio - GPIO_RA_4);
++  else
++    return -ENXIO;
++
++#else
++    return -ENXIO;
++
++#endif
++}
++
++static inline int irq_to_gpio(unsigned gpio)
++{
++      return -ENXIO;
++}
++
++extern struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio);
++
++extern int __init ubi_gpio_init(void);
++
++#endif /* _ASM_UBICOM32_GPIO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/hardirq.h
+@@ -0,0 +1,55 @@
++/*
++ * arch/ubicom32/include/asm/hardirq.h
++ *   Definition of ack_bad_irq() for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
++ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
++ * Copyright (C) 2001 MIPS Technologies, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_HARDIRQ_H
++#define _ASM_UBICOM32_HARDIRQ_H
++
++#include <linux/threads.h>
++#include <linux/irq.h>
++
++/*
++ * The hardirq mask has to be large enough to have space
++ * for potentially all IRQ sources in the system nesting
++ * on a single CPU.  For Ubicom32, we have 64 IRQ sources.
++ */
++#define HARDIRQ_BITS  6
++#if (1 << HARDIRQ_BITS) < NR_IRQS
++# error HARDIRQ_BITS is too low!
++#endif
++
++typedef struct {
++      unsigned int __softirq_pending;
++} ____cacheline_aligned irq_cpustat_t;
++
++#include <linux/irq_cpustat.h>        /* Standard mappings for irq_cpustat_t above */
++
++extern void ack_bad_irq(unsigned int irq);
++
++#endif /* _ASM_UBICOM32_HARDIRQ_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/hw_irq.h
+@@ -0,0 +1,31 @@
++/*
++ * arch/ubicom32/include/asm/hw_irq.h
++ *   Ubicom32 architecture APIC support.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_HW_IRQ_H
++#define _ASM_UBICOM32_HW_IRQ_H
++
++#endif /* _ASM_UBICOM32_HW_IRQ_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ioctl.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/ioctl.h
++ *   Generic ioctl.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IOCTL_H
++#define _ASM_UBICOM32_IOCTL_H
++
++#include <asm-generic/ioctl.h>
++
++#endif /* _ASM_UBICOM32_IOCTL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ioctls.h
+@@ -0,0 +1,111 @@
++/*
++ * arch/ubicom32/include/asm/ioctls.h
++ *   Definitions of ioctls for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IOCTLS_H
++#define _ASM_UBICOM32_IOCTLS_H
++
++#include <asm/ioctl.h>
++
++/* 0x54 is just a magic number to make these relatively unique ('T') */
++
++#define TCGETS                0x5401
++#define TCSETS                0x5402
++#define TCSETSW               0x5403
++#define TCSETSF               0x5404
++#define TCGETA                0x5405
++#define TCSETA                0x5406
++#define TCSETAW               0x5407
++#define TCSETAF               0x5408
++#define TCSBRK                0x5409
++#define TCXONC                0x540A
++#define TCFLSH                0x540B
++#define TIOCEXCL      0x540C
++#define TIOCNXCL      0x540D
++#define TIOCSCTTY     0x540E
++#define TIOCGPGRP     0x540F
++#define TIOCSPGRP     0x5410
++#define TIOCOUTQ      0x5411
++#define TIOCSTI               0x5412
++#define TIOCGWINSZ    0x5413
++#define TIOCSWINSZ    0x5414
++#define TIOCMGET      0x5415
++#define TIOCMBIS      0x5416
++#define TIOCMBIC      0x5417
++#define TIOCMSET      0x5418
++#define TIOCGSOFTCAR  0x5419
++#define TIOCSSOFTCAR  0x541A
++#define FIONREAD      0x541B
++#define TIOCINQ               FIONREAD
++#define TIOCLINUX     0x541C
++#define TIOCCONS      0x541D
++#define TIOCGSERIAL   0x541E
++#define TIOCSSERIAL   0x541F
++#define TIOCPKT               0x5420
++#define FIONBIO               0x5421
++#define TIOCNOTTY     0x5422
++#define TIOCSETD      0x5423
++#define TIOCGETD      0x5424
++#define TCSBRKP               0x5425  /* Needed for POSIX tcsendbreak() */
++#define TIOCSBRK      0x5427  /* BSD compatibility */
++#define TIOCCBRK      0x5428  /* BSD compatibility */
++#define TIOCGSID      0x5429  /* Return the session ID of FD */
++#define TCGETS2               _IOR('T',0x2A, struct termios2)
++#define TCSETS2               _IOW('T',0x2B, struct termios2)
++#define TCSETSW2      _IOW('T',0x2C, struct termios2)
++#define TCSETSF2      _IOW('T',0x2D, struct termios2)
++#define TIOCGPTN      _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
++#define TIOCSPTLCK    _IOW('T',0x31, int)  /* Lock/unlock Pty */
++
++#define FIONCLEX      0x5450  /* these numbers need to be adjusted. */
++#define FIOCLEX               0x5451
++#define FIOASYNC      0x5452
++#define TIOCSERCONFIG 0x5453
++#define TIOCSERGWILD  0x5454
++#define TIOCSERSWILD  0x5455
++#define TIOCGLCKTRMIOS        0x5456
++#define TIOCSLCKTRMIOS        0x5457
++#define TIOCSERGSTRUCT        0x5458 /* For debugging only */
++#define TIOCSERGETLSR   0x5459 /* Get line status register */
++#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
++#define TIOCSERSETMULTI 0x545B /* Set multiport config */
++
++#define TIOCMIWAIT    0x545C  /* wait for a change on serial input line(s) */
++#define TIOCGICOUNT   0x545D  /* read serial port inline interrupt counts */
++#define FIOQSIZE      0x545E
++
++/* Used for packet mode */
++#define TIOCPKT_DATA           0
++#define TIOCPKT_FLUSHREAD      1
++#define TIOCPKT_FLUSHWRITE     2
++#define TIOCPKT_STOP           4
++#define TIOCPKT_START          8
++#define TIOCPKT_NOSTOP                16
++#define TIOCPKT_DOSTOP                32
++
++#define TIOCSER_TEMT    0x01  /* Transmitter physically empty */
++
++#endif /* _ASM_UBICOM32_IOCTLS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/io.h
+@@ -0,0 +1,313 @@
++/*
++ * arch/ubicom32/include/asm/io.h
++ *   I/O memory accessor functions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IO_H
++#define _ASM_UBICOM32_IO_H
++
++#ifdef __KERNEL__
++#include <linux/string.h>
++#include <linux/compiler.h>
++
++static inline unsigned short _swapw(volatile unsigned short v)
++{
++    return ((v << 8) | (v >> 8));
++}
++
++static inline unsigned int _swapl(volatile unsigned long v)
++{
++    return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
++}
++
++#ifndef CONFIG_PCI
++#define readb(addr) \
++    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
++#define readw(addr) \
++    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
++#define readl(addr) \
++    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
++
++#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
++#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
++#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
++#else /*CONFIG_PCI */
++
++#define PCI_CPU_REG_BASE (0x00000000UL)   /* taking lower 2GB space */
++#define PCI_DEV_REG_BASE (0x80000000UL)
++
++#if PCI_CPU_REG_BASE > PCI_DEV_REG_BASE
++#define IS_PCI_ADDRESS(x) (((unsigned int)(x)&(PCI_CPU_REG_BASE)) == 0)
++#else
++#define IS_PCI_ADDRESS(x) ((unsigned int)(x)&(PCI_DEV_REG_BASE))
++#endif 
++
++extern unsigned int ubi32_pci_read_u32(const volatile void __iomem *addr);
++extern unsigned short ubi32_pci_read_u16(const volatile void __iomem *addr);
++extern unsigned char ubi32_pci_read_u8(const volatile void __iomem *addr);
++extern  void ubi32_pci_write_u32(unsigned int val, const volatile void __iomem *addr);
++extern  void ubi32_pci_write_u16(unsigned short val, const volatile void __iomem *addr);
++extern  void ubi32_pci_write_u8(unsigned char val, const volatile void __iomem *addr);
++
++static  inline unsigned char readb(const volatile void __iomem *addr)
++{
++      if (IS_PCI_ADDRESS(addr))
++              return ubi32_pci_read_u8(addr);
++      else 
++              return (unsigned char)(*(volatile unsigned char *)addr); 
++}
++static inline unsigned short readw(const volatile void __iomem *addr)
++{
++      if (IS_PCI_ADDRESS(addr))
++              return ubi32_pci_read_u16(addr);
++      else 
++              return (unsigned short)(*(volatile unsigned short *)addr);      
++}
++
++static  inline unsigned int  readl(const volatile void __iomem *addr)
++{
++      if (IS_PCI_ADDRESS(addr))
++              return ubi32_pci_read_u32(addr);
++      else 
++              return (unsigned int)(*(volatile unsigned int *)addr);
++}
++
++static inline void writel(unsigned int val, volatile void __iomem *addr)
++{
++      if (IS_PCI_ADDRESS(addr))
++                ubi32_pci_write_u32(val, addr);
++        else
++                      *(volatile unsigned int *)addr = val; 
++}
++
++static inline void writew(unsigned short val, volatile void __iomem *addr)
++{
++      if (IS_PCI_ADDRESS(addr))
++                ubi32_pci_write_u16(val, addr);
++        else
++                      *(volatile unsigned short *)addr = val; 
++}
++
++static inline void writeb(unsigned char val, volatile void __iomem *addr)
++{
++      if (IS_PCI_ADDRESS(addr))
++                ubi32_pci_write_u8(val, addr);
++        else
++                      *(volatile unsigned char *)addr = val; 
++}
++#endif
++
++#define readb_relaxed(addr) readb(addr)
++#define readw_relaxed(addr) readw(addr)
++#define readl_relaxed(addr) readl(addr)
++
++
++#define __raw_readb readb
++#define __raw_readw readw
++#define __raw_readl readl
++#define __raw_writeb writeb
++#define __raw_writew writew
++#define __raw_writel writel
++
++static inline void io_outsb(unsigned int addr, const void *buf, int len)
++{
++      volatile unsigned char *ap = (volatile unsigned char *) addr;
++      unsigned char *bp = (unsigned char *) buf;
++      while (len--)
++              *ap = *bp++;
++}
++
++static inline void io_outsw(unsigned int addr, const void *buf, int len)
++{
++      volatile unsigned short *ap = (volatile unsigned short *) addr;
++      unsigned short *bp = (unsigned short *) buf;
++      while (len--)
++              *ap = _swapw(*bp++);
++}
++
++static inline void io_outsl(unsigned int addr, const void *buf, int len)
++{
++      volatile unsigned int *ap = (volatile unsigned int *) addr;
++      unsigned int *bp = (unsigned int *) buf;
++      while (len--)
++              *ap = _swapl(*bp++);
++}
++
++static inline void io_insb(unsigned int addr, void *buf, int len)
++{
++      volatile unsigned char *ap = (volatile unsigned char *) addr;
++      unsigned char *bp = (unsigned char *) buf;
++      while (len--)
++              *bp++ = *ap;
++}
++
++static inline void io_insw(unsigned int addr, void *buf, int len)
++{
++      volatile unsigned short *ap = (volatile unsigned short *) addr;
++      unsigned short *bp = (unsigned short *) buf;
++      while (len--)
++              *bp++ = _swapw(*ap);
++}
++
++static inline void io_insl(unsigned int addr, void *buf, int len)
++{
++      volatile unsigned int *ap = (volatile unsigned int *) addr;
++      unsigned int *bp = (unsigned int *) buf;
++      while (len--)
++              *bp++ = _swapl(*ap);
++}
++
++#define mmiowb()
++
++/*
++ *    make the short names macros so specific devices
++ *    can override them as required
++ */
++#ifndef CONFIG_PCI
++#define memset_io(a,b,c)      memset((void *)(a),(b),(c))
++#define memcpy_fromio(a,b,c)  memcpy((a),(void *)(b),(c))
++#define memcpy_toio(a,b,c)    memcpy((void *)(a),(b),(c))
++#else 
++extern void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned len);
++extern void memcpy_toio(volatile void __iomem *to, const void *from, unsigned len);
++extern void memset_io(volatile void __iomem *addr, int val, size_t count);
++#endif
++
++#define inb(addr)    readb(addr)
++#define inw(addr)    readw(addr)
++#define inl(addr)    readl(addr)
++#define outb(x,addr) ((void) writeb(x,addr))
++#define outw(x,addr) ((void) writew(x,addr))
++#define outl(x,addr) ((void) writel(x,addr))
++
++#define inb_p(addr)    inb(addr)
++#define inw_p(addr)    inw(addr)
++#define inl_p(addr)    inl(addr)
++#define outb_p(x,addr) outb(x,addr)
++#define outw_p(x,addr) outw(x,addr)
++#define outl_p(x,addr) outl(x,addr)
++
++#define outsb(a,b,l) io_outsb(a,b,l)
++#define outsw(a,b,l) io_outsw(a,b,l)
++#define outsl(a,b,l) io_outsl(a,b,l)
++
++#define insb(a,b,l) io_insb(a,b,l)
++#define insw(a,b,l) io_insw(a,b,l)
++#define insl(a,b,l) io_insl(a,b,l)
++
++#ifndef CONFIG_PCI
++#define ioread8_rep(a,d,c)    insb(a,d,c)
++#define ioread16_rep(a,d,c)   insw(a,d,c)
++#define ioread32_rep(a,d,c)   insl(a,d,c)
++#define iowrite8_rep(a,s,c)   outsb(a,s,c)
++#define iowrite16_rep(a,s,c)  outsw(a,s,c)
++#define iowrite32_rep(a,s,c)  outsl(a,s,c)
++#else
++extern void  ioread8_rep(void __iomem *port, void *buf, unsigned long count);
++extern void  ioread16_rep(void __iomem *port, void *buf, unsigned long count);
++extern void  ioread32_rep(void __iomem *port, void *buf, unsigned long count);
++extern void  iowrite8_rep(void __iomem *port, const void *buf, unsigned long count);
++extern void  iowrite16_rep(void __iomem *port, const void *buf, unsigned long count);
++extern void  iowrite32_rep(void __iomem *port, const void *buf, unsigned long count);
++#endif
++
++
++#ifndef CONFIG_PCI
++#define ioread8(X)                    readb(X)
++#define ioread16(X)                   readw(X)
++#define ioread32(X)                   readl(X)
++#define iowrite8(val,X)                       writeb(val,X)
++#define iowrite16(val,X)              writew(val,X)
++#define iowrite32(val,X)              writel(val,X)
++#else /*CONFIG_PCI */
++extern  unsigned char  ioread8(void __iomem *addr);
++extern  unsigned short ioread16(void __iomem *addr);
++extern  unsigned int  ioread32(void __iomem *addr);
++extern  void iowrite8(unsigned char val, void __iomem *addr);
++extern  void iowrite16(unsigned short val, void __iomem *addr);
++extern  void iowrite32(unsigned int val, void __iomem *addr);
++#endif /* CONFIG_PCI */
++
++#define IO_SPACE_LIMIT 0xffff
++
++/* Values for nocacheflag and cmode */
++#define IOMAP_FULL_CACHING            0
++#define IOMAP_NOCACHE_SER             1
++#define IOMAP_NOCACHE_NONSER          2
++#define IOMAP_WRITETHROUGH            3
++
++extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
++extern void __iounmap(void *addr, unsigned long size);
++
++static inline void *ioremap(unsigned long physaddr, unsigned long size)
++{
++      return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
++}
++static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
++{
++      return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
++}
++static inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
++{
++      return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
++}
++static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
++{
++      return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
++}
++
++extern void iounmap(void *addr);
++
++#define ioport_map(port, nr)            ((void __iomem*)(port))
++#define ioport_unmap(addr)
++
++
++/* Pages to physical address... */
++#define page_to_phys(page)      ((page - mem_map) << PAGE_SHIFT)
++#define page_to_bus(page)       ((page - mem_map) << PAGE_SHIFT)
++
++/*
++ * Macros used for converting between virtual and physical mappings.
++ */
++#define phys_to_virt(vaddr)   ((void *) (vaddr))
++#define virt_to_phys(vaddr)   ((unsigned long) (vaddr))
++
++#define virt_to_bus virt_to_phys
++#define bus_to_virt phys_to_virt
++
++/*
++ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
++ * access
++ */
++#define xlate_dev_mem_ptr(p)  __va(p)
++
++/*
++ * Convert a virtual cached pointer to an uncached pointer
++ */
++#define xlate_dev_kmem_ptr(p) p
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_UBICOM32_IO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ip5000-asm.h
+@@ -0,0 +1,156 @@
++/*
++ * arch/ubicom32/include/asm/ip5000-asm.h
++ *    Instruction macros for the IP5000.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_IP5000_ASM_H
++#define _ASM_UBICOM32_IP5000_ASM_H
++
++#if !defined(__LINKER__)
++
++#if defined(__ASSEMBLY__)
++.macro        cycles  quant
++.if   (\quant) == 1
++      nop
++.else
++.if   (((\quant) + 3) / 8) > 0
++.rept (((\quant) + 3) / 8)
++      jmpt.f          .+4
++.endr
++.endif
++.if   ((((\quant) + 3) % 8) / 4) > 0
++      jmpt.t          .+4
++.endif
++.endif
++.endm
++#else
++/*
++ * Same macro as above just in C inline asm
++ */
++asm ("                                        \n\
++.macro        cycles  quant                   \n\
++.if   (\\quant) == 1                  \n\
++      nop                             \n\
++.else                                 \n\
++.if   (((\\quant) + 3) / 8) > 0       \n\
++.rept (((\\quant) + 3) / 8)           \n\
++      jmpt.f          .+4             \n\
++.endr                                 \n\
++.endif                                        \n\
++.if   ((((\\quant) + 3) % 8) / 4) > 0 \n\
++      jmpt.t          .+4             \n\
++.endif                                        \n\
++.endif                                        \n\
++.endm                                 \n\
++");
++#endif
++
++
++#if defined(__ASSEMBLY__)
++.macro        pipe_flush      cyc
++      cycles          11 - (\cyc)
++.endm
++#else
++/*
++ * Same macro as above just in C inline asm
++ */
++asm ("                                        \n\
++.macro        pipe_flush      cyc             \n\
++      cycles          11 - (\\cyc)    \n\
++.endm                                 \n\
++");
++
++#endif
++
++#if defined(__ASSEMBLY__)
++.macro        setcsr_flush    cyc
++      cycles          5 - (\cyc)
++.endm
++#else
++/*
++ * Same macro as above just in C inline asm
++ */
++asm ("                                        \n\
++.macro        setcsr_flush    cyc             \n\
++      cycles          5 - (\\cyc)     \n\
++.endm                                 \n\
++");
++#endif
++
++/*
++ * Macros for prefetch (using miss-aligned memory write)
++ */
++#if defined(__ASSEMBLY__)
++
++.macro        pre_fetch_macro thread_num, Ascratch, Aaddress length
++      bclr            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
++      bset            \Ascratch, \Aaddress, #0        ; force a miss-aligned address
++      jmpt.t          .+4                             ; delay for both address setup and trap disable
++      move.4          (\Ascratch), #0
++      .if             (\length > 32)
++      move.4          32(\Ascratch), #0
++      .endif
++      .if             (\length > 64)
++      move.4          64(\Ascratch), #0
++      .endif
++      .if             (\length > 96)
++      move.4          96(\Ascratch), #0
++      .endif
++      .if             (\length > 128)
++      invalid_instruction                             ; maximum pre-fetch size is 4 cache lines
++      .endif
++      bset            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)
++.endm
++
++#else
++/*
++ * Same macro as above just in C inline asm
++ */
++asm ("                                                                \n\
++.macro        pre_fetch_macro thread_num, Ascratch, Aaddress length   \n\
++      bclr            MT_TRAP_EN, MT_TRAP_EN, #(\thread_num)  \n\
++      bset            \\Ascratch, \\Aaddress, #0      ; force a miss-aligned address \n\
++      jmpt.t          .+4                             ; delay for both address setup and trap disable \n\
++      move.4          (\\Ascratch), #0                        \n\
++      .if             (\\length > 32)                         \n\
++      move.4          32(\\Ascratch), #0                      \n\
++      .endif                                                  \n\
++      .if             (\\length > 64)                         \n\
++      move.4          64(\\Ascratch), #0                      \n\
++      .endif                                                  \n\
++      .if             (\\length > 96)                         \n\
++      move.4          96(\\Ascratch), #0                      \n\
++      .endif                                                  \n\
++      .if             (\\length > 128)                        \n\
++      invalid_instruction                             ; maximum pre-fetch size is 4 cache lines \n\
++      .endif                                                  \n\
++      bset            MT_TRAP_EN, MT_TRAP_EN, #(\\thread_num) \n\
++.endm                                                         \n\
++");
++#endif
++
++#endif /* !defined(__LINKER__) */
++#endif /* defined _ASM_UBICOM32_IP5000_ASM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ip5000.h
+@@ -0,0 +1,860 @@
++/*
++ * arch/ubicom32/include/asm/ip5000.h
++ *   Specific details for the Ubicom IP5000 processor.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_IP5000_H
++#define _ASM_UBICOM32_IP5000_H
++
++/*
++ * Inline assembly define
++ */
++#define S(arg) #arg
++#define D(arg) S(arg)
++
++/*
++ * Assembler include file
++ */
++#include <asm/ip5000-asm.h>
++
++/*
++ * Timing
++ */
++#define JMPT_PENALTY 3
++#define JMPF_PENALTY 7
++#define RET_PENALTY 7
++
++/*
++ * Threads
++ */
++#if defined(IP5000) || defined(IP5000_REV2)
++#define THREAD_COUNT 10
++#elif defined(IP7000) || defined(IP7000_REV2)
++#define THREAD_COUNT 12
++#else
++#error "Unknown IP5K silicon"
++#endif
++
++/*
++ * Arch
++ */
++#if defined(IP5000) || defined(IP5000_REV2)
++#define UBICOM32_ARCH_VERSION 3
++#elif defined(IP7000) || defined(IP7000_REV2)
++#define UBICOM32_ARCH_VERSION 4
++#else
++#error "Unknown IP5K silicon"
++#endif
++
++/*
++ * Memory Size
++ */
++#define OCM_SECTOR_SIZE       0x00008000              /* 32K */
++
++#if defined(IP5000) || defined(IP5000_REV2)
++#define OCMSIZE       0x00030000              /* 192K on-chip RAM for both program and data */
++#elif defined(IP7000) || defined(IP7000_REV2)
++#define OCMSIZE       0x0003C000              /* 240K on-chip RAM for both program and data */
++#else
++#error "Unknown IP5K silicon"
++#endif
++
++#define OCMSTART      0x3ffc0000              /* alias from 0x03000000 for easy jump to/from SDRAM */
++#define OCMEND                (OCMSTART + OCMSIZE)
++#define SDRAMSTART    0x40000000
++#define FLASHSTART    0x60000000
++
++/*
++ * Registers
++ */
++#define ROSR_INT (1 << 0)
++
++/* Interrupts */
++#define INT_CHIP(reg, bit) (((reg) << 5) | (bit))
++#define INT_REG(interrupt) (((interrupt) >> 5) * 4)
++#define INT_SET(interrupt) 0x0114 + INT_REG(interrupt)
++#define INT_CLR(interrupt) 0x0124 + INT_REG(interrupt)
++#define INT_STAT(interrupt) 0x0104 + INT_REG(interrupt)
++#define INT_MASK(interrupt) 0x00C0 + INT_REG(interrupt)
++#define INT_BIT(interrupt) ((interrupt) & 0x1F)
++#define INT_BIT_MASK(interrupt) (1 << INT_BIT(interrupt))
++
++/*
++ * The LOCK_INT and THREAD_INT are used to wake up corresponding thread. They are sharing
++ * the same set of SW interrupt resource.
++ *
++ * LOCK_INT(n): One SW INT per NRT thread that can participate lock operation.
++ *    The threads that can participate lock are application threads and DSR thread.
++ *    (Lock locks - numbers are hard-coded in lock.h)
++ * THREAD_INT(n):   One SW INT per HRT thread for wake up trigger.
++ */
++#define LOCK_INT(thread)      INT_CHIP(0, (thread))
++#define THREAD_INT(thread)    INT_CHIP(0, (thread))
++
++/*
++ * The SYSTEM_INT and DSR_INT are sharing the same set of SW interrupt resource.
++ *
++ * SYSTEM_INT(n): One SW INT per NRT threads (application threads) as system queue interrupt,
++ *    and for DSR as self-trigger interrupt.
++ *    (The application threads include at least thread 0)
++ * DSR_INT(n):    One SW INT per HRT thread to request DSR service.
++ */
++#define SYSTEM_INT(thread)    INT_CHIP(0, THREAD_COUNT + (thread))
++#define DSR_INT(thread)               INT_CHIP(0, THREAD_COUNT + (thread))
++
++/* GLOBAL_CTRL */
++#define GLOBAL_CTRL_TRAP_RST_EN (1 << 9)
++#define GLOBAL_CTRL_AERROR_RST_EN (1 << 8)
++#define GLOBAL_CTRL_MT_MIN_DELAY(x) ((x) << 3)
++#define GLOBAL_CTRL_HRT_BANK_SELECT (1 << 2)
++#define GLOBAL_CTRL_INT_EN (1 << 0)
++
++/*
++ * HRT Tables
++ */
++#define HRT_TABLE0_BASE 0x0800
++#define HRT_TABLE1_BASE 0x0900
++#define HRT_TABLE_SIZE 64
++
++/*
++ * Break Point Trap Register
++ */
++#define ASYNCERROR_INT INT_CHIP(0, 31)
++#define BREAKPOINT_INT INT_CHIP(1, 31)
++
++/*
++ * Port interrupts
++ *    The non-existing FIFO INTs are mapped to INT2 for the ports.
++ */
++#define IO_PORT_PTR_TO_NUM(port) (((port) & 0x0000ffff) >> 12)
++#define RX_FIFO_INT(port) \
++      ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 25) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 26) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 24) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 27) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 16) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 21) : \
++      INT_CHIP(1, 15))))))))))
++#define TX_FIFO_INT(port) \
++      ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 24) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 27) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 25) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 28) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 17) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 22) : \
++      INT_CHIP(1, 15))))))))))
++#define PORT_OTHER_INT(port) \
++      ((IO_PORT_PTR_TO_NUM(port) == 0) ? INT_CHIP(0, 25) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 1) ? INT_CHIP(0, 28) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 2) ? INT_CHIP(0, 29) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 3) ? INT_CHIP(1, 26) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 4) ? INT_CHIP(1, 29) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 5) ? INT_CHIP(1, 18) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 6) ? INT_CHIP(1, 19) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 7) ? INT_CHIP(1, 20) : \
++      ((IO_PORT_PTR_TO_NUM(port) == 8) ? INT_CHIP(1, 23) : \
++      INT_CHIP(1, 15))))))))))
++
++/*
++ * On Chip Peripherals Base.
++ */
++#define OCP_BASE      0x01000000
++#define OCP_GENERAL   0x000
++#define OCP_TIMERS    0x100
++#define OCP_TRNG      0x200   /* True Random Number Generator Control Reigsters */
++#define OCP_DEBUG     0x300
++#define OCP_SECURITY  0x400
++#define OCP_ICCR      0x500   /* I-Cache Control Registers */
++#define OCP_DCCR      0x600   /* D-Cache Control Registers */
++#define OCP_OCMC      0x700   /* On Chip Memory Control Registers */
++#define OCP_STATISTICS        0x800   /* Statistics Counters */
++#define OCP_MTEST     0x900   /* Memory Test Registers */
++#define OCP_MCFG      0xa00   /* Memory Configuration Registers -- IP7000 only */
++#define OCP_DEBUG_INST        0x000   /* Up to 16M */
++
++/*
++ * General Configuration Registers (PLL)
++ */
++#define GENERAL_CFG_BASE (OCP_BASE + OCP_GENERAL)
++#define GEN_CLK_CORE_CFG 0x00
++#define GEN_CLK_IO_CFG 0x04
++#define GEN_CLK_DDR_CFG 0x08
++#define GEN_CLK_DDRDS_CFG 0x0c
++#define GEN_CLK_SLIP_CLR 0x10
++#define GEN_CLK_SLIP_START 0x14
++#define GEN_CLK_SERDES_SEL 0x18       /* IP7000 only */
++#define GEN_CLK_DDR_CFG2 0x1c /* IP7000 only */
++#define GEN_DDR_CAL_CTRL 0x30 /* IP5000 only */
++#define GEN_DDR_CAL_STAT 0x34 /* IP5000 only */
++#define GEN_USB_DFT_CTRL 0x38 /* IP5000 only */
++#define GEN_USB_DFT_STAT 0x3c /* IP5000 only */
++#define GEN_USB_PHY_CFG 0x40  /* IP7000 only */
++#define GEN_USB_PHY_TEST 0x44 /* IP7000 only */
++#define GEN_USB_PHY_STAT 0x48 /* IP7000 only */
++#define GEN_SW_RESET 0x80
++#define GEN_RESET_REASON 0x84
++#define GEN_BOND_CFG 0x88
++#define GEN_IO_PU_CFG 0x8c
++#define GEN_MEM_RM_CFG 0x90
++#define GEN_IO_CONFIG 0x94
++
++#define GEN_CLK_PLL_SECURITY_BIT_NO 31
++#define GEN_CLK_PLL_SECURITY (1 << GEN_CLK_PLL_SECURITY_BIT_NO)
++#define GEN_CLK_PLL_ENSAT (1 << 30)
++#define GEN_CLK_PLL_FASTEN (1 << 29)
++#define GEN_CLK_PLL_NR(v) (((v) - 1) << 23)
++#define GEN_CLK_PLL_NF(v) (((v) - 1) << 11)
++#define GEN_CLK_PLL_OD(v) (((v) - 1) << 8)
++#define GEN_CLK_PLL_RESET (1 << 7)
++#define GEN_CLK_PLL_BYPASS (1 << 6)
++#define GEN_CLK_PLL_POWERDOWN (1 << 5)
++#define GEN_CLK_PLL_SELECT (1 << 4)
++
++#define GEN_GET_CLK_PLL_NR(v) ((((v) >> 23) & 0x003f) + 1)
++#define GEN_GET_CLK_PLL_NF(v) ((((v) >> 11) & 0x0fff) + 1)
++#define GEN_GET_CLK_PLL_OD(v) ((((v) >> 8) & 0x7) + 1)
++
++
++#define RESET_FLAG_DST_MEM_ERROR (1 << 18)
++#define RESET_FLAG_SRC1_MEM_ERROR (1 << 17)
++#define RESET_FLAG_WRITE_ADDR (1 << 16)
++#define RESET_FLAG_DST_SYNC_ERROR (1 << 15)
++#define RESET_FLAG_SRC1_SYNC_ERROR (1 << 14)
++#define RESET_FLAG_DST_ALGN_ERROR (1 << 13)
++#define RESET_FLAG_SRC1_ALGN_ERROR (1 << 12)
++#define RESET_FLAG_DST_ADDR_ERROR (1 << 11)
++#define RESET_FLAG_SRC1_ADDR_ERROR (1 << 10)
++#define RESET_FLAG_ILLEGAL_INST (1 << 9)
++#define RESET_FLAG_INST_SYNC_ERROR (1 << 8)
++#define RESET_FLAG_INST_ADDR_ERROR (1 << 7)
++#define RESET_FLAG_DATA_PORT_ERROR (1 << 6)
++#define RESET_FLAG_INST_PORT_ERROR (1 << 5)
++#define RESET_FLAG_SW_RESET (1 << 4)
++#define RESET_FLAG_DEBUG (1 << 3)
++#define RESET_FLAG_WATCHDOG (1 << 2)
++#define RESET_FLAG_POWER_ON (1 << 1)
++#define RESET_FLAG_EXTERNAL (1 << 0)
++
++/*
++ * Timer block
++ */
++#define TIMER_BASE (OCP_BASE + OCP_TIMERS)
++#define TIMER_MPTVAL 0x00
++#define TIMER_RTCOM 0x04
++#define TIMER_TKEY 0x08
++#define TIMER_WDCOM 0x0c
++#define TIMER_WDCFG 0x10
++#define TIMER_SYSVAL 0x14
++#define TIMER_SYSCOM(tmr) (0x18 + (tmr) * 4)
++#define TIMER_TRN_CFG 0x100
++#define TIMER_TRN 0x104
++
++#define TIMER_COUNT 10
++#define TIMER_INT(tmr) INT_CHIP(1, (tmr))
++#define TIMER_TKEYVAL 0xa1b2c3d4
++#define TIMER_WATCHDOG_DISABLE 0x4d3c2b1a
++#define TIMER_TRN_CFG_ENABLE_OSC 0x00000007
++
++#ifndef __ASSEMBLY__
++/*
++ * ubicom32_io_timer
++ */
++struct ubicom32_io_timer {
++      volatile u32_t mptval;
++      volatile u32_t rtcom;
++      volatile u32_t tkey;
++      volatile u32_t wdcom;
++      volatile u32_t wdcfg;
++      volatile u32_t sysval;
++      volatile u32_t syscom[TIMER_COUNT];
++      volatile u32_t reserved[64 - 6 - TIMER_COUNT];  // skip all the way to OCP-TRNG section
++      volatile u32_t rsgcfg;
++      volatile u32_t trn;
++};
++
++#define UBICOM32_IO_TIMER ((struct ubicom32_io_timer *)TIMER_BASE)
++#endif
++
++#define UBICOM32_VECTOR_TO_TIMER_INDEX(vector) (vector - TIMER_INT(0))
++
++/*
++ * OCP-Debug Module (Mailbox)
++ */
++#define ISD_MAILBOX_BASE (OCP_BASE + OCP_DEBUG)
++#define ISD_MAILBOX_IN 0x00
++#define ISD_MAILBOX_OUT 0x04
++#define ISD_MAILBOX_STATUS 0x08
++
++#define ISD_MAILBOX_INT INT_CHIP(1, 30)
++
++#define ISD_MAILBOX_STATUS_IN_FULL (1 << 31)
++#define ISD_MAILBOX_STATUS_IN_EMPTY (1 << 30)
++#define ISD_MAILBOX_STATUS_OUT_FULL (1 << 29)
++#define ISD_MAILBOX_STATUS_OUT_EMPTY (1 << 28)
++
++/*
++ * OCP-Security
++ */
++#define SECURITY_BASE (OCP_BASE + OCP_SECURITY)
++#define SECURITY_BASE_EFFECTIVE_ADDRESS (SECURITY_BASE >> 7) // To load the base address in a single instruction
++#define SECURITY_CTRL 0x00
++#define SECURITY_CTRL_BYTE_OFFSET(x) ((x) << 16)
++#define SECURITY_CTRL_KEY_SIZE(x) ((x) << 8)
++#define SECURITY_CTRL_HASH_ALG_NONE (0 << 4)
++#define SECURITY_CTRL_HASH_ALG_MD5 (1 << 4)
++#define SECURITY_CTRL_HASH_ALG_SHA1 (2 << 4)
++#define SECURITY_CTRL_CBC (1 << 3)
++#define SECURITY_CTRL_CIPHER_ALG_AES (0 << 1)
++#define SECURITY_CTRL_CIPHER_ALG_NONE (1 << 1)
++#define SECURITY_CTRL_CIPHER_ALG_DES (2 << 1)
++#define SECURITY_CTRL_CIPHER_ALG_3DES (3 << 1)
++#define SECURITY_CTRL_ENCIPHER (1 << 0)
++#define SECURITY_CTRL_DECIPHER (0 << 0)
++#define SECURITY_STAT 0x04
++#define SECURITY_STAT_BUSY (1 << 0)
++#define SECURITY_KEY_VALUE(x) (0x10 + (x) * 4)
++#define SECURITY_KEY_IN(x) (0x30 + (x) * 4)
++#define SECURITY_KEY_OUT(x) (0x50 + (x) * 4)
++#define SECURITY_KEY_HASH(x) (0x70 + (x) * 4)
++
++/*
++ * OCP-ICCR
++ */
++#define ICCR_BASE (OCP_BASE + OCP_ICCR)
++#define ICACHE_TOTAL_SIZE 16384                       /* in bytes */
++
++/*
++ * OCP-DCCR
++ */
++#define DCCR_BASE (OCP_BASE + OCP_DCCR)
++#if defined(IP5000) || defined(IP5000_REV2)
++#define DCACHE_TOTAL_SIZE 8192                        /* in bytes */
++#elif defined(IP7000) || defined(IP7000_REV2)
++#define DCACHE_TOTAL_SIZE 16384                       /* in bytes */
++#endif
++
++#if defined(IP5000) || defined(IP5000_REV2) || defined(IP7000) || defined(IP7000_REV2)
++#define DCACHE_WRITE_QUEUE_LENGTH 6
++#else
++#error "Unknown IP5K silicon"
++#endif
++
++#define CACHE_LINE_SIZE 32                    /* in bytes */
++
++#define CCR_ADDR 0x00
++#define CCR_RDD 0x04
++#define CCR_WRD 0x08
++#define CCR_STAT 0x0c
++#define CCR_CTRL 0x10
++
++#define CCR_STAT_MCBE 0
++#define CCR_STAT_WIDEL 1                      /* D-cache only */
++
++#define CCR_CTRL_DONE 0
++#define CCR_CTRL_RESET 2
++#define CCR_CTRL_VALID 3
++#define CCR_CTRL_RD_DATA (1 << 4)
++#define CCR_CTRL_RD_TAG (2 << 4)
++#define CCR_CTRL_WR_DATA (3 << 4)
++#define CCR_CTRL_WR_TAG (4 << 4)
++#define CCR_CTRL_INV_INDEX (5 << 4)
++#define CCR_CTRL_INV_ADDR (6 << 4)
++#define CCR_CTRL_FLUSH_INDEX (7 << 4)         /* D-cache only */
++#define CCR_CTRL_FLUSH_INV_INDEX (8 << 4)     /* D-cache only */
++#define CCR_CTRL_FLUSH_ADDR (9 << 4)          /* D-cache only */
++#define CCR_CTRL_FLUSH_INV_ADDR (10 << 4)     /* D-cache only */
++
++/*
++ * OCP-OCMC
++ */
++#define OCMC_BASE (OCP_BASE + OCP_OCMC)
++#define OCMC_BANK_MASK 0x00
++#define OCMC_BIST_CNTL 0x04   /* IP5000 only */
++#define OCMC_BIST_STAT 0x08   /* IP5000 only */
++
++#define OCMC_BANK_PROG(n) ((1<<(n))-1)
++
++#define OCMC_BIST_WRCK (1 << 7)
++#define OCMC_BIST_RESET (1 << 5)
++#define OCMC_BIST_SMART (1 << 4)
++#define OCMC_BIST_RUN (1 << 3)
++#define OCMC_BIST_REPAIR (1 << 2)
++
++#define OCMC_BIST_READY (1 << 3)
++#define OCMC_BIST_FAIL (1 << 2)
++
++/*
++ * OCP-STATISTICS
++ */
++#define STATISTICS_BASE (OCP_BASE + OCP_STATISTICS)
++#define STAT_COUNTER_CTRL(n) ((n)*8)
++#define STAT_COUNTER(n) ((n)*8 + 4)
++
++#define STAT_EVENT_MP_INST 0
++#define STAT_EVENT_OCM_ACCESS 4
++#define STAT_EVENT_OCM_REQ 5
++#define STAT_EVENT_IC_REQ_INVAL 13
++#define STAT_EVENT_IC_MISS_INVAL 14
++#define STAT_EVENT_IC_REQ_INVAL_NACK 15
++#define STAT_EVENT_IC_REQ_VAL 16
++#define STAT_EVENT_IC_MISS_VAL 17
++#define STAT_EVENT_IC_REQ_VAL_NACK 18
++#define STAT_EVENT_IC_MISS_Q 19
++#define STAT_EVENT_DC_RD_REQ 20
++#define STAT_EVENT_DC_RD_MISS 21
++#define STAT_EVENT_DC_WR_REQ 22
++#define STAT_EVENT_DC_WR_MISS 23
++#define STAT_EVENT_DC_MISS_Q 24
++#define STAT_EVENT_DC_WB_FULL 25
++#define STAT_EVENT_DC_REQ_NACK 26
++#define STAT_EVENT_DC_CORE_REQ 27
++#define STAT_EVENT_DC_MISS 28
++#define STAT_EVENT_DC_EVICT 29
++#define STAT_EVENT_TRUE 30
++#define STAT_EVENT_FALSE 31
++
++/*
++ * OCP_MTEST
++ */
++#define MTEST_BASE (OCP_BASE + OCP_MTEST)
++#define MTEST_ADDR 0x00
++#define MTEST_WR 0x04
++#define MTEST_RD 0x08
++#define MTEST_CTRL 0x0c
++
++/*
++ * OCP_MCFG (IP7000 only)
++ */
++#define MCFG_BASE (OCP_BASE + OCP_MCFG)
++#define MCFG_CTRL 0x00
++#define MCFG_WCFG 0x04
++#define MCFG_RCFG 0x08
++
++/*
++ * Port registers
++ */
++#define IO_BASE 0x02000000
++#define RA (IO_BASE + 0x00000000)
++#define RB (IO_BASE + 0x00001000)
++#define RC (IO_BASE + 0x00002000)
++#define RD (IO_BASE + 0x00003000)
++#define RE (IO_BASE + 0x00004000)
++#define RF (IO_BASE + 0x00005000)
++#define RG (IO_BASE + 0x00006000)
++#define RH (IO_BASE + 0x00007000)
++#define RI (IO_BASE + 0x00008000)
++#define RJ (IO_BASE + 0x00009000)
++#define RLATCH (IO_BASE + 0x00ff0000) // For latched output only
++#define IO_PORT_BR_OFFSET 0x00000800
++
++/*
++ * General I/O Register Map (per port)
++ */
++#define IO_FUNC 0x00
++#define IO_GPIO_CTL 0x04
++#define IO_GPIO_OUT 0x08
++#define IO_GPIO_IN 0x0C
++#define IO_INT_STATUS 0x10
++#define IO_INT_MASK 0x14
++#define IO_INT_SET 0x18
++#define IO_INT_CLR 0x1C
++#define IO_TX_FIFO 0x20
++#define IO_TX_FIFO_HI 0x24
++#define IO_RX_FIFO 0x28
++#define IO_RX_FIFO_HI 0x2c
++#define IO_CTL0 0x30
++#define IO_CTL1 0x34
++#define IO_CTL2 0x38
++#define IO_STATUS0 0x3c
++#define IO_STATUS1 0x40
++#define IO_STATUS2 0x44
++#define IO_FIFO_WATER 0x48
++#define IO_FIFO_LEVEL 0x4c
++#define IO_GPIO_MASK 0x50
++
++#define IO_FUNC_FUNCTION_RESET(func) ((1 << ((func) - 1)) << 4)       /* Function 0 doesn't need reset */
++#define IO_FUNC_RX_FIFO (1 << 3)
++#define IO_FUNC_SELECT(func) ((func) << 0)
++
++/*
++ * External interrupt pins.
++ */
++#define EXT_INT_IO_BIT(pin) ((pin) + 5)       // Interrupt pin number -> I/O INT bit
++#define EXT_INT_RISING_EDGE(pin) (0x2 << (2*(pin) + 7))
++#define EXT_INT_FALLING_EDGE(pin) (0x1 << (2*(pin) + 7))
++
++/*
++ * Flash
++ */
++#define IO_XFL_BASE RA
++
++#define IO_XFL_INT_START (1 << 16)
++#define IO_XFL_INT_ERR (1 << 8)
++#define IO_XFL_INT_DONE (1 << 0)
++
++#define IO_XFL_CTL0_MASK (0xffe07fff)
++#define IO_XFL_CTL0_RD_CMD(cmd) (((cmd) & 0xff) << 24)
++#define IO_XFL_CTL0_RD_DUMMY(n) (((n) & 0x7) << 21)
++#define IO_XFL_CTL0_CLK_WIDTH(core_cycles) ((((core_cycles) + 1) & 0x7e) << 8)        /* must be even number */
++#define IO_XFL_CTL0_CE_WAIT(spi_cycles) (((spi_cycles) & 0x3f) << 2)
++#define IO_XFL_CTL0_MCB_LOCK (1 << 1)
++#define IO_XFL_CTL0_ENABLE (1 << 0)
++#define IO_XFL_CTL0_FAST_VALUE(div, wait) (IO_XFL_CTL0_RD_CMD(0xb) | IO_XFL_CTL0_RD_DUMMY(1) | IO_XFL_CTL0_CLK_WIDTH(div) | IO_XFL_CTL0_CE_WAIT(wait) | IO_XFL_CTL0_ENABLE)
++#define IO_XFL_CTL0_VALUE(div, wait) (IO_XFL_CTL0_RD_CMD(3) | IO_XFL_CTL0_CLK_WIDTH(div) | IO_XFL_CTL0_CE_WAIT(wait) | IO_XFL_CTL0_ENABLE)
++
++#define IO_XFL_CTL1_MASK (0xc0003fff)
++#define IO_XFL_CTL1_FC_INST(inst) (((inst) & 0x3) << 30)
++#define IO_XFL_CTL1_FC_DATA(n) (((n) & 0x3ff) << 4)
++#define IO_XFL_CTL1_FC_DUMMY(n) (((n) & 0x7) << 1)
++#define IO_XFL_CTL1_FC_ADDR (1 << 0)
++
++#define IO_XFL_CTL2_FC_CMD(cmd) (((cmd) & 0xff) << 24)
++#define IO_XFL_CTL2_FC_ADDR(addr) ((addr) & 0x00ffffff)       /* Only up to 24 bits */
++
++#define IO_XFL_STATUS0_MCB_ACTIVE (1 << 0)
++#define IO_XFL_STATUS0_IOPCS_ACTIVE (1 << 1)
++
++/*
++ * SDRAM
++ */
++#define IO_SDRAM_DATA_BASE RG
++#define IO_SDRAM_CNTL_BASE RH
++
++#define IO_SDRAM_CTRL0_EN_REF (1 << 0)
++
++/*
++ * Port function code (common fucntion codes for all I/O ports)
++ */
++#define IO_PORTX_FUNC_GPIO 0x00
++#define IO_PORTX_FUNC_XFL 0x01
++#define IO_PORTX_FUNC_PCI 0x01
++#define IO_PORTX_FUNC_SERDES 0x01
++#define IO_PORTX_FUNC_GMII 0x01
++#define IO_PORTX_FUNC_DDR 0x01
++#define IO_PORTX_FUNC_PCIX 0x01
++#define IO_PORTX_FUNC_USB2_0 0x01
++#define IO_PORTX_FUNC_GPIO_INT_CLK 0x02
++#define IO_PORTX_FUNC_PLIO 0x02
++#define IO_PORTX_FUNC_GPIO_INT 0x03
++#define IO_PORTX_FUNC_MII 0x03
++
++/*
++ * Port 0
++ */
++#define IO_PORT0_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT0_FUNC_XFL_INT_CLK IO_PORTX_FUNC_XFL   // Default mode after reset
++#define IO_PORT0_FUNC_GPIO_INT_CLK IO_PORTX_FUNC_GPIO_INT_CLK
++#define IO_PORT0_FUNC_GPIO_INT IO_PORTX_FUNC_GPIO_INT
++
++/*
++ * Port 1
++ */
++#define IO_PORT1_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT1_FUNC_PCI IO_PORTX_FUNC_PCI           // PCI control
++#define IO_PORT1_FUNC_MII IO_PORTX_FUNC_MII           // port 4 MII extension
++
++/*
++ * Port 2
++ */
++#define IO_PORT2_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT2_FUNC_PCI IO_PORTX_FUNC_PCI           // PCI data I/O
++#define IO_PORT2_FUNC_PLIO IO_PORTX_FUNC_PLIO         // Extended LM
++
++/*
++ * Port 3
++ */
++#define IO_PORT3_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT3_FUNC_SERDES IO_PORTX_FUNC_SERDES
++#define IO_PORT3_FUNC_PLIO IO_PORTX_FUNC_PLIO
++
++/*
++ * Port 4
++ */
++#define IO_PORT4_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT4_FUNC_SERDES IO_PORTX_FUNC_SERDES
++#define IO_PORT4_FUNC_PLIO IO_PORTX_FUNC_PLIO         // Extended LM
++#define IO_PORT4_FUNC_MII IO_PORTX_FUNC_MII
++
++/*
++ * Port 5
++ */
++#define IO_PORT5_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT5_FUNC_GMII IO_PORTX_FUNC_GMII
++
++/*
++ * Port 6
++ */
++#define IO_PORT6_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT6_FUNC_DDR IO_PORTX_FUNC_DDR
++
++/*
++ * Port 7
++ */
++#define IO_PORT7_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT7_FUNC_DDR IO_PORTX_FUNC_DDR
++
++/*
++ * Port 8
++ */
++#define IO_PORT8_FUNC_GPIO IO_PORTX_FUNC_GPIO
++#define IO_PORT8_FUNC_PCIX IO_PORTX_FUNC_PCIX
++#define IO_PORT8_FUNC_PLIO IO_PORTX_FUNC_PLIO         // Extended LM
++#define IO_PORT8_FUNC_MII IO_PORTX_FUNC_MII           // port 4 MII extension
++
++/*
++ * Port 9
++ */
++#define IO_PORT9_FUNC_USB2_0 IO_PORTX_FUNC_USB2_0
++
++/*
++ * FIFO
++ */
++#define IO_PORTX_INT_FIFO_TX_RESET (1 << 31)
++#define IO_PORTX_INT_FIFO_RX_RESET (1 << 30)
++#define IO_PORTX_INT_FIFO_TX_UF (1 << 15)
++#define IO_PORTX_INT_FIFO_TX_WM (1 << 14)
++#define IO_PORTX_INT_FIFO_RX_OF (1 << 13)
++#define IO_PORTX_INT_FIFO_RX_WM (1 << 12)
++
++#define IO_PORTX_FUNC_FIFO_TX_WM(n) ((n) << 16)
++#define IO_PORTX_FUNC_FIFO_RX_WM(n) ((n) << 0)
++
++/*
++ * MII
++ */
++#define IO_PORTX_INT_MII_TX_ERR_SEND (1 << 18)
++#define IO_PORTX_INT_MII_TX_HALT (1 << 17)
++#define IO_PORTX_INT_MII_TX_START (1 << 16)
++#define IO_PORTX_INT_MII_THRESHOLD (1 << 8)
++#define IO_PORTX_INT_MII_RX_EOP (1 << 7)
++#define IO_PORTX_INT_MII_RX_SFD (1 << 6)
++#define IO_PORTX_INT_MII_RX_ERR (1 << 5)
++#define IO_PORTX_INT_MII_TX_EOP (1 << 4)
++#define IO_PORTX_INT_MII_COL (1 << 3)
++#define IO_PORTX_INT_MII_CRS (1 << 2)
++#define IO_PORTX_INT_MII_ODD_NIB_ERR (1 << 1)
++#define IO_PORTX_INT_MII_FALSE_CARRIER (1 << 0)
++
++/*
++ * SerDes
++ */
++#define IO_PORTX_INT_SERDES_TXBUF_VALID (1 << 16)
++#define IO_PORTX_INT_SERDES_RXERR (1 << 7)
++#define IO_PORTX_INT_SERDES_RXEOP (1 << 6)
++#define IO_PORTX_INT_SERDES_SYND (1 << 5)
++#define IO_PORTX_INT_SERDES_TXBE (1 << 4)
++#define IO_PORTX_INT_SERDES_TXEOP (1 << 3)
++#define IO_PORTX_INT_SERDES_SXLP (1 << 2)
++#define IO_PORTX_INT_SERDES_RXBF (1 << 1)
++#define IO_PORTX_INT_SERDES_RXCRS (1 << 0)
++
++#ifndef __ASSEMBLY__
++struct ubicom32_io_port {
++      volatile u32_t function;
++      volatile u32_t gpio_ctl;
++      volatile u32_t gpio_out;
++      volatile u32_t gpio_in;
++      volatile u32_t int_status;
++      volatile u32_t int_mask;
++      volatile u32_t int_set;
++      volatile u32_t int_clr;
++      volatile u32_t tx_fifo;
++      volatile u32_t tx_fifo_hi;
++      volatile u32_t rx_fifo;
++      volatile u32_t rx_fifo_hi;
++      volatile u32_t ctl0;
++      volatile u32_t ctl1;
++      volatile u32_t ctl2;
++      volatile u32_t status0;
++      volatile u32_t status1;
++      volatile u32_t status2;
++      volatile u32_t fifo_watermark;
++      volatile u32_t fifo_level;
++      volatile u32_t gpio_mask;
++};
++
++#define UBICOM32_IO_PORT(port) ((struct ubicom32_io_port *)((port)))
++#endif
++
++#ifndef __ASSEMBLY__
++/*
++ * ubicom32_set_interrupt()
++ */
++extern inline void ubicom32_set_interrupt(u8_t interrupt)
++{
++      u32_t ibit = INT_BIT_MASK(interrupt);
++
++      if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
++              asm volatile (
++                      "move.4         "D(INT_SET(INT_CHIP(0, 0)))", %0\n\t"
++                      :
++                      : "r" (ibit)
++              );
++
++              return;
++      }
++
++      asm volatile (
++              "move.4         "D(INT_SET(INT_CHIP(1, 0)))", %0\n\t"
++              :
++              : "r" (ibit)
++      );
++}
++
++/*
++ * ubicom32_clear_interrupt()
++ */
++extern inline void ubicom32_clear_interrupt(u8_t interrupt)
++{
++      u32_t ibit = INT_BIT_MASK(interrupt);
++
++      if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
++              asm volatile (
++                      "move.4         "D(INT_CLR(INT_CHIP(0, 0)))", %0\n\t"
++                      :
++                      : "r" (ibit)
++              );
++
++              return;
++      }
++
++      asm volatile (
++              "move.4         "D(INT_CLR(INT_CHIP(1, 0)))", %0\n\t"
++              :
++              : "r" (ibit)
++      );
++}
++
++/*
++ * ubicom32_enable_interrupt()
++ */
++extern inline void ubicom32_enable_interrupt(u8_t interrupt)
++{
++      u32_t ibit = INT_BIT_MASK(interrupt);
++
++      if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
++              asm volatile (
++                      "or.4           "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
++                      :
++                      : "d" (ibit)
++              );
++
++              return;
++      }
++
++      asm volatile (
++              "or.4           "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
++              :
++              : "d" (ibit)
++      );
++}
++
++/*
++ * ubicom32_disable_interrupt()
++ */
++extern inline void ubicom32_disable_interrupt(u8_t interrupt)
++{
++      u32_t ibit = ~INT_BIT_MASK(interrupt);
++
++      if (INT_REG(interrupt) == INT_REG(INT_CHIP(0, 0))) {
++              asm volatile (
++                      "and.4          "D(INT_MASK(INT_CHIP(0, 0)))", "D(INT_MASK(INT_CHIP(0, 0)))", %0\n\t"
++                      :
++                      : "d" (ibit)
++              );
++
++              return;
++      }
++
++      asm volatile (
++              "and.4          "D(INT_MASK(INT_CHIP(1, 0)))", "D(INT_MASK(INT_CHIP(1, 0)))", %0\n\t"
++              :
++              : "d" (ibit)
++      );
++}
++
++/*
++ * ubicom32_enable_global_interrupts()
++ */
++extern inline void ubicom32_enable_global_interrupts(void)
++{
++      asm volatile(
++              "bset           GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
++      );
++}
++
++/*
++ * ubicom32_disable_global_interrupts()
++ */
++extern inline void ubicom32_disable_global_interrupts(void)
++{
++      asm volatile(
++              "bclr           GLOBAL_CTRL, GLOBAL_CTRL, #%bit("D(GLOBAL_CTRL_INT_EN)")"
++      );
++}
++
++/*
++ * ubicom32_get_reset_reason()
++ */
++extern inline u32_t ubicom32_get_reset_reason(void)
++{
++      return *(u32_t *)(GENERAL_CFG_BASE + GEN_RESET_REASON);
++}
++
++/*
++ * ubicom32_read_reg()
++ */
++extern inline u32_t ubicom32_read_reg(volatile void *reg)
++{
++      u32_t v;
++      asm volatile (
++              "move.4         %[dest], %[src] \n\t"
++              : [dest] "=r" (v)
++              : [src] "m" (*(u32_t *)reg)
++      );
++      return v;
++}
++
++/*
++ * ubicom32_write_reg()
++ */
++extern inline void ubicom32_write_reg(volatile void *reg, u32_t v)
++{
++      asm volatile (
++              "move.4         %[dest], %[src] \n\t"
++              :
++              : [src] "r" (v), [dest] "m" (*(u32_t *)reg)
++      );
++}
++
++#endif /* __ASSEMBLY__ */
++#endif /* _ASM_UBICOM32_IP5000_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ipcbuf.h
+@@ -0,0 +1,55 @@
++/*
++ * arch/ubicom32/include/asm/ipcbuf.h
++ *   Definition of ipc64_perm struct for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IPCBUF_H
++#define _ASM_UBICOM32_IPCBUF_H
++
++/*
++ * The user_ipc_perm structure for m68k architecture.
++ * Note extra padding because this structure is passed back and forth
++ * between kernel and user space.
++ *
++ * Pad space is left for:
++ * - 32-bit mode_t and seq
++ * - 2 miscellaneous 32-bit values
++ */
++struct ipc64_perm
++{
++      __kernel_key_t          key;
++      __kernel_uid32_t        uid;
++      __kernel_gid32_t        gid;
++      __kernel_uid32_t        cuid;
++      __kernel_gid32_t        cgid;
++      __kernel_mode_t         mode;
++      unsigned short          __pad1;
++      unsigned short          seq;
++      unsigned short          __pad2;
++      unsigned long           __unused1;
++      unsigned long           __unused2;
++};
++
++#endif /* _ASM_UBICOM32_IPCBUF_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/irqflags.h
+@@ -0,0 +1,94 @@
++/*
++ * arch/ubicom32/include/asm/irqflags.h
++ *   Raw implementation of local IRQ functions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IRQFLAGS_H
++#define _ASM_UBICOM32_IRQFLAGS_H
++
++#include <linux/thread_info.h>
++#include <asm/ubicom32-common.h>
++#include <asm/smp.h>
++#include <asm/ldsr.h>
++
++#if defined(CONFIG_PREEMPT)
++#error Not supported by Ubicom32 irq handling, yet!
++#endif
++
++/*
++ * raw_local_irq_enable()
++ *    Enable interrupts for this thread.
++ */
++static inline void raw_local_irq_enable(void)
++{
++      ldsr_local_irq_enable();
++}
++
++/*
++ * raw_local_irq_disable()
++ *    Disable interrupts for this thread.
++ */
++static inline void raw_local_irq_disable(void)
++{
++      ldsr_local_irq_disable();
++}
++
++/*
++ * raw_local_save_flags()
++ *    Get the current IRQ state.
++ */
++#define raw_local_save_flags(flags)           \
++do {                                          \
++      (flags) = ldsr_local_irq_is_disabled(); \
++} while (0)
++
++/*
++ * raw_local_irq_save()
++ *    Save the current interrupt state and disable interrupts.
++ */
++#define raw_local_irq_save(flags)             \
++do {                                          \
++      (flags) = ldsr_local_irq_save();        \
++} while (0)
++
++/*
++ * raw_local_irq_restore()
++ *    Restore the IRQ state back to flags.
++ */
++static inline void raw_local_irq_restore(unsigned long flags)
++{
++      ldsr_local_irq_restore(flags);
++}
++
++/*
++ * raw_irqs_disabled_flags()
++ *    Return true if the flags indicate that IRQ(s) are disabled.
++ */
++static inline int raw_irqs_disabled_flags(unsigned long flags)
++{
++      return (flags);
++}
++
++#endif /* _ASM_UBICOM32_IRQFLAGS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/irq.h
+@@ -0,0 +1,45 @@
++/*
++ * arch/ubicom32/include/asm/irq.h
++ *   IRQ definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IRQ_H
++#define _ASM_UBICOM32_IRQ_H
++
++#include <asm/irqflags.h>
++
++/*
++ * We setup the IRQS to cover the full range of interrupt registers in
++ * processor.
++ */
++#define NR_IRQS               64
++
++#define irq_canonicalize(irq) (irq)
++
++extern int irq_soft_alloc(unsigned int *soft);
++extern void ack_bad_irq(unsigned int irq);
++extern void do_IRQ(int irq, struct pt_regs *fp);
++
++#endif /* _ASM_UBICOM32_IRQ_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/irq_regs.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/irq_regs.h
++ *   Generic irq_regs.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IRQ_REGS_H
++#define _ASM_UBICOM32_IRQ_REGS_H
++
++#include <asm-generic/irq_regs.h>
++
++#endif /* _ASM_UBICOM32_IRQ_REGS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/Kbuild
+@@ -0,0 +1 @@
++include include/asm-generic/Kbuild.asm
+--- /dev/null
++++ b/arch/ubicom32/include/asm/kdebug.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/kdebug.h
++ *   Generic kdebug.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_KDEBUG_H
++#define _ASM_UBICOM32_KDEBUG_H
++
++#include <asm-generic/kdebug.h>
++
++#endif /* _ASM_UBICOM32_KDEBUG_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/kmap_types.h
+@@ -0,0 +1,48 @@
++/*
++ * arch/ubicom32/include/asm/kmap_types.h
++ *   Definition of km_type's for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_KMAP_TYPES_H
++#define _ASM_UBICOM32_KMAP_TYPES_H
++
++enum km_type {
++      KM_BOUNCE_READ,
++      KM_SKB_SUNRPC_DATA,
++      KM_SKB_DATA_SOFTIRQ,
++      KM_USER0,
++      KM_USER1,
++      KM_BIO_SRC_IRQ,
++      KM_BIO_DST_IRQ,
++      KM_PTE0,
++      KM_PTE1,
++      KM_IRQ0,
++      KM_IRQ1,
++      KM_SOFTIRQ0,
++      KM_SOFTIRQ1,
++      KM_TYPE_NR
++};
++
++#endif /* _ASM_UBICOM32_KMAP_TYPES_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ldsr.h
+@@ -0,0 +1,186 @@
++/*
++ * arch/ubicom32/include/asm/ldsr.h
++ *   Ubicom32 LDSR interface definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_LDSR_H
++#define _ASM_UBICOM32_LDSR_H
++
++#include <asm/ubicom32-common.h>
++#include <asm/types.h>
++#include <asm/thread.h>
++
++extern unsigned int ldsr_soft_irq_mask;
++
++/*
++ * ldsr_local_irq_is_disabled()
++ *    Test if interrupts are disabled for this thread?
++ */
++static inline int ldsr_local_irq_is_disabled(void)
++{
++      int ret;
++      thread_t self = thread_get_self();
++      unsigned int mask = (1 << self);
++
++      asm volatile (
++      "       and.4   %0, scratchpad1, %1     \n\t"
++              : "=r" (ret)
++              : "d" (mask)
++              : "cc"
++      );
++
++      /*
++       *  We return a simple 1 == disabled, 0 == enabled
++       *  losing which tid this is for, because Linux
++       *  can restore interrupts on a different thread.
++       */
++      return ret >> self;
++}
++
++/*
++ * ldsr_local_irq_save()
++ *    Get the current interrupt state and disable interrupts.
++ */
++static inline unsigned int ldsr_local_irq_save(void)
++{
++      int ret;
++      thread_t self = thread_get_self();
++      unsigned int mask = (1 << self);
++
++      /*
++       * Ensure the compiler can not optimize out the code
++       * (volatile) and that it does not "cache" values around
++       * the interrupt state change (memory).  This ensures
++       * that interrupt changes are treated as a critical
++       * section.
++       */
++      asm volatile (
++      "       and.4   %0, scratchpad1, %1             \n\t"
++      "       or.4    scratchpad1, scratchpad1, %1    \n\t"
++              : "=&r" (ret)
++              : "d" (mask)
++              : "cc", "memory"
++      );
++
++      /*
++       *  We return a simple 1 == disabled, 0 == enabled
++       *  losing which tid this is for, because Linux
++       *  can restore interrupts on a different thread.
++       */
++      return ret >> self;
++}
++
++/*
++ * ldsr_local_irq_restore()
++ *    Restore this cpu's interrupt enable/disable state.
++ *
++ * Note: flags is either 0 or 1.
++ */
++static inline void ldsr_local_irq_restore(unsigned int flags)
++{
++      unsigned int temp;
++      thread_t self = thread_get_self();
++      unsigned int mask = (1 << self);
++      flags = (flags << self);
++
++      /*
++       * Ensure the compiler can not optimize out the code
++       * (volatile) and that it does not "cache" values around
++       * the interrupt state change (memory).  This ensures
++       * that interrupt changes are treated as a critical
++       * section.
++       *
++       * Atomic change to our bit in scratchpad1 without
++       * causing any temporary glitch in the value and
++       * without effecting other values.  Also this uses
++       * no branches so no penalties.
++       */
++      asm volatile (
++      "       xor.4   %0, scratchpad1, %1             \n\t"
++      "       and.4   %0, %2, %0                      \n\t"
++      "       xor.4   scratchpad1, scratchpad1, %0    \n\t"
++      "       move.4  int_set0, %3                    \n\t"
++              : "=&d"(temp)
++              : "d"(flags), "r"(mask), "r"(ldsr_soft_irq_mask)
++              : "cc", "memory"
++      );
++}
++
++/*
++ * ldsr_local_irq_disable_interrupt()
++ *    Disable ints for this thread.
++ */
++static inline void ldsr_local_irq_disable(void)
++{
++      unsigned int mask = (1 << thread_get_self());
++
++      /*
++       * Ensure the compiler can not optimize out the code
++       * (volatile) and that it does not "cache" values around
++       * the interrupt state change (memory).  This ensures
++       * that interrupt changes are treated as a critical
++       * section.
++       */
++      asm  volatile (
++      "       or.4    scratchpad1, scratchpad1, %0    \n\t"
++              :
++              : "d" (mask)
++              : "cc", "memory"
++      );
++}
++
++/*
++ * ldsr_local_irq_enable_interrupt
++ *    Enable ints for this thread.
++ */
++static inline void ldsr_local_irq_enable(void)
++{
++      unsigned int mask = (1 << thread_get_self());
++
++      /*
++       * Ensure the compiler can not optimize out the code
++       * (volatile) and that it does not "cache" values around
++       * the interrupt state change (memory).  This ensures
++       * that interrupt changes are treated as a critical
++       * section.
++       */
++      asm volatile (
++      "       and.4   scratchpad1, scratchpad1, %0    \n\t"
++      "       move.4  int_set0, %1                    \n\t"
++              :
++              : "d" (~mask), "r" (ldsr_soft_irq_mask)
++              : "cc", "memory"
++      );
++}
++
++extern void ldsr_init(void);
++extern void ldsr_set_trap_irq(unsigned int irq);
++extern void ldsr_mask_vector(unsigned int vector);
++extern void ldsr_unmask_vector(unsigned int vector);
++extern void ldsr_enable_vector(unsigned int vector);
++extern void ldsr_disable_vector(unsigned int vector);
++extern thread_t ldsr_get_threadid(void);
++
++#endif /* _ASM_UBICOM32_LDSR_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/linkage.h
+@@ -0,0 +1,34 @@
++/*
++ * arch/ubicom32/include/asm/linkage.h
++ *   Definition of Ubicom32 architecture specific linkage types.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_LINKAGE_H
++#define _ASM_UBICOM32_LINKAGE_H
++
++#define __ocm_text __section(.ocm_text)
++#define __ocm_data __section(.ocm_data)
++
++#endif        /* _ASM_UBICOM32_LINKAGE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/local.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/local.h
++ *   Generic local.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_LOCAL_H
++#define _ASM_UBICOM32_LOCAL_H
++
++#include <asm-generic/local.h>
++
++#endif /* _ASM_UBICOM32_LOCAL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/machdep.h
+@@ -0,0 +1,43 @@
++/*
++ * arch/ubicom32/include/asm/machdep.h
++ *   Machine dependent utility routines.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MACHDEP_H
++#define _ASM_UBICOM32_MACHDEP_H
++
++#include <linux/interrupt.h>
++
++/* Hardware clock functions */
++extern unsigned long hw_timer_offset(void);
++
++/* machine dependent power off functions */
++extern void (*mach_reset)(void);
++extern void (*mach_halt)(void);
++extern void (*mach_power_off)(void);
++
++extern void config_BSP(char *command, int len);
++
++#endif /* _ASM_UBICOM32_MACHDEP_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/mc146818rtc.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/ubicom32/include/asm/mc146818rtc.h
++ *   Generic mc146818rtc.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++/*
++ * Machine dependent access functions for RTC registers.
++ */
++#ifndef _ASM_UBICOM32_MC146818RTC_H
++#define _ASM_UBICOM32_MC146818RTC_H
++
++/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
++
++#endif /* _ASM_UBICOM32_MC146818RTC_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/mman.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/ubicom32/include/asm/mman.h
++ *   Memory mapping definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MMAN_H
++#define _ASM_UBICOM32_MMAN_H
++
++#include <asm-generic/mman.h>
++
++#define MAP_GROWSDOWN 0x0100          /* stack-like segment */
++#define MAP_DENYWRITE 0x0800          /* ETXTBSY */
++#define MAP_EXECUTABLE        0x1000          /* mark it as an executable */
++#define MAP_LOCKED    0x2000          /* pages are locked */
++#define MAP_NORESERVE 0x4000          /* don't check for reservations */
++#define MAP_POPULATE  0x8000          /* populate (prefault) pagetables */
++#define MAP_NONBLOCK  0x10000         /* do not block on IO */
++
++#define MCL_CURRENT   1               /* lock all current mappings */
++#define MCL_FUTURE    2               /* lock all future mappings */
++
++#endif /* _ASM_UBICOM32_MMAN_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/mmu_context.h
+@@ -0,0 +1,60 @@
++/*
++ * arch/ubicom32/include/asm/mmu_context.h
++ *   MMU context definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 2004, Microtronix Datacom Ltd., All rights reserved.          
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_MMU_CONTEXT_H
++#define _ASM_UBICOM32_MMU_CONTEXT_H
++
++#include <asm/setup.h>
++#include <asm/page.h>
++#include <asm/pgalloc.h>
++
++static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
++{
++}
++
++extern inline int
++init_new_context(struct task_struct *tsk, struct mm_struct *mm)
++{
++      // mm->context = virt_to_phys(mm->pgd);
++      return(0);
++}
++
++#define destroy_context(mm)           do { } while(0)
++
++static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
++{
++}
++
++#define deactivate_mm(tsk,mm) do { } while (0)
++
++extern inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
++{
++}
++
++#endif /* _ASM_UBICOM32_MMU_CONTEXT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/mmu.h
+@@ -0,0 +1,41 @@
++/*
++ * arch/ubicom32/include/asm/mmu.h
++ *   Definition of mm_context_t struct for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 2002, David McCullough <davidm@snapgear.com>
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MMU_H
++#define _ASM_UBICOM32_MMU_H
++
++typedef struct {
++      struct vm_list_struct   *vmlist;
++      unsigned long           end_brk;
++#ifdef CONFIG_BINFMT_ELF_FDPIC
++      unsigned long   exec_fdpic_loadmap;
++      unsigned long   interp_fdpic_loadmap;
++#endif
++} mm_context_t;
++
++#endif /* _ASM_UBICOM32_MMU_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/module.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/ubicom32/include/asm/module.h
++ *   Ubicom32 architecture specific module definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MODULE_H
++#define _ASM_UBICOM32_MODULE_H
++
++struct mod_arch_specific {
++      void *ocm_inst;
++      int ocm_inst_size;
++};
++
++#define Elf_Shdr Elf32_Shdr
++#define Elf_Sym Elf32_Sym
++#define Elf_Ehdr Elf32_Ehdr
++
++#define ARCH_PROC_MODULES_EXTRA(m,mod) \
++      seq_printf(m, " OCM(%d bytes @ 0x%p)", \
++                 (mod)->arch.ocm_inst_size, (mod)->arch.ocm_inst)
++
++#endif /* _ASM_UBICOM32_MODULE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/msgbuf.h
+@@ -0,0 +1,58 @@
++/*
++ * arch/ubicom32/include/asm/msgbuf.h
++ *   Definition of msqid64_ds struct for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MSGBUF_H
++#define _ASM_UBICOM32_MSGBUF_H
++
++/*
++ * The msqid64_ds structure for ubicom32 architecture.
++ * Note extra padding because this structure is passed back and forth
++ * between kernel and user space.
++ *
++ * Pad space is left for:
++ * - 64-bit time_t to solve y2038 problem
++ * - 2 miscellaneous 32-bit values
++ */
++
++struct msqid64_ds {
++      struct ipc64_perm msg_perm;
++      __kernel_time_t msg_stime;      /* last msgsnd time */
++      unsigned long   __unused1;
++      __kernel_time_t msg_rtime;      /* last msgrcv time */
++      unsigned long   __unused2;
++      __kernel_time_t msg_ctime;      /* last change time */
++      unsigned long   __unused3;
++      unsigned long  msg_cbytes;      /* current number of bytes on queue */
++      unsigned long  msg_qnum;        /* number of messages in queue */
++      unsigned long  msg_qbytes;      /* max number of bytes on queue */
++      __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
++      __kernel_pid_t msg_lrpid;       /* last receive pid */
++      unsigned long  __unused4;
++      unsigned long  __unused5;
++};
++
++#endif /* _ASM_UBICOM32_MSGBUF_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/mutex.h
+@@ -0,0 +1,41 @@
++/*
++ * arch/ubicom32/include/asm/mutex.h
++ *   Generic mutex.h for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++/*
++ * Pull in the generic implementation for the mutex fastpath.
++ *
++ * TODO: implement optimized primitives instead, or leave the generic
++ * implementation in place, or pick the atomic_xchg() based generic
++ * implementation. (see asm-generic/mutex-xchg.h for details)
++ */
++
++#ifndef _ASM_UBICOM32_MUTEX_H
++#define _ASM_UBICOM32_MUTEX_H
++
++#include <asm-generic/mutex-dec.h>
++
++#endif /* _ASM_UBICOM32_MUTEX_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/namei.h
+@@ -0,0 +1,38 @@
++/*
++ * arch/ubicom32/include/asm/namei.h
++ *   Definition of __emul_prefix() for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_NAMEI_H
++#define _ASM_UBICOM32_NAMEI_H
++
++/* This dummy routine maybe changed to something useful
++ * for /usr/gnemul/ emulation stuff.
++ * Look at asm-sparc/namei.h for details.
++ */
++
++#define __emul_prefix() NULL
++
++#endif /* _ASM_UBICOM32_NAMEI_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ocm-alloc.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/ubicom32/include/asm/ocm-alloc.h
++ *   Ubicom32 architecture specific ocm definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_OCM_ALLOC_H
++#define _ASM_UBICOM32_OCM_ALLOC_H
++
++
++extern void *ocm_inst_alloc(size_t size, pid_t pid);
++extern int ocm_free(const void *ptr);
++extern int ocm_inst_free(const void *ptr);
++
++#endif /* _ASM_UBICOM32_OCM_ALLOC_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ocm_size.h
+@@ -0,0 +1,2 @@
++#define APP_OCM_CODE_SIZE (0x3ffc2e00-0x3ffc0000)
++#define APP_OCM_DATA_SIZE (0x3ffd3500-0x3ffc8000)
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ocm_text.lds.inc
+@@ -0,0 +1,175 @@
++/*
++ * arch/ubicom32/include/asm/ocm_text.lds.inc
++ *    <TODO: Replace with short file description>
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++*(.text.do_csum)
++*(.text.tcp_packet)
++*(.text.ipt_do_table)
++*(.text.nf_conntrack_in)
++*(.text.ip_forward)
++*(.text.dev_queue_xmit)
++*(.text.netif_receive_skb)
++*(.text.ip_route_input)
++*(.text.ip_finish_output)
++*(.text.nf_iterate)
++*(.text.__hash_conntrack)
++*(.text.memset)
++*(.text.memcpy)
++*(.text.ip_rcv)
++*(.text.__nf_conntrack_find)
++*(.text.dev_hard_start_xmit)
++*(.text.vlan_dev_hard_start_xmit)
++*(.text.vlan_dev_hard_header)
++*(.text.__nf_ct_refresh_acct)
++*(.text.tcp_error)
++*(.text.pfifo_fast_enqueue)
++*(.text.ipv4_confirm)
++*(.text.ip_output)
++*(.text.neigh_connected_output)
++*(.text.nf_hook_slow)
++*(.text.nf_nat_packet)
++*(.text.local_bh_enable)
++*(.text.pfifo_fast_dequeue)
++*(.text.ubi32_eth_receive)
++*(.text.nf_nat_fn)
++*(.text.skb_checksum)
++*(.text.memmove)
++*(.text.ubi32_eth_tx_done)
++*(.text.eth_header)
++*(.text.skb_release_data)
++*(.text.nf_conntrack_find_get)
++*(.text.process_backlog)
++*(.text.vlan_skb_recv)
++*(.text.ip_rcv_finish)
++*(.text.__qdisc_run)
++*(.text.skb_push)
++*(.text.eth_type_trans)
++*(.text.__alloc_skb)
++*(.text.netif_rx)
++*(.text.nf_ip_checksum)
++*(.text.__skb_checksum_complete_head)
++*(.text.ipv4_conntrack_defrag)
++*(.text.tcp_pkt_to_tuple)
++*(.text.kfree)
++*(.text.tcp_manip_pkt)
++*(.text.skb_put)
++*(.text.nf_ct_get_tuple)
++*(.text.__kmalloc)
++*(.text.ubi32_eth_start_xmit)
++*(.text.free_block)
++*(.text.ipt_hook)
++*(.text.kmem_cache_free)
++*(.text.skb_pull_rcsum)
++*(.text.cache_alloc_refill)
++*(.text.skb_release_head_state)
++*(.text.manip_pkt)
++*(.text.ip_sabotage_in)
++*(.text.ip_forward_finish)
++*(.text.kmem_cache_alloc)
++*(.text.local_bh_disable)
++*(.text.ipv4_pkt_to_tuple)
++*(.text.inet_proto_csum_replace4)
++*(.text.__nf_ct_l4proto_find)
++*(.text.csum_partial)
++*(.text.neigh_resolve_output)
++*(.text.__kfree_skb)
++*(.text.kfree_skb)
++*(.text.__find_vlan_dev)
++*(.text.ldsr_ctxsw_thread)
++*(.text.__do_IRQ)
++*(.text.skb_pull)
++*(.text.ipv4_invert_tuple)
++*(.text.nf_ct_invert_tuplepr)
++*(.text.skb_make_writable)
++*(.text.ipv4_get_l4proto)
++*(.text.handle_IRQ_event)
++*(.text.net_rx_action)
++*(.text.__do_softirq)
++*(.text.nf_nat_in)
++*(.text.note_interrupt)
++*(.text.ipv4_conntrack_in)
++*(.text.dst_release)
++*(.text.tasklet_action)
++*(.text.nf_nat_out)
++*(.text.nf_ct_invert_tuple)
++*(.text.do_IRQ)
++*(.text.__tasklet_schedule)
++*(.text.__skb_checksum_complete)
++*(.text.ubi32_eth_interrupt)
++*(.text.dev_kfree_skb_any)
++*(.text.ret_from_interrupt_to_kernel)
++*(.text.preemptive_context_save)
++*(.text.irq_ack_vector)
++*(.text.update_wall_time)
++*(.text.ldsr_thread)
++*(.text.irq_exit)
++*(.text.ubi32_eth_do_tasklet)
++*(.text.__napi_schedule)
++*(.text.idle_cpu)
++*(.text.run_timer_softirq)
++*(.text.ldsr_mask_vector)
++*(.text.irq_enter)
++*(.text.ldsr_get_lsb)
++*(.text.ldsr_unmask_vector)
++*(.text.ip_fast_csum)
++*(.text.hrtimer_run_queues)
++*(.text.tcp_invert_tuple)
++*(.text.T___705)
++*(.text.run_posix_cpu_timers)
++*(.text.free_hot_cold_page)
++*(.text.lock_timer_base)
++*(.text.calc_delta_mine)
++*(.text.slab_destroy)
++*(.text.rcu_pending)
++*(.text.scheduler_tick)
++*(.text.hrtimer_run_pending)
++*(.text.do_softirq)
++*(.text.del_timer)
++*(.text.irq_end_vector)
++*(.text.pci_read_u32)
++*(.text.udivmodsi4)
++*(.text.memcmp)
++*(.text.memset)
++*(.text.__slab_alloc)
++*(.text.br_handle_frame)
++*(.text.br_fdb_update)
++*(.text.__br_fdb_get)
++*(.text.br_forward)
++*(.text.br_handle_frame_finish)
++*(.text.pci_write_u32)
++*(.text.kmem_freepages)
++*(.text.br_dev_queue_push_xmit)
++*(.text.ioread32)
++*(.text.next_zones_zonelist)
++*(.text.ubi32_pci_read_u32)
++*(.text.zone_watermark_ok)
++*(.text.__rmqueue_smallest)
++*(.text.ubi32_eth_napi_poll)
++*(.text.ubi32_pci_write_u32)
++*(.text.ubi32_pci_read_u32)
++*(.text._local_bh_enable)
++*(.text._local_bh_disable)
++*(.text.get_slab)
+--- /dev/null
++++ b/arch/ubicom32/include/asm/page.h
+@@ -0,0 +1,106 @@
++/*
++ * arch/ubicom32/include/asm/page.h
++ *   Memory page related operations and definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PAGE_H
++#define _ASM_UBICOM32_PAGE_H
++
++/* PAGE_SHIFT determines the page size */
++
++#define PAGE_SHIFT    12
++#define PAGE_SIZE     (1 << PAGE_SHIFT)
++#define PAGE_MASK     (~(PAGE_SIZE-1))
++
++#include <asm/setup.h>
++
++#ifndef __ASSEMBLY__
++
++#define get_user_page(vaddr)          __get_free_page(GFP_KERNEL)
++#define free_user_page(page, addr)    free_page(addr)
++
++#define clear_page(page)      memset((page), 0, PAGE_SIZE)
++#define copy_page(to,from)    memcpy((to), (from), PAGE_SIZE)
++
++#define clear_user_page(page, vaddr, pg)      clear_page(page)
++#define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
++
++#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
++      alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
++#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
++
++/*
++ * These are used to make use of C type-checking..
++ */
++typedef struct { unsigned long pte; } pte_t;
++typedef struct { unsigned long pmd[16]; } pmd_t;
++typedef struct { unsigned long pgd; } pgd_t;
++typedef struct { unsigned long pgprot; } pgprot_t;
++typedef struct page *pgtable_t;
++
++#define pte_val(x)    ((x).pte)
++#define pmd_val(x)    ((&x)->pmd[0])
++#define pgd_val(x)    ((x).pgd)
++#define pgprot_val(x) ((x).pgprot)
++
++#define __pte(x)      ((pte_t) { (x) } )
++#define __pmd(x)      ((pmd_t) { (x) } )
++#define __pgd(x)      ((pgd_t) { (x) } )
++#define __pgprot(x)   ((pgprot_t) { (x) } )
++
++extern unsigned long memory_start;
++extern unsigned long memory_end;
++
++#endif /* !__ASSEMBLY__ */
++
++#include <asm/page_offset.h>
++
++#define PAGE_OFFSET           (PAGE_OFFSET_RAW)
++
++#ifndef __ASSEMBLY__
++
++#define __pa(vaddr)           virt_to_phys((void *)(vaddr))
++#define __va(paddr)           phys_to_virt((unsigned long)(paddr))
++
++#define virt_to_pfn(kaddr)    (__pa(kaddr) >> PAGE_SHIFT)
++#define pfn_to_virt(pfn)      __va((pfn) << PAGE_SHIFT)
++
++#define virt_to_page(addr)    (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
++#define page_to_virt(page)    ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
++
++#define pfn_to_page(pfn)      virt_to_page(pfn_to_virt(pfn))
++#define page_to_pfn(page)     virt_to_pfn(page_to_virt(page))
++#define pfn_valid(pfn)                ((pfn) < max_mapnr)
++
++#define       virt_addr_valid(kaddr)  (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
++                              ((void *)(kaddr) < (void *)memory_end))
++
++#endif /* __ASSEMBLY__ */
++
++#ifdef __KERNEL__
++#include <asm-generic/page.h>
++#endif
++
++#endif /* _ASM_UBICOM32_PAGE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/page_offset.h
+@@ -0,0 +1,35 @@
++/*
++ * arch/ubicom32/include/asm/page_offset.h
++ *   Definition of PAGE_OFFSET_RAW for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_PAGE_OFFSET_H
++#define _ASM_UBICOM32_PAGE_OFFSET_H
++
++/* This handles the memory map.. */
++#define       PAGE_OFFSET_RAW         0x3ffc0000
++
++#endif /* _ASM_UBICOM32_PAGE_OFFSET_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/param.h
+@@ -0,0 +1,49 @@
++/*
++ * arch/ubicom32/include/asm/param.h
++ *   Definition of miscellaneous constants, including HZ.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PARAM_H
++#define _ASM_UBICOM32_PARAM_H
++
++#ifdef __KERNEL__
++#define HZ CONFIG_HZ
++#define       USER_HZ         HZ
++#define       CLOCKS_PER_SEC  (USER_HZ)
++#endif
++
++#ifndef HZ
++#define HZ    100
++#endif
++
++#define EXEC_PAGESIZE 4096
++
++#ifndef NOGROUP
++#define NOGROUP               (-1)
++#endif
++
++#define MAXHOSTNAMELEN        64      /* max length of hostname */
++
++#endif /* _ASM_UBICOM32_PARAM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/pci.h
+@@ -0,0 +1,210 @@
++/*
++ * arch/ubicom32/include/asm/pci.h
++ *   Definitions of PCI operations for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PCI_H
++#define _ASM_UBICOM32_PCI_H
++
++#include <asm/io.h>
++
++/* The PCI address space does equal the physical memory
++ * address space.  The networking and block device layers use
++ * this boolean for bounce buffer decisions.
++ */
++#define PCI_DMA_BUS_IS_PHYS   (1)
++
++
++
++/*
++ * Perform a master read/write to the PCI bus.
++ * These functions return a PCI_RESP_xxx code.
++ */
++extern u8 pci_read_u32(u8 pci_cmd, u32 address, u32 *data);
++extern u8 pci_write_u32(u8 pci_cmd, u32 address, u32 data);
++extern u8 pci_read_u16(u8 pci_cmd, u32 address, u16 *data);
++extern u8 pci_write_u16(u8 pci_cmd, u32 address, u16 data);
++extern u8 pci_read_u8(u8 pci_cmd, u32 address, u8 *data);
++extern u8 pci_write_u8(u8 pci_cmd, u32 address, u8 data);
++
++
++#define PCIBIOS_MIN_IO          0x100
++#define PCIBIOS_MIN_MEM         0x10000000
++
++#define pcibios_assign_all_busses()   0
++#define pcibios_scan_all_fns(a, b)    0
++extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
++      struct resource *res);
++
++extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
++      struct pci_bus_region *region);
++
++struct pci_sys_data;
++struct pci_bus;
++
++struct hw_pci {
++        struct list_head buses;
++        int             nr_controllers;
++        int             (*setup)(int nr, struct pci_sys_data *);
++        struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
++        void            (*preinit)(void);
++        void            (*postinit)(void);
++        u8              (*swizzle)(struct pci_dev *dev, u8 *pin);
++        int             (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
++};
++
++/*
++ * Per-controller structure
++ */
++struct pci_sys_data {
++        struct list_head node;
++        int             busnr;          /* primary bus number                   */
++        u64             mem_offset;     /* bus->cpu memory mapping offset       */
++        unsigned long   io_offset;      /* bus->cpu IO mapping offset           */
++        struct pci_bus  *bus;           /* PCI bus                              */
++        struct resource *resource[3];   /* Primary PCI bus resources            */
++                                        /* Bridge swizzling                     */
++        u8              (*swizzle)(struct pci_dev *, u8 *);
++                                        /* IRQ mapping                          */
++        int             (*map_irq)(struct pci_dev *, u8, u8);
++        struct hw_pci   *hw;
++};
++
++static  inline struct resource *
++pcibios_select_root(struct pci_dev *pdev, struct resource *res)
++{
++        struct resource *root = NULL;
++
++        if (res->flags & IORESOURCE_IO)
++                root = &ioport_resource;
++        if (res->flags & IORESOURCE_MEM)
++                root = &iomem_resource;
++
++        return root;
++}
++
++static inline void pcibios_set_master(struct pci_dev *dev)
++{
++        /* No special bus mastering setup handling */
++}
++#define HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE 1
++#define HAVE_ARCH_PCI_SET_DMA_SEGMENT_BOUNDARY 1
++
++#ifdef CONFIG_PCI
++static inline void * pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
++                     dma_addr_t *dma_handle)
++{
++    void *vaddr = kmalloc(size, GFP_KERNEL);
++    if(vaddr != NULL) {
++        *dma_handle = virt_to_phys(vaddr);
++    }
++    return vaddr;
++}
++
++static  inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
++{
++      return 1;
++}
++
++static  inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
++      void *cpu_addr, dma_addr_t dma_handle)
++{ 
++      kfree(cpu_addr);
++      return;
++}
++
++static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
++      size_t size, int direction)
++{
++       return virt_to_phys(ptr);
++}
++
++static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
++      size_t size, int direction)
++{
++       return;
++}
++
++static inline dma_addr_t
++pci_map_page(struct pci_dev *hwdev, struct page *page,
++             unsigned long offset, size_t size, int direction)
++{
++       return pci_map_single(hwdev, page_address(page) + offset, size, (int)direction);
++}
++
++static inline void
++pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
++               size_t size, int direction)
++{
++      pci_unmap_single(hwdev, dma_address, size, direction);
++}
++
++static inline int
++pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
++           int nents, int direction)
++{
++        return nents; 
++}
++
++static inline void
++pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
++             int nents, int direction)
++{
++}
++
++static inline void
++pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
++                int nelems, int direction)
++{
++}
++
++static inline void
++pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
++                int nelems, int direction)
++{
++}
++
++static inline void
++pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
++                    size_t size, int direction)
++{
++}
++
++static inline void
++pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
++                    size_t size, int direction)
++{
++}
++
++static inline int
++pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr)
++{
++        return dma_addr == 0;
++}
++extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
++extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
++#endif
++
++#endif /* _ASM_UBICOM32_PCI_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/percpu.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/percpu.h
++ *   Generic percpu.h for the Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PERCPU_H
++#define _ASM_UBICOM32_PERCPU_H
++
++#include <asm-generic/percpu.h>
++
++#endif /* _ASM_UBICOM32_PERCPU_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/pgalloc.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/ubicom32/include/asm/pgalloc.h
++ *   Page table allocation definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PGALLOC_H
++#define _ASM_UBICOM32_PGALLOC_H
++
++#include <linux/mm.h>
++#include <asm/setup.h>
++
++#define check_pgt_cache()     do { } while (0)
++
++#endif /* _ASM_UBICOM32_PGALLOC_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/pgtable.h
+@@ -0,0 +1,124 @@
++/*
++ * arch/ubicom32/include/asm/pgtable.h
++ *   Ubicom32 pseudo page table definitions and operations.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 2004   Microtronix Datacom Ltd
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ *   and various works, Alpha, ix86, M68K, Sparc, ...et al
++ */
++#ifndef _ASM_UBICOM32_PGTABLE_H
++#define _ASM_UBICOM32_PGTABLE_H
++
++#include <asm-generic/4level-fixup.h>
++
++//vic - this bit copied from m68knommu version
++#include <asm/setup.h>
++#include <asm/io.h>
++#include <linux/sched.h>
++
++typedef pte_t *pte_addr_t;
++
++#define pgd_present(pgd)      (1)       /* pages are always present on NO_MM */
++#define pgd_none(pgd)         (0)
++#define pgd_bad(pgd)          (0)
++#define pgd_clear(pgdp)
++#define kern_addr_valid(addr)         (1)
++#define       pmd_offset(a, b)        ((void *)0)
++
++#define PAGE_NONE             __pgprot(0)    /* these mean nothing to NO_MM */
++#define PAGE_SHARED           __pgprot(0)    /* these mean nothing to NO_MM */
++#define PAGE_COPY             __pgprot(0)    /* these mean nothing to NO_MM */
++#define PAGE_READONLY         __pgprot(0)    /* these mean nothing to NO_MM */
++#define PAGE_KERNEL           __pgprot(0)    /* these mean nothing to NO_MM */
++//vic - this bit copied from m68knommu version
++
++extern void paging_init(void);
++#define swapper_pg_dir ((pgd_t *) 0)
++
++#define __swp_type(x)         (0)
++#define __swp_offset(x)               (0)
++#define __swp_entry(typ,off)  ((swp_entry_t) { ((typ) | ((off) << 7)) })
++#define __pte_to_swp_entry(pte)       ((swp_entry_t) { pte_val(pte) })
++#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
++
++/*
++ * pgprot_noncached() is only for infiniband pci support, and a real
++ * implementation for RAM would be more complicated.
++ */
++#define pgprot_noncached(prot)        (prot)
++
++static inline int pte_file(pte_t pte) { return 0; }
++
++/*
++ * ZERO_PAGE is a global shared page that is always zero: used
++ * for zero-mapped memory areas etc..
++ */
++#define ZERO_PAGE(vaddr)      (virt_to_page(0))
++
++extern unsigned int kobjsize(const void *objp);
++extern int is_in_rom(unsigned long);
++
++/*
++ * No page table caches to initialise
++ */
++#define pgtable_cache_init()   do { } while (0)
++
++#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)               \
++              remap_pfn_range(vma, vaddr, pfn, size, prot)
++
++extern inline void flush_cache_mm(struct mm_struct *mm)
++{
++}
++
++extern inline void flush_cache_range(struct mm_struct *mm,
++                                   unsigned long start,
++                                   unsigned long end)
++{
++}
++
++/* Push the page at kernel virtual address and clear the icache */
++extern inline void flush_page_to_ram (unsigned long address)
++{
++}
++
++/* Push n pages at kernel virtual address and clear the icache */
++extern inline void flush_pages_to_ram (unsigned long address, int n)
++{
++}
++
++/*
++ * All 32bit addresses are effectively valid for vmalloc...
++ * Sort of meaningless for non-VM targets.
++ */
++#define       VMALLOC_START   0
++#define       VMALLOC_END     0xffffffff
++
++#define arch_enter_lazy_mmu_mode()    do {} while (0)
++#define arch_leave_lazy_mmu_mode()    do {} while (0)
++#define arch_flush_lazy_mmu_mode()    do {} while (0)
++#define arch_enter_lazy_cpu_mode()    do {} while (0)
++#define arch_leave_lazy_cpu_mode()    do {} while (0)
++#define arch_flush_lazy_cpu_mode()    do {} while (0)
++
++#endif /* _ASM_UBICOM32_PGTABLE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/poll.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/ubicom32/include/asm/poll.h
++ *   Ubicom32 specific poll() related flags definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_POLL_H
++#define _ASM_UBICOM32_POLL_H
++
++#define POLLWRNORM    POLLOUT
++#define POLLWRBAND    0x0100
++
++#include <asm-generic/poll.h>
++
++#endif /* _ASM_UBICOM32_POLL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/posix_types.h
+@@ -0,0 +1,93 @@
++/*
++ * arch/ubicom32/include/asm/posix_types.h
++ *   Ubicom32 architecture posix types.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 2004   Microtronix Datacom Ltd
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef __ARCH_UBICOM32_POSIX_TYPES_H
++#define __ARCH_UBICOM32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long __kernel_ino_t;
++typedef unsigned short        __kernel_mode_t;
++typedef unsigned short        __kernel_nlink_t;
++typedef long          __kernel_off_t;
++typedef int           __kernel_pid_t;
++typedef unsigned short        __kernel_ipc_pid_t;
++typedef unsigned short        __kernel_uid_t;
++typedef unsigned short        __kernel_gid_t;
++typedef unsigned int  __kernel_size_t;
++typedef int           __kernel_ssize_t;
++typedef int           __kernel_ptrdiff_t;
++typedef long          __kernel_time_t;
++typedef long          __kernel_suseconds_t;
++typedef long          __kernel_clock_t;
++typedef int           __kernel_timer_t;
++typedef int           __kernel_clockid_t;
++typedef int           __kernel_daddr_t;
++typedef char *                __kernel_caddr_t;
++typedef unsigned short        __kernel_uid16_t;
++typedef unsigned short        __kernel_gid16_t;
++typedef unsigned int  __kernel_uid32_t;
++typedef unsigned int  __kernel_gid32_t;
++
++typedef unsigned short        __kernel_old_uid_t;
++typedef unsigned short        __kernel_old_gid_t;
++typedef unsigned short        __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long     __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__KERNEL__) || defined(__USE_ALL)
++      int     val[2];
++#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
++      int     __val[2];
++#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
++} __kernel_fsid_t;
++
++#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
++
++#undef        __FD_SET
++#define       __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
++
++#undef        __FD_CLR
++#define       __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
++
++#undef        __FD_ISSET
++#define       __FD_ISSET(d, set)      ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
++
++#undef        __FD_ZERO
++#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
++
++#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
++
++#endif
+--- /dev/null
++++ b/arch/ubicom32/include/asm/processor.h
+@@ -0,0 +1,163 @@
++/*
++ * arch/ubicom32/include/asm/processor.h
++ *   Thread related definitions for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 1995 Hamish Macdonald
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not, 
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_PROCESSOR_H
++#define _ASM_UBICOM32_PROCESSOR_H
++
++/*
++ * Default implementation of macro that returns current
++ * instruction pointer ("program counter").
++ */
++#define current_text_addr() ({ __label__ _l; _l: &&_l;})
++
++#include <linux/compiler.h>
++#include <linux/threads.h>
++#include <asm/types.h>
++#include <asm/segment.h>
++#include <asm/fpu.h>
++#include <asm/ptrace.h>
++#include <asm/current.h>
++#include <asm/thread_info.h>
++
++#if defined(CONFIG_UBICOM32_V3)
++      #define CPU "IP5K"
++#endif
++#if defined(CONFIG_UBICOM32_V4)
++      #define CPU "IP7K"
++#endif
++#ifndef CPU
++      #define CPU "UNKNOWN"
++#endif
++
++/*
++ * User space process size: 1st byte beyond user address space.
++ */
++extern unsigned long memory_end;
++#define TASK_SIZE     (memory_end)
++
++/*
++ * This decides where the kernel will search for a free chunk of vm
++ * space during mmap's. We won't be using it
++ */
++#define TASK_UNMAPPED_BASE    0
++
++/*
++ * This is the structure where we are going to save callee-saved registers.
++ * A5 is the return address, A7 is the stack pointer, A6 is the frame
++ * pointer.  This is the frame that is created because of switch_to. This
++ * is not the frame due to interrupt preemption or because of syscall entry.
++ */
++
++struct thread_struct {
++      unsigned long  d10;             /* D10  */
++      unsigned long  d11;             /* D11  */
++      unsigned long  d12;             /* D12  */
++      unsigned long  d13;             /* D13  */
++      unsigned long  a1;              /* A1  */
++      unsigned long  a2;              /* A2  */
++      unsigned long  a5;              /* A5 return address. */
++      unsigned long  a6;              /* A6 */
++      unsigned long  sp;              /* A7 kernel stack pointer. */
++};
++
++#define INIT_THREAD  { \
++      0, 0, 0, 0, 0, 0, 0, 0, \
++      sizeof(init_stack) + (unsigned long) init_stack - 8, \
++}
++
++/*
++ * Do necessary setup to start up a newly executed thread.
++ *
++ * pass the data segment into user programs if it exists,
++ * it can't hurt anything as far as I can tell
++ */
++/*
++ * Do necessary setup to start up a newly executed thread.
++ */
++#define start_thread(regs, new_pc, new_sp)     \
++      do {                                     \
++              regs->pc = new_pc & ~3;          \
++              regs->an[5] = new_pc & ~3;       \
++              regs->an[7] = new_sp;            \
++              regs->nesting_level = -1;        \
++              regs->frame_type = UBICOM32_FRAME_TYPE_NEW_THREAD; \
++              regs->thread_type = NORMAL_THREAD; \
++      } while(0)
++
++/* Forward declaration, a strange C thing */
++struct task_struct;
++
++/* Free all resources held by a thread. */
++static inline void release_thread(struct task_struct *dead_task)
++{
++}
++
++/* Prepare to copy thread state - unlazy all lazy status */
++#define prepare_to_copy(tsk)  do { } while (0)
++
++extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
++
++/*
++ * Free current thread data structures etc..
++ */
++static inline void exit_thread(void)
++{
++}
++
++unsigned long thread_saved_pc(struct task_struct *tsk);
++unsigned long get_wchan(struct task_struct *p);
++
++#define       KSTK_EIP(tsk)   (tsk->thread.a5)
++#define       KSTK_ESP(tsk)   (tsk->thread.sp)
++
++#define cpu_relax()    barrier()
++
++extern void processor_init(void);
++extern unsigned int processor_timers(void);
++extern unsigned int processor_threads(void);
++extern unsigned int processor_frequency(void);
++extern int processor_interrupts(unsigned int *int0, unsigned int *int1);
++extern int processor_ocm(void **socm, void **eocm);
++extern int processor_dram(void **sdram, void **edram);
++
++#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
++#define KSTK_TOP(info)                                                 \
++({                                                                     \
++       unsigned long *__ptr = (unsigned long *)(info);                 \
++       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
++})
++
++#define task_pt_regs(task)                                             \
++({                                                                     \
++       struct pt_regs *__regs__;                                       \
++       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
++       __regs__ - 1;                                                   \
++})
++
++#endif        /* _ASM_UBICOM32_PROCESSOR_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ptrace.h
+@@ -0,0 +1,177 @@
++/*
++ * arch/ubicom32/include/asm/ptrace.h
++ *   Ubicom32 architecture ptrace support.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PTRACE_H
++#define _ASM_UBICOM32_PTRACE_H
++
++#ifndef __ASSEMBLY__
++
++/*
++ * We use hard coded constants because this is shared with user
++ * space and the values are NOT allowed to change.  Only fields
++ * that are intended to be exposed get values.
++ */
++#define PT_D0           0
++#define PT_D1           4
++#define PT_D2           8
++#define PT_D3           12
++#define PT_D4           16
++#define PT_D5           20
++#define PT_D6           24
++#define PT_D7           28
++#define PT_D8           32
++#define PT_D9           36
++#define PT_D10          40
++#define PT_D11          44
++#define PT_D12          48
++#define PT_D13          52
++#define PT_D14          56
++#define PT_D15          60
++#define PT_A0           64
++#define PT_A1           68
++#define PT_A2           72
++#define PT_A3           76
++#define PT_A4           80
++#define PT_A5           84
++#define PT_A6           88
++#define PT_A7           92
++#define PT_SP           92
++#define PT_ACC0HI       96
++#define PT_ACC0LO       100
++#define PT_MAC_RC16     104
++#define PT_ACC1HI       108
++#define PT_ACC1LO       112
++#define PT_SOURCE3      116
++#define PT_INST_CNT     120
++#define PT_CSR          124
++#define PT_DUMMY_UNUSED 128
++#define PT_INT_MASK0    132
++#define PT_INT_MASK1    136
++#define PT_TRAP_CAUSE   140
++#define PT_PC           144
++#define PT_ORIGINAL_D0  148
++#define PT_FRAME_TYPE   152
++
++/*
++ * The following 'registers' are not registers at all but are used
++ * locate the relocated sections.
++ */
++#define PT_TEXT_ADDR          200
++#define PT_TEXT_END_ADDR      204
++#define PT_DATA_ADDR          208
++#define PT_EXEC_FDPIC_LOADMAP 212
++#define PT_INTERP_FDPIC_LOADMAP       216
++
++/*
++ * This struct defines the way the registers are stored on the
++ * stack during a system call.
++ */
++enum thread_type {
++      NORMAL_THREAD,
++      KERNEL_THREAD,
++};
++
++#define UBICOM32_FRAME_TYPE_SYSCALL   -1 /* System call frame */
++#define UBICOM32_FRAME_TYPE_INVALID   0 /* Invalid frame, no longer in use */
++#define UBICOM32_FRAME_TYPE_INTERRUPT 1 /* Interrupt frame */
++#define UBICOM32_FRAME_TYPE_TRAP      2 /* Trap frame */
++#define UBICOM32_FRAME_TYPE_SIGTRAMP  3 /* Signal trampoline frame. */
++#define UBICOM32_FRAME_TYPE_NEW_THREAD        4 /* New Thread. */
++
++struct pt_regs {
++      /*
++       * Data Registers
++       */
++      unsigned long dn[16];
++
++      /*
++       * Address Registers
++       */
++      unsigned long an[8];
++
++      /*
++       * Per thread misc registers.
++       */
++      unsigned long acc0[2];
++      unsigned long mac_rc16;
++      unsigned long acc1[2];
++      unsigned long source3;
++      unsigned long inst_cnt;
++      unsigned long csr;
++      unsigned long dummy_unused;
++      unsigned long int_mask0;
++      unsigned long int_mask1;
++      unsigned long trap_cause;
++      unsigned long pc;
++      unsigned long original_dn_0;
++
++      /*
++       * Frame type. Syscall frames are -1. For other types look above.
++       */
++      unsigned long frame_type;
++
++      /*
++       * These fields are not exposed to ptrace.
++       */
++      unsigned long previous_pc;
++      long nesting_level;             /* When the kernel in in user space this
++                                       * will be -1. */
++      unsigned long thread_type;      /* This indicates if this is a kernel
++                                       * thread. */
++};
++
++/*
++ * This is the extended stack used by signal handlers and the context
++ * switcher: it's pushed after the normal "struct pt_regs".
++ */
++struct switch_stack {
++      unsigned long  dummy;
++};
++
++#ifdef __KERNEL__
++
++/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
++#define PTRACE_GETREGS                12
++#define PTRACE_SETREGS                13
++
++#ifndef PS_S
++#define PS_S  (0x2000)
++#define PS_M  (0x1000)
++#endif
++
++extern  int __user_mode(unsigned long sp);
++
++#define user_mode(regs) (__user_mode((regs->an[7])))
++#define user_stack(regs) ((regs)->an[7])
++#define instruction_pointer(regs) ((regs)->pc)
++#define profile_pc(regs) instruction_pointer(regs)
++extern void show_regs(struct pt_regs *);
++#endif /* __KERNEL__ */
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* _ASM_UBICOM32_PTRACE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/range-protect-asm.h
+@@ -0,0 +1,91 @@
++/*
++ * arch/ubicom32/include/asm/range-protect-asm.h
++ *   Assembly macros for enabling memory protection.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_RANGE_PROTECT_ASM_H
++#define _ASM_UBICOM32_RANGE_PROTECT_ASM_H
++
++#if defined(__ASSEMBLY__)
++
++#include <asm/thread-asm.h>
++
++/*
++ * You should only use the enable/disable ranges when you have the atomic lock,
++ * if you do not there will be problems.
++ */
++
++/*
++ * enable_kernel_ranges
++ *    Enable the kernel ranges (disabling protection) for thread,
++ *    where thread == (1 << thread number)
++ */
++.macro        enable_kernel_ranges thread
++#ifdef CONFIG_PROTECT_KERNEL
++      or.4    I_RANGE0_EN, I_RANGE0_EN, \thread        /* Enable Range Register */
++      or.4    D_RANGE0_EN, D_RANGE0_EN, \thread
++      or.4    D_RANGE1_EN, D_RANGE1_EN, \thread
++#endif
++.endm
++
++/*
++ * enable_kernel_ranges_for_current
++ *    Enable the kernel ranges (disabling protection) for this thread
++ */
++.macro        enable_kernel_ranges_for_current scratch_reg
++#ifdef CONFIG_PROTECT_KERNEL
++      thread_get_self_mask \scratch_reg
++      enable_kernel_ranges \scratch_reg
++#endif
++.endm
++
++/*
++ * disable_kernel_ranges
++ *    Disables the kernel ranges (enabling protection) for thread
++ *    where thread == (1 << thread number)
++ */
++.macro        disable_kernel_ranges thread
++#ifdef CONFIG_PROTECT_KERNEL
++      not.4   \thread, \thread
++      and.4   I_RANGE0_EN, I_RANGE0_EN, \thread        /* Disable Range Register */
++      and.4   D_RANGE0_EN, D_RANGE0_EN, \thread
++      and.4   D_RANGE1_EN, D_RANGE1_EN, \thread
++#endif
++.endm
++
++/*
++ * disable_kernel_ranges_for_current
++ *    Disable kernel ranges (enabling protection) for this thread
++ */
++.macro        disable_kernel_ranges_for_current scratch_reg
++#ifdef CONFIG_PROTECT_KERNEL
++      thread_get_self_mask \scratch_reg
++      disable_kernel_ranges \scratch_reg
++#endif
++.endm
++#endif
++
++#endif  /* _ASM_UBICOM32_RANGE_PROTECT_ASM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/range-protect.h
+@@ -0,0 +1,62 @@
++/*
++ * arch/ubicom32/include/asm/range-protect.h
++ *   Assembly macros declared in C for enabling memory protection.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ *
++ * This file is part of the Ubicom32 Linux Kernel Port.
++ *
++ * The Ubicom32 Linux Kernel Port is free software: you can redistribute
++ * it and/or modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation, either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * The Ubicom32 Linux Kernel Port is distributed in the hope that it
++ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
++ * the GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with the Ubicom32 Linux Kernel Port.  If not,
++ * see <http://www.gnu.org/licenses/>.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ *   arch/m68knommu
++ *   arch/blackfin
++ *   arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_RANGE_PROTECT_H
++#define _ASM_UBICOM32_RANGE_PROTECT_H
++
++#if !defined(__ASSEMBLY__)
++#include <asm/thread.h>
++/*
++ * The following macros should be the identical to the ones in
++ * range-protect-asm.h
++ *
++ * You should only use the enable/disable ranges when you have the atomic lock,
++ * if you do not there will be problems.
++ */
++
++/*
++ * enable_kernel_ranges
++ *    Enable the kernel ranges (disabling protection) for thread,
++ *    where thread == (1 << thread number)
++ */
++asm (
++      ".macro enable_kernel_ranges thread                     \n\t"
++#ifdef CONFIG_PROTECT_KERNEL
++      "       or.4    I_RANGE0_EN, I_RANGE0_EN, \\thread      \n\t" /* Enable Range Register */
++      "       or.4    D_RANGE0_E