diff --git a/target/linux/ubicom32/Makefile b/target/linux/ubicom32/Makefile
new file mode 100644
index 0000000000..7bdbd204e8
--- /dev/null
+++ b/target/linux/ubicom32/Makefile
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+#Add target specific (nommu) flags
+TARGET_CFLAGS+= -DNO_FORK
+
+ARCH:=ubicom32
+BOARD:=ubicom32
+BOARDNAME:=Ubicom IPxx
+FEATURES:=nommu
+
+LINUX_VERSION:=2.6.28.10
+
+include $(INCLUDE_DIR)/target.mk
+
+KERNEL_MAKEOPTS += LDFLAGS_BUILD_ID=""
+
+define Target/Description
+ Build firmware images for Ubicom based routers and media devices.
+endef
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/ubicom32/config-2.6.28 b/target/linux/ubicom32/config-2.6.28
new file mode 100755
index 0000000000..8c1dae5ddc
--- /dev/null
+++ b/target/linux/ubicom32/config-2.6.28
@@ -0,0 +1,169 @@
+# CONFIG_ACCESS_OK_CHECKS_ENABLED is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_AOUT=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_ARPD is not set
+CONFIG_BASE_SMALL=0
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_BITREVERSE=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BRD_64MB=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CLASSIC_RCU=y
+CONFIG_CMDLINE="console=ttyUM0 console=ttyUS0 serdes=0x02004000,61,250000000"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_RNG2=y
+# CONFIG_CRYPTO_UBICOM32 is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_IRQMEASURE is not set
+# CONFIG_DEBUG_PCIMEASURE is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEVKMEM=y
+CONFIG_DEVPORT=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_EPOLL is not set
+# CONFIG_EVENTFD is not set
+CONFIG_FORCE_MAX_ZONEORDER=14
+# CONFIG_FPU is not set
+# CONFIG_FUTEX is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GEN_RTC is not set
+CONFIG_GPIOLIB=y
+# CONFIG_HAMRADIO is not set
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_UBICOM32=y
+# CONFIG_I2C is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_SOURCE="../romfs ../vendors/Ubicom/RouterGateway/initramfs_list"
+CONFIG_INPUT=y
+# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IP5160DEV is not set
+# CONFIG_IP5160EVAL is not set
+# CONFIG_IP5170DPF is not set
+# CONFIG_IP7145DPF is not set
+# CONFIG_IP7160BRINGUP is not set
+# CONFIG_IP7160DPF is not set
+CONFIG_IP7160RGW=y
+# CONFIG_IP7500AV is not set
+# CONFIG_IP7500MEDIA is not set
+# CONFIG_IP7500MODULE is not set
+# CONFIG_IRQSTACKS is not set
+CONFIG_IRQ_PER_CPU=y
+# CONFIG_ISDN is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_KERNELBASE=0x40400000
+CONFIG_LDM_DEBUG=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_TRIGGERS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_LIBCRC32C=y
+# CONFIG_LINKER_RELAXATION is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_MMU is not set
+CONFIG_MODULE_FORCE_LOAD=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_UBI32_M25P80=y
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NOBOARD is not set
+CONFIG_NO_HZ=y
+CONFIG_NO_IOPORT=y
+# CONFIG_NO_KERNEL_MSG is not set
+CONFIG_OCM_MODULES_FALLBACK_TO_DDR=y
+CONFIG_OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE=y
+CONFIG_OCM_MODULES_RESERVATION=41
+# CONFIG_PACKET_MMAP is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PCI=y
+CONFIG_PCI_DEV0_IDSEL=0x001000000
+CONFIG_PCI_DEV1_IDSEL=0x002000000
+CONFIG_PRINTK_TIME=y
+CONFIG_PROTECT_KERNEL=y
+CONFIG_RAMBASE=0x40000000
+CONFIG_RAMKERNEL=y
+CONFIG_RAMSIZE=0x4000000
+# CONFIG_RTC is not set
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_UBI32_MAILBOX=y
+CONFIG_SERIAL_UBI32_MAILBOX_CONSOLE=y
+# CONFIG_SERIAL_UBI32_SERDES is not set
+# CONFIG_SERIAL_UBI32_UARTTIO is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_SMP is not set
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_MASTER=y
+# CONFIG_SPI_SPIDEV is not set
+CONFIG_SPI_UBICOM32_GPIO=y
+# CONFIG_STOP_ON_BUG is not set
+# CONFIG_STOP_ON_TRAP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_TICK_ONESHOT=y
+# CONFIG_TIMERFD is not set
+CONFIG_TIMER_EXTRA_ALLOC=0
+CONFIG_TIME_LOW_RES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_UBI32_WDT=y
+CONFIG_UBICOM32=y
+CONFIG_UBICOM32_GMAC=y
+CONFIG_UBICOM32_NAPI=y
+CONFIG_UBICOM32_OCM_FOR_SKB=y
+CONFIG_UBICOM32_V4=y
+# CONFIG_UBICOM_HID is not set
+CONFIG_UBICOM_INPUT=y
+# CONFIG_UBICOM_INPUT_I2C is not set
+# CONFIG_UNALIGNED_ACCESS_DISABLED is not set
+CONFIG_UNALIGNED_ACCESS_ENABLED=y
+# CONFIG_UNALIGNED_ACCESS_USERSPACE_ONLY is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
diff --git a/target/linux/ubicom32/image/Makefile b/target/linux/ubicom32/image/Makefile
new file mode 100644
index 0000000000..64b294d76e
--- /dev/null
+++ b/target/linux/ubicom32/image/Makefile
@@ -0,0 +1,12 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+# use default targets for everything
+
+$(eval $(call BuildImage))
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
index 0000000000..4ec511fa6e
--- /dev/null
+++ b/target/linux/ubicom32/patches-2.6.28/100-ubicom32_support.patch
@@ -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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++#include
++#include
++#include
++#include "crypto_ubicom32.h"
++#include
++
++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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * 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
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++
++#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 .
++ * Modified by Raimar Falke 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
++ * Copyright (c) Gisle Sflensminde
++ * Copyright (C) 2001 Niels Mvller.
++ * Copyright (c) 2002 James Morris
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++#include
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++
++#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
++#
++#
++# (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 .
++#
++# 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#define __ASM__
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#define __ASM__
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++#include
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ATOMIC_H
++#define _ASM_UBICOM32_ATOMIC_H
++
++#include
++#include
++#include
++
++/*
++ * 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
++
++/*
++ * 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 .
++ */
++
++#ifndef _AUDIO_TIO_H
++#define _AUDIO_TIO_H
++
++#include
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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
++#include /* swab32 */
++
++#ifdef __KERNEL__
++
++#ifndef _LINUX_BITOPS_H
++#error only can be included directly
++#endif
++
++#include
++#include
++
++#include
++#include
++
++#include
++
++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
++
++/*
++ * 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
++#include
++#include
++
++#include
++#include
++#include
++
++#endif /* __KERNEL__ */
++
++#include
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BUG_H
++#define _ASM_UBICOM32_BUG_H
++
++#include
++#include
++
++#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
++
++#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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_BYTEORDER_H
++#define _ASM_UBICOM32_BYTEORDER_H
++
++#include
++
++#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
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CACHECTL_H
++#define _ASM_UBICOM32_CACHECTL_H
++
++#include
++
++/*
++ * 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 .
++ *
++ * 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
++ */
++#include
++#include
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CHECKSUM_H
++#define _ASM_UBICOM32_CHECKSUM_H
++
++#include
++
++/*
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CPU_H
++#define _ASM_UBICOM32_CPU_H
++
++#include
++
++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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CPUTIME_H
++#define _ASM_UBICOM32_CPUTIME_H
++
++#include
++
++#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
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_CURRENT_H
++#define _ASM_UBICOM32_CURRENT_H
++
++#include
++
++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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DELAY_H
++#define _ASM_UBICOM32_DELAY_H
++
++#include
++#include
++
++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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DEVICE_H
++#define _ASM_UBICOM32_DEVICE_H
++
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_DIV64_H
++#define _ASM_UBICOM32_DIV64_H
++
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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
++#include
++
++#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 .
++ *
++ * 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
++#include
++
++/*
++ * 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 .
++ *
++ * 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
++#include
++
++/*
++ * 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 .
++ *
++ * 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
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ENTRY_H
++#define _ASM_UBICOM32_ENTRY_H
++
++#include
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_ERRNO_H
++#define _ASM_UBICOM32_ERRNO_H
++
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_FB_H
++#define _ASM_UBICOM32_FB_H
++#include
++
++#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 .
++ *
++ * 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
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_FUTEX_H
++#define _ASM_UBICOM32_FUTEX_H
++
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_GPIO_H
++#define _ASM_UBICOM32_GPIO_H
++
++#include
++#include
++
++#include
++
++#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
++
++/*
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_HARDIRQ_H
++#define _ASM_UBICOM32_HARDIRQ_H
++
++#include
++#include
++
++/*
++ * 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 /* 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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IOCTL_H
++#define _ASM_UBICOM32_IOCTL_H
++
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IOCTLS_H
++#define _ASM_UBICOM32_IOCTLS_H
++
++#include
++
++/* 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 .
++ *
++ * 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
++#include
++
++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 .
++ *
++ * 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 .
++ *
++ * 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
++
++/*
++ * 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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IRQFLAGS_H
++#define _ASM_UBICOM32_IRQFLAGS_H
++
++#include
++#include
++#include
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_IRQ_H
++#define _ASM_UBICOM32_IRQ_H
++
++#include
++
++/*
++ * 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 .
++ *
++ * 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
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_KDEBUG_H
++#define _ASM_UBICOM32_KDEBUG_H
++
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_LDSR_H
++#define _ASM_UBICOM32_LDSR_H
++
++#include
++#include
++#include
++
++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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_LOCAL_H
++#define _ASM_UBICOM32_LOCAL_H
++
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MACHDEP_H
++#define _ASM_UBICOM32_MACHDEP_H
++
++#include
++
++/* 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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_MMAN_H
++#define _ASM_UBICOM32_MMAN_H
++
++#include
++
++#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 .
++ *
++ * 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
++#include
++#include
++
++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
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * 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
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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
++ *
++ *
++ * (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 .
++ *
++ * 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 .
++ *
++ * 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
++
++#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
++
++#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
++#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 .
++ *
++ * 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 .
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PCI_H
++#define _ASM_UBICOM32_PCI_H
++
++#include
++
++/* 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PERCPU_H
++#define _ASM_UBICOM32_PERCPU_H
++
++#include
++
++#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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_PGALLOC_H
++#define _ASM_UBICOM32_PGALLOC_H
++
++#include
++#include
++
++#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 .
++ *
++ * 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
++
++//vic - this bit copied from m68knommu version
++#include
++#include
++#include
++
++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 .
++ *
++ * 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
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++
++#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 .
++ *
++ * 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 .
++ *
++ * 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
++
++/*
++ * 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 .
++ *
++ * 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
++/*
++ * 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_EN, D_RANGE0_EN, \\thread \n\t"
++ " or.4 D_RANGE1_EN, D_RANGE1_EN, \\thread \n\t"
++#endif
++ ".endm \n\t"
++);
++
++#else /* __ASSEMBLY__ */
++
++#include
++
++#endif
++#endif /* _ASM_UBICOM32_RANGE_PROTECT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/resource.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/resource.h
++ * Generic 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_RESOURCE_H
++#define _ASM_UBICOM32_RESOURCE_H
++
++#include
++
++#endif /* _ASM_UBICOM32_RESOURCE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ring_tio.h
+@@ -0,0 +1,42 @@
++/*
++ * arch/ubicom32/include/asm/ring_tio.h
++ * Ubicom32 architecture Ring TIO 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 .
++ */
++#ifndef _ASM_UBICOM32_RING_TIO_H
++#define _ASM_UBICOM32_RING_TIO_H
++
++#include
++
++#define RING_TIO_NODE_VERSION 2
++
++/*
++ * Devtree node for ring
++ */
++struct ring_tio_node {
++ struct devtree_node dn;
++
++ u32_t version;
++ void *regs;
++};
++
++extern void ring_tio_init(const char *node_name);
++
++#endif /* _ASM_UBICOM32_RING_TIO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/scatterlist.h
+@@ -0,0 +1,49 @@
++/*
++ * arch/ubicom32/include/asm/scatterlist.h
++ * Definitions of struct scatterlist 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SCATTERLIST_H
++#define _ASM_UBICOM32_SCATTERLIST_H
++
++#include
++#include
++
++struct scatterlist {
++#ifdef CONFIG_DEBUG_SG
++ unsigned long sg_magic;
++#endif
++ unsigned long page_link;
++ unsigned int offset;
++ dma_addr_t dma_address;
++ unsigned int length;
++};
++
++#define sg_dma_address(sg) ((sg)->dma_address)
++#define sg_dma_len(sg) ((sg)->length)
++
++#define ISA_DMA_THRESHOLD (0xffffffff)
++
++#endif /* _ASM_UBICOM32_SCATTERLIST_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/sd_tio.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/ubicom32/include/asm/sd_tio.h
++ * SD TIO 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 .
++ */
++#ifndef _ASM_UBICOM32_SD_TIO_H
++#define _ASM_UBICOM32_SD_TIO_H
++
++#include
++
++/*
++ * Devtree node for SD
++ */
++struct sd_tio_node {
++ struct devtree_node dn;
++ void *regs;
++};
++
++#endif /* _ASM_UBICOM32_SD_TIO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/sections.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/sections.h
++ * Generic sections.h 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SECTIONS_H
++#define _ASM_UBICOM32_SECTIONS_H
++
++#include
++
++#endif /* _ASM_UBICOM32_SECTIONS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/segment.h
+@@ -0,0 +1,78 @@
++/*
++ * arch/ubicom32/include/asm/segment.h
++ * Memory segment 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SEGMENT_H
++#define _ASM_UBICOM32_SEGMENT_H
++
++/* define constants */
++/* Address spaces (FC0-FC2) */
++#define USER_DATA (1)
++#ifndef __USER_DS
++#define __USER_DS (USER_DATA)
++#endif
++#define USER_PROGRAM (2)
++#define SUPER_DATA (5)
++#ifndef __KERNEL_DS
++#define __KERNEL_DS (SUPER_DATA)
++#endif
++#define SUPER_PROGRAM (6)
++#define CPU_SPACE (7)
++
++#ifndef __ASSEMBLY__
++
++typedef struct {
++ unsigned long seg;
++} mm_segment_t;
++
++#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
++#define USER_DS MAKE_MM_SEG(__USER_DS)
++#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
++
++/*
++ * Get/set the SFC/DFC registers for MOVES instructions
++ */
++
++static inline mm_segment_t get_fs(void)
++{
++ return USER_DS;
++}
++
++static inline mm_segment_t get_ds(void)
++{
++ /* return the supervisor data space code */
++ return KERNEL_DS;
++}
++
++static inline void set_fs(mm_segment_t val)
++{
++}
++
++#define segment_eq(a,b) ((a).seg == (b).seg)
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* _ASM_UBICOM32_SEGMENT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/semaphore.h
+@@ -0,0 +1,140 @@
++/*
++ * arch/ubicom32/include/asm/semaphore.h
++ * Interrupt-safe semaphores for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * (C) Copyright 1996 Linus Torvalds
++ * m68k version by Andreas Schwab
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SEMAPHORE_H
++#define _ASM_UBICOM32_SEMAPHORE_H
++
++#define RW_LOCK_BIAS 0x01000000
++
++#ifndef __ASSEMBLY__
++
++#include
++#include
++#include
++#include
++
++#include
++#include
++
++struct semaphore {
++ atomic_t count;
++ atomic_t waking;
++ wait_queue_head_t wait;
++};
++
++#define __SEMAPHORE_INITIALIZER(name, n) \
++{ \
++ .count = ATOMIC_INIT(n), \
++ .waking = ATOMIC_INIT(0), \
++ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
++}
++
++#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
++ struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
++
++#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
++#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
++
++static inline void sema_init (struct semaphore *sem, int val)
++{
++ *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
++}
++
++static inline void init_MUTEX (struct semaphore *sem)
++{
++ sema_init(sem, 1);
++}
++
++static inline void init_MUTEX_LOCKED (struct semaphore *sem)
++{
++ sema_init(sem, 0);
++}
++
++asmlinkage void __down_failed(void /* special register calling convention */);
++asmlinkage int __down_failed_interruptible(void /* params in registers */);
++asmlinkage int __down_failed_trylock(void /* params in registers */);
++asmlinkage void __up_wakeup(void /* special register calling convention */);
++
++asmlinkage void __down(struct semaphore * sem);
++asmlinkage int __down_interruptible(struct semaphore * sem);
++asmlinkage int __down_trylock(struct semaphore * sem);
++asmlinkage void __up(struct semaphore * sem);
++
++extern spinlock_t semaphore_wake_lock;
++
++/*
++ * This is ugly, but we want the default case to fall through.
++ * "down_failed" is a special asm handler that calls the C
++ * routine that actually waits.
++ */
++static inline void down(struct semaphore * sem)
++{
++ might_sleep();
++
++ if (atomic_dec_return(&sem->count) < 0)
++ __down(sem);
++}
++
++static inline int down_interruptible(struct semaphore * sem)
++{
++ int ret = 0;
++
++
++ might_sleep();
++
++ if(atomic_dec_return(&sem->count) < 0)
++ ret = __down_interruptible(sem);
++ return ret;
++}
++
++static inline int down_trylock(struct semaphore * sem)
++{
++ int ret = 0;
++
++ if (atomic_dec_return (&sem->count) < 0)
++ ret = __down_trylock(sem);
++ return ret;
++}
++
++/*
++ * Note! This is subtle. We jump to wake people up only if
++ * the semaphore was negative (== somebody was waiting on it).
++ * The default case (no contention) will result in NO
++ * jumps for both down() and up().
++ */
++static inline void up(struct semaphore * sem)
++{
++ if (atomic_inc_return(&sem->count) <= 0)
++ __up(sem);
++}
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* _ASM_UBICOM32_SEMAPHORE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/semaphore-helper.h
+@@ -0,0 +1,109 @@
++/*
++ * arch/ubicom32/include/asm/semaphore-helper.h
++ * Semaphore related 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SEMAPHORE_HELPER_H
++#define _ASM_UBICOM32_SEMAPHORE_HELPER_H
++
++/*
++ * SMP- and interrupt-safe semaphores helper functions.
++ *
++ * (C) Copyright 1996 Linus Torvalds
++ *
++ * m68k version by Andreas Schwab
++ */
++
++
++/*
++ * These two _must_ execute atomically wrt each other.
++ */
++static inline void wake_one_more(struct semaphore * sem)
++{
++ atomic_inc(&sem->waking);
++}
++
++static inline int waking_non_zero(struct semaphore *sem)
++{
++ int ret;
++ unsigned long flags;
++
++ spin_lock_irqsave(&semaphore_wake_lock, flags);
++ ret = 0;
++ if (atomic_read(&sem->waking) > 0) {
++ atomic_dec(&sem->waking);
++ ret = 1;
++ }
++ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
++ return ret;
++}
++
++/*
++ * waking_non_zero_interruptible:
++ * 1 got the lock
++ * 0 go to sleep
++ * -EINTR interrupted
++ */
++static inline int waking_non_zero_interruptible(struct semaphore *sem,
++ struct task_struct *tsk)
++{
++ int ret;
++ unsigned long flags;
++
++ spin_lock_irqsave(&semaphore_wake_lock, flags);
++ ret = 0;
++ if (atomic_read(&sem->waking) > 0) {
++ atomic_dec(&sem->waking);
++ ret = 1;
++ } else if (signal_pending(tsk)) {
++ atomic_inc(&sem->count);
++ ret = -EINTR;
++ }
++ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
++ return ret;
++}
++
++/*
++ * waking_non_zero_trylock:
++ * 1 failed to lock
++ * 0 got the lock
++ */
++static inline int waking_non_zero_trylock(struct semaphore *sem)
++{
++ int ret;
++ unsigned long flags;
++
++ spin_lock_irqsave(&semaphore_wake_lock, flags);
++ ret = 1;
++ if (atomic_read(&sem->waking) > 0) {
++ atomic_dec(&sem->waking);
++ ret = 0;
++ } else
++ atomic_inc(&sem->count);
++ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
++ return ret;
++}
++
++#endif /* _ASM_UBICOM32_SEMAPHORE_HELPER_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/sembuf.h
+@@ -0,0 +1,52 @@
++/*
++ * arch/ubicom32/include/asm/sembuf.h
++ * The semid64_ds structure 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SEMBUF_H
++#define _ASM_UBICOM32_SEMBUF_H
++
++/*
++ * The semid64_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 semid64_ds {
++ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
++ __kernel_time_t sem_otime; /* last semop time */
++ unsigned long __unused1;
++ __kernel_time_t sem_ctime; /* last change time */
++ unsigned long __unused2;
++ unsigned long sem_nsems; /* no. of semaphores in array */
++ unsigned long __unused3;
++ unsigned long __unused4;
++};
++
++#endif /* _ASM_UBICOM32_SEMBUF_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/setup.h
+@@ -0,0 +1,35 @@
++/*
++ * arch/ubicom32/include/asm/setup.h
++ * Kernel command line length definition.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_SETUP_H
++#define _ASM_UBICOM32_SETUP_H
++
++#define COMMAND_LINE_SIZE 512
++
++#endif /* _ASM_UBICOM32_SETUP_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/shmbuf.h
+@@ -0,0 +1,69 @@
++/*
++ * arch/ubicom32/include/asm/shmbuf.h
++ * The shmid64_ds structure 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SHMBUF_H
++#define _ASM_UBICOM32_SHMBUF_H
++
++/*
++ * The shmid64_ds 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:
++ * - 64-bit time_t to solve y2038 problem
++ * - 2 miscellaneous 32-bit values
++ */
++
++struct shmid64_ds {
++ struct ipc64_perm shm_perm; /* operation perms */
++ size_t shm_segsz; /* size of segment (bytes) */
++ __kernel_time_t shm_atime; /* last attach time */
++ unsigned long __unused1;
++ __kernel_time_t shm_dtime; /* last detach time */
++ unsigned long __unused2;
++ __kernel_time_t shm_ctime; /* last change time */
++ unsigned long __unused3;
++ __kernel_pid_t shm_cpid; /* pid of creator */
++ __kernel_pid_t shm_lpid; /* pid of last operator */
++ unsigned long shm_nattch; /* no. of current attaches */
++ unsigned long __unused4;
++ unsigned long __unused5;
++};
++
++struct shminfo64 {
++ unsigned long shmmax;
++ unsigned long shmmin;
++ unsigned long shmmni;
++ unsigned long shmseg;
++ unsigned long shmall;
++ unsigned long __unused1;
++ unsigned long __unused2;
++ unsigned long __unused3;
++ unsigned long __unused4;
++};
++
++#endif /* _ASM_UBICOM32_SHMBUF_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/shmparam.h
+@@ -0,0 +1,35 @@
++/*
++ * arch/ubicom32/include/asm/shmparam.h
++ * Shared memory definitions for Ubicom32 architecture.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ * Alpha, ix86, M68K, Sparc, ...et al
++ */
++#ifndef _ASM_UBICOM32_SHMPARAM_H
++#define _ASM_UBICOM32_SHMPARAM_H
++
++#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
++
++#endif /* _ASM_UBICOM32_SHMPARAM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/sigcontext.h
+@@ -0,0 +1,37 @@
++/*
++ * arch/ubicom32/include/asm/sigcontext.h
++ * Definition of sigcontext 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SIGCONTEXT_H
++#define _ASM_UBICOM32_SIGCONTEXT_H
++
++#include
++
++struct sigcontext {
++ struct pt_regs sc_regs;
++};
++
++#endif /* _ASM_UBICOM32_SIGCONTEXT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/siginfo.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/siginfo.h
++ * Generic siginfo.h 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SIGINFO_H
++#define _ASM_UBICOM32_SIGINFO_H
++
++#include
++
++#endif /* _ASM_UBICOM32_SIGINFO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/signal.h
+@@ -0,0 +1,180 @@
++/*
++ * arch/ubicom32/include/asm/signal.h
++ * Signal related 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SIGNAL_H
++#define _ASM_UBICOM32_SIGNAL_H
++
++#include
++
++/* Avoid too many header ordering problems. */
++struct siginfo;
++
++#ifdef __KERNEL__
++/* Most things should be clean enough to redefine this at will, if care
++ is taken to make libc match. */
++
++#define _NSIG 64
++#define _NSIG_BPW 32
++#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
++
++typedef unsigned long old_sigset_t; /* at least 32 bits */
++
++typedef struct {
++ unsigned long sig[_NSIG_WORDS];
++} sigset_t;
++
++#endif /* __KERNEL__ */
++
++#define SIGHUP 1
++#define SIGINT 2
++#define SIGQUIT 3
++#define SIGILL 4
++#define SIGTRAP 5
++#define SIGABRT 6
++#define SIGIOT 6
++#define SIGBUS 7
++#define SIGFPE 8
++#define SIGKILL 9
++#define SIGUSR1 10
++#define SIGSEGV 11
++#define SIGUSR2 12
++#define SIGPIPE 13
++#define SIGALRM 14
++#define SIGTERM 15
++#define SIGSTKFLT 16
++#define SIGCHLD 17
++#define SIGCONT 18
++#define SIGSTOP 19
++#define SIGTSTP 20
++#define SIGTTIN 21
++#define SIGTTOU 22
++#define SIGURG 23
++#define SIGXCPU 24
++#define SIGXFSZ 25
++#define SIGVTALRM 26
++#define SIGPROF 27
++#define SIGWINCH 28
++#define SIGIO 29
++#define SIGPOLL SIGIO
++/*
++#define SIGLOST 29
++*/
++#define SIGPWR 30
++#define SIGSYS 31
++#define SIGUNUSED 31
++
++/* These should not be considered constants from userland. */
++#define SIGRTMIN 32
++#define SIGRTMAX _NSIG
++
++/*
++ * SA_FLAGS values:
++ *
++ * SA_ONSTACK indicates that a registered stack_t will be used.
++ * SA_RESTART flag to get restarting signals (which were the default long ago)
++ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
++ * SA_RESETHAND clears the handler when the signal is delivered.
++ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
++ * SA_NODEFER prevents the current signal from being masked in the handler.
++ *
++ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
++ * Unix names RESETHAND and NODEFER respectively.
++ */
++#define SA_NOCLDSTOP 0x00000001
++#define SA_NOCLDWAIT 0x00000002
++#define SA_SIGINFO 0x00000004
++#define SA_ONSTACK 0x08000000
++#define SA_RESTART 0x10000000
++#define SA_NODEFER 0x40000000
++#define SA_RESETHAND 0x80000000
++
++#define SA_NOMASK SA_NODEFER
++#define SA_ONESHOT SA_RESETHAND
++
++/*
++ * sigaltstack controls
++ */
++#define SS_ONSTACK 1
++#define SS_DISABLE 2
++
++#define MINSIGSTKSZ 2048
++#define SIGSTKSZ 8192
++
++#include
++
++#ifdef __KERNEL__
++struct old_sigaction {
++ __sighandler_t sa_handler;
++ old_sigset_t sa_mask;
++ unsigned long sa_flags;
++ void (*sa_restorer)(void);
++};
++
++struct sigaction {
++ __sighandler_t sa_handler;
++ unsigned long sa_flags;
++ void (*sa_restorer)(void);
++ sigset_t sa_mask; /* mask last for extensibility */
++};
++
++struct k_sigaction {
++ struct sigaction sa;
++};
++#else
++/* Here we must cater to libcs that poke about in kernel headers. */
++
++struct sigaction {
++ union {
++ __sighandler_t _sa_handler;
++ void (*_sa_sigaction)(int, struct siginfo *, void *);
++ } _u;
++ sigset_t sa_mask;
++ unsigned long sa_flags;
++ void (*sa_restorer)(void);
++};
++
++#define sa_handler _u._sa_handler
++#define sa_sigaction _u._sa_sigaction
++
++#endif /* __KERNEL__ */
++
++typedef struct sigaltstack {
++ void *ss_sp;
++ int ss_flags;
++ size_t ss_size;
++} stack_t;
++
++#ifdef __KERNEL__
++
++#include
++#undef __HAVE_ARCH_SIG_BITOPS
++
++#define ptrace_signal_deliver(regs, cookie) do { } while (0)
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_UBICOM32_SIGNAL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/smp.h
+@@ -0,0 +1,83 @@
++/*
++ * arch/ubicom32/include/asm/smp.h
++ * SMP 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SMP_H
++#define _ASM_UBICOM32_SMP_H
++
++#ifndef ASSEMBLY
++#include
++#include
++#include
++#include
++
++typedef unsigned long address_t;
++extern cpumask_t cpu_online_map;
++extern unsigned int smp_ipi_irq;
++
++/*
++ * This magic constant controls our willingness to transfer
++ * a process across CPUs.
++ *
++ * Such a transfer incurs cache and tlb
++ * misses. The current value is inherited from i386. Still needs
++ * to be tuned for parisc.
++ */
++#define PROC_CHANGE_PENALTY 15 /* Schedule penalty */
++#define NO_PROC_ID 0xFF /* No processor magic marker */
++#define ANY_PROC_ID 0xFF /* Any processor magic marker */
++
++#ifdef CONFIG_SMP
++#define raw_smp_processor_id() (current_thread_info()->cpu)
++#endif /* CONFIG_SMP */
++
++static inline int __cpu_disable (void)
++{
++ return 0;
++}
++
++static inline void __cpu_die (unsigned int cpu)
++{
++ while(1) {
++ };
++}
++
++extern int __cpu_up(unsigned int cpu);
++extern void smp_send_timer_all(void);
++extern void smp_timer_broadcast(cpumask_t mask);
++extern void smp_set_affinity(unsigned int irq, cpumask_t dest);
++extern void arch_send_call_function_single_ipi(int cpu);
++extern void arch_send_call_function_ipi(cpumask_t mask);
++
++/*
++ * TODO: Once these are fully tested, we should turn them into
++ * inline macros for performance.
++ */
++extern unsigned long smp_get_affinity(unsigned int irq, int *all);
++extern void smp_reset_ipi(unsigned long mask);
++
++#endif /* !ASSEMBLY */
++#endif /* _ASM_UBICOM32_SMP_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/socket.h
+@@ -0,0 +1,84 @@
++/*
++ * arch/ubicom32/include/asm/socket.h
++ * Socket options 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SOCKET_H
++#define _ASM_UBICOM32_SOCKET_H
++
++#include
++
++/* For setsockopt(2) */
++#define SOL_SOCKET 1
++
++#define SO_DEBUG 1
++#define SO_REUSEADDR 2
++#define SO_TYPE 3
++#define SO_ERROR 4
++#define SO_DONTROUTE 5
++#define SO_BROADCAST 6
++#define SO_SNDBUF 7
++#define SO_RCVBUF 8
++#define SO_SNDBUFFORCE 32
++#define SO_RCVBUFFORCE 33
++#define SO_KEEPALIVE 9
++#define SO_OOBINLINE 10
++#define SO_NO_CHECK 11
++#define SO_PRIORITY 12
++#define SO_LINGER 13
++#define SO_BSDCOMPAT 14
++/* To add :#define SO_REUSEPORT 15 */
++#define SO_PASSCRED 16
++#define SO_PEERCRED 17
++#define SO_RCVLOWAT 18
++#define SO_SNDLOWAT 19
++#define SO_RCVTIMEO 20
++#define SO_SNDTIMEO 21
++
++/* Security levels - as per NRL IPv6 - don't actually do anything */
++#define SO_SECURITY_AUTHENTICATION 22
++#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
++#define SO_SECURITY_ENCRYPTION_NETWORK 24
++
++#define SO_BINDTODEVICE 25
++
++/* Socket filtering */
++#define SO_ATTACH_FILTER 26
++#define SO_DETACH_FILTER 27
++
++#define SO_PEERNAME 28
++#define SO_TIMESTAMP 29
++#define SCM_TIMESTAMP SO_TIMESTAMP
++
++#define SO_ACCEPTCONN 30
++
++#define SO_PEERSEC 31
++#define SO_PASSSEC 34
++#define SO_TIMESTAMPNS 35
++#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
++
++#define SO_MARK 36
++
++#endif /* _ASM_UBICOM32_SOCKET_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/sockios.h
+@@ -0,0 +1,40 @@
++/*
++ * arch/ubicom32/include/asm/sockios.h
++ * Socket-level ioctl 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SOCKIOS_H
++#define _ASM_UBICOM32_SOCKIOS_H
++
++/* Socket-level I/O control calls. */
++#define FIOSETOWN 0x8901
++#define SIOCSPGRP 0x8902
++#define FIOGETOWN 0x8903
++#define SIOCGPGRP 0x8904
++#define SIOCATMARK 0x8905
++#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
++
++#endif /* _ASM_UBICOM32_SOCKIOS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/spinlock.h
+@@ -0,0 +1,293 @@
++/*
++ * arch/ubicom32/include/asm/spinlock.h
++ * Spinlock related 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SPINLOCK_H
++#define _ASM_UBICOM32_SPINLOCK_H
++
++#include
++#include
++#include
++
++/*
++ * __raw_spin_lock()
++ * Lock the lock.
++ */
++static inline void __raw_spin_lock(raw_spinlock_t *x)
++{
++ asm volatile (
++ "1: bset %0, %0, #0 \n\t"
++ " jmpne.f 1b \n\t"
++ : "+U4" (x->lock)
++ :
++ : "memory", "cc"
++ );
++}
++
++/*
++ * __raw_spin_unlock()
++ * Unlock the lock.
++ */
++static inline void __raw_spin_unlock(raw_spinlock_t *x)
++{
++ asm volatile (
++ " bclr %0, %0, #0 \n\t"
++ : "+U4" (x->lock)
++ :
++ : "memory", "cc"
++ );
++}
++
++/*
++ * __raw_spin_is_locked()
++ * Test if the lock is locked.
++ */
++static inline int __raw_spin_is_locked(raw_spinlock_t *x)
++{
++ return x->lock;
++}
++
++/*
++ * __raw_spin_unlock_wait()
++ * Wait for the lock to be unlocked.
++ *
++ * Note: the caller has not guarantee that the lock will not
++ * be acquired before they get to it.
++ */
++static inline void __raw_spin_unlock_wait(raw_spinlock_t *x)
++{
++ do {
++ cpu_relax();
++ } while (__raw_spin_is_locked(x));
++}
++
++/*
++ * __raw_spin_trylock()
++ * Try the lock, return 0 on failure, 1 on success.
++ */
++static inline int __raw_spin_trylock(raw_spinlock_t *x)
++{
++ int ret = 0;
++
++ asm volatile (
++ " bset %1, %1, #0 \n\t"
++ " jmpne.f 1f \n\t"
++ " move.4 %0, #1 \n\t"
++ "1: \n\t"
++ : "+r" (ret), "+U4" (x->lock)
++ :
++ : "memory", "cc"
++ );
++
++ return ret;
++}
++
++/*
++ * __raw_spin_lock_flags()
++ * Spin waiting for the lock (enabling IRQ(s))
++ */
++static inline void __raw_spin_lock_flags(raw_spinlock_t *x, unsigned long flags)
++{
++ mb();
++ while (!__raw_spin_trylock(x)) {
++ /*
++ * If the flags from the IRQ are set, interrupts are disabled and we
++ * need to re-enable them.
++ */
++ if (!flags) {
++ cpu_relax();
++ } else {
++ raw_local_irq_enable();
++ cpu_relax();
++ raw_local_irq_disable();
++ }
++ }
++ mb();
++}
++
++/*
++ * Read-write spinlocks, allowing multiple readers but only one writer.
++ * Linux rwlocks are unfair to writers; they can be starved for an indefinite
++ * time by readers. With care, they can also be taken in interrupt context.
++ *
++ * In Ubicom32 architecture implementation, we have a spinlock and a counter.
++ * Readers use the lock to serialise their access to the counter (which
++ * records how many readers currently hold the lock).
++ * Writers hold the spinlock, preventing any readers or other writers from
++ * grabbing the rwlock.
++ */
++
++/*
++ * __raw_read_lock()
++ * Increment the counter in the rwlock.
++ *
++ * Note that we have to ensure interrupts are disabled in case we're
++ * interrupted by some other code that wants to grab the same read lock
++ */
++static inline void __raw_read_lock(raw_rwlock_t *rw)
++{
++ unsigned long flags;
++ raw_local_irq_save(flags);
++ __raw_spin_lock_flags(&rw->lock, flags);
++ rw->counter++;
++ __raw_spin_unlock(&rw->lock);
++ raw_local_irq_restore(flags);
++}
++
++/*
++ * __raw_read_unlock()
++ * Decrement the counter.
++ *
++ * Note that we have to ensure interrupts are disabled in case we're
++ * interrupted by some other code that wants to grab the same read lock
++ */
++static inline void __raw_read_unlock(raw_rwlock_t *rw)
++{
++ unsigned long flags;
++ raw_local_irq_save(flags);
++ __raw_spin_lock_flags(&rw->lock, flags);
++ rw->counter--;
++ __raw_spin_unlock(&rw->lock);
++ raw_local_irq_restore(flags);
++}
++
++/*
++ * __raw_read_trylock()
++ * Increment the counter if we can.
++ *
++ * Note that we have to ensure interrupts are disabled in case we're
++ * interrupted by some other code that wants to grab the same read lock
++ */
++static inline int __raw_read_trylock(raw_rwlock_t *rw)
++{
++ unsigned long flags;
++ retry:
++ raw_local_irq_save(flags);
++ if (__raw_spin_trylock(&rw->lock)) {
++ rw->counter++;
++ __raw_spin_unlock(&rw->lock);
++ raw_local_irq_restore(flags);
++ return 1;
++ }
++
++ raw_local_irq_restore(flags);
++
++ /*
++ * If write-locked, we fail to acquire the lock
++ */
++ if (rw->counter < 0) {
++ return 0;
++ }
++
++ /*
++ * Wait until we have a realistic chance at the lock
++ */
++ while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0) {
++ cpu_relax();
++ }
++
++ goto retry;
++}
++
++/*
++ * __raw_write_lock()
++ *
++ * Note that we have to ensure interrupts are disabled in case we're
++ * interrupted by some other code that wants to read_trylock() this lock
++ */
++static inline void __raw_write_lock(raw_rwlock_t *rw)
++{
++ unsigned long flags;
++retry:
++ raw_local_irq_save(flags);
++ __raw_spin_lock_flags(&rw->lock, flags);
++
++ if (rw->counter != 0) {
++ __raw_spin_unlock(&rw->lock);
++ raw_local_irq_restore(flags);
++
++ while (rw->counter != 0)
++ cpu_relax();
++
++ goto retry;
++ }
++
++ rw->counter = -1; /* mark as write-locked */
++ mb();
++ raw_local_irq_restore(flags);
++}
++
++static inline void __raw_write_unlock(raw_rwlock_t *rw)
++{
++ rw->counter = 0;
++ __raw_spin_unlock(&rw->lock);
++}
++
++/* Note that we have to ensure interrupts are disabled in case we're
++ * interrupted by some other code that wants to read_trylock() this lock */
++static inline int __raw_write_trylock(raw_rwlock_t *rw)
++{
++ unsigned long flags;
++ int result = 0;
++
++ raw_local_irq_save(flags);
++ if (__raw_spin_trylock(&rw->lock)) {
++ if (rw->counter == 0) {
++ rw->counter = -1;
++ result = 1;
++ } else {
++ /* Read-locked. Oh well. */
++ __raw_spin_unlock(&rw->lock);
++ }
++ }
++ raw_local_irq_restore(flags);
++
++ return result;
++}
++
++/*
++ * read_can_lock - would read_trylock() succeed?
++ * @lock: the rwlock in question.
++ */
++static inline int __raw_read_can_lock(raw_rwlock_t *rw)
++{
++ return rw->counter >= 0;
++}
++
++/*
++ * write_can_lock - would write_trylock() succeed?
++ * @lock: the rwlock in question.
++ */
++static inline int __raw_write_can_lock(raw_rwlock_t *rw)
++{
++ return !rw->counter;
++}
++
++#define _raw_spin_relax(lock) cpu_relax()
++#define _raw_read_relax(lock) cpu_relax()
++#define _raw_write_relax(lock) cpu_relax()
++
++#endif /* _ASM_UBICOM32_SPINLOCK_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/spinlock_types.h
+@@ -0,0 +1,43 @@
++/*
++ * arch/ubicom32/include/asm/spinlock_types.h
++ * Spinlock related structure 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SPINLOCK_TYPES_H
++#define _ASM_UBICOM32_SPINLOCK_TYPES_H
++
++typedef struct {
++ volatile unsigned int lock;
++} raw_spinlock_t;
++
++typedef struct {
++ raw_spinlock_t lock;
++ volatile int counter;
++} raw_rwlock_t;
++
++#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
++#define __RAW_RW_LOCK_UNLOCKED { __RAW_SPIN_LOCK_UNLOCKED, 0 }
++
++#endif /* _ASM_UBICOM32_SPINLOCK_TYPES_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/stacktrace.h
+@@ -0,0 +1,72 @@
++/*
++ * arch/ubicom32/include/asm/stacktrace.h
++ * Stacktrace functions 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_STACKTRACE_H
++#define _ASM_UBICOM32_STACKTRACE_H
++
++#define between(a, b, c) (( \
++ ((unsigned long) a) >= ((unsigned long) b)) && \
++ (((unsigned long)a) <= ((unsigned long)c)))
++
++/*
++ * These symbols are filled in by the linker.
++ */
++extern unsigned long _stext;
++extern unsigned long _etext;
++
++/* OCM text goes from __ocm_text_run_begin to __data_begin */
++extern unsigned long __ocm_text_run_begin;
++extern unsigned long __data_begin;
++
++/* Account for OCM case - see stacktrace.c maybe combine(also trap.c) */
++/*
++ * ubicom32_is_kernel()
++ *
++ * Check to see if the given address belongs to the kernel.
++ * NOMMU does not permit any other means.
++ */
++static inline int ubicom32_is_kernel(unsigned long addr)
++{
++ int is_kernel = between(addr, &_stext, &_etext) || \
++ between(addr, &__ocm_text_run_begin, &__data_begin);
++
++#ifdef CONFIG_MODULES
++ if (!is_kernel)
++ is_kernel = is_module_address(addr);
++#endif
++ return is_kernel;
++}
++
++extern unsigned long stacktrace_iterate(
++ unsigned long **trace,
++ unsigned long stext, unsigned long etext,
++ unsigned long ocm_stext, unsigned long ocm_etext,
++ unsigned long sstack, unsigned long estack);
++#ifdef CONFIG_STACKTRACE
++void stacktrace_save_entries(struct task_struct *tsk, struct stack_trace *trace, unsigned long sp);
++#endif
++#endif /* _ASM_UBICOM32_STACKTRACE_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/statfs.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/statfs.h
++ * Generic statfs.h 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_STATFS_H
++#define _ASM_UBICOM32_STATFS_H
++
++#include
++
++#endif /* _ASM_UBICOM32_STATFS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/stat.h
+@@ -0,0 +1,104 @@
++/*
++ * arch/ubicom32/include/asm/stat.h
++ * File status 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_STAT_H
++#define _ASM_UBICOM32_STAT_H
++
++struct __old_kernel_stat {
++ unsigned short st_dev;
++ unsigned short st_ino;
++ unsigned short st_mode;
++ unsigned short st_nlink;
++ unsigned short st_uid;
++ unsigned short st_gid;
++ unsigned short st_rdev;
++ unsigned long st_size;
++ unsigned long st_atime;
++ unsigned long st_mtime;
++ unsigned long st_ctime;
++};
++
++struct stat {
++ unsigned short st_dev;
++ unsigned short __pad1;
++ unsigned long st_ino;
++ unsigned short st_mode;
++ unsigned short st_nlink;
++ unsigned short st_uid;
++ unsigned short st_gid;
++ unsigned short st_rdev;
++ unsigned short __pad2;
++ unsigned long st_size;
++ unsigned long st_blksize;
++ unsigned long st_blocks;
++ unsigned long st_atime;
++ unsigned long __unused1;
++ unsigned long st_mtime;
++ unsigned long __unused2;
++ unsigned long st_ctime;
++ unsigned long __unused3;
++ unsigned long __unused4;
++ unsigned long __unused5;
++};
++
++/* This matches struct stat64 in glibc2.1, hence the absolutely
++ * insane amounts of padding around dev_t's.
++ */
++struct stat64 {
++ unsigned long long st_dev;
++ unsigned char __pad1[2];
++
++#define STAT64_HAS_BROKEN_ST_INO 1
++ unsigned long __st_ino;
++
++ unsigned int st_mode;
++ unsigned int st_nlink;
++
++ unsigned long st_uid;
++ unsigned long st_gid;
++
++ unsigned long long st_rdev;
++ unsigned char __pad3[2];
++
++ long long st_size;
++ unsigned long st_blksize;
++
++ unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
++
++ unsigned long st_atime;
++ unsigned long st_atime_nsec;
++
++ unsigned long st_mtime;
++ unsigned long st_mtime_nsec;
++
++ unsigned long st_ctime;
++ unsigned long st_ctime_nsec;
++
++ unsigned long long st_ino;
++};
++
++#endif /* _ASM_UBICOM32_STAT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/string.h
+@@ -0,0 +1,37 @@
++/*
++ * arch/ubicom32/include/asm/string.h
++ * String operation 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_STRING_H
++#define _ASM_UBICOM32_STRING_H
++
++#define __HAVE_ARCH_MEMSET
++extern void *memset(void *b, int c, size_t len);
++
++#define __HAVE_ARCH_MEMCPY
++extern void *memcpy(void *to, const void *from, size_t len);
++
++#endif /* _ASM_UBICOM32_STRING_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/switch-bcm539x.h
+@@ -0,0 +1,57 @@
++/*
++ * arch/ubicom32/include/asm/switch-bcm539x.h
++ * Broadcom bcm539x platform data 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SWITCH_BCM539X_H
++#define _ASM_UBICOM32_SWITCH_BCM539X_H
++
++#define SWITCH_BCM539X_FLAG_HW_RESET 0x01
++#define SWITCH_BCM539X_FLAG_SW_RESET 0x02
++
++struct switch_bcm539x_platform_data {
++ /*
++ * See flags above
++ */
++ u32_t flags;
++
++ /*
++ * GPIO to use for nReset
++ */
++ int pin_reset;
++
++
++ /*
++ * GPIO to use for chip select
++ */
++ int pin_cs;
++
++ /*
++ * Name of this switch
++ */
++ const char *name;
++};
++
++#endif /* _ASM_UBICOM32_SWITCH_BCM539X_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/system.h
+@@ -0,0 +1,101 @@
++/*
++ * arch/ubicom32/include/asm/system.h
++ * Low level switching 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_SYSTEM_H
++#define _ASM_UBICOM32_SYSTEM_H
++
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++
++/*
++ * switch_to(n) should switch tasks to task ptr, first checking that
++ * ptr isn't the current task, in which case it does nothing.
++ */
++asmlinkage void resume(void);
++extern void *__switch_to(struct task_struct *prev,
++ struct thread_struct *prev_switch,
++ struct thread_struct *next_switch);
++
++/*
++ * We will need a per linux thread sw_ksp for the switch_to macro to
++ * track the kernel stack pointer for the current thread on that linux thread.
++ */
++#define switch_to(prev,next,last) \
++({ \
++ void *_last; \
++ _last = (void *) \
++ __switch_to(prev, &prev->thread, &next->thread); \
++ (last) = _last; \
++})
++
++/*
++ * Force strict CPU ordering.
++ * Not really required on ubicom32...
++ */
++#define nop() asm volatile ("nop"::)
++#define mb() asm volatile ("" : : :"memory")
++#define rmb() asm volatile ("" : : :"memory")
++#define wmb() asm volatile ("" : : :"memory")
++#define set_mb(var, value) ({ (var) = (value); wmb(); })
++
++#ifdef CONFIG_SMP
++#define smp_mb() mb()
++#define smp_rmb() rmb()
++#define smp_wmb() wmb()
++#define smp_read_barrier_depends() read_barrier_depends()
++#else
++#define smp_mb() mb()
++#define smp_rmb() rmb()
++#define smp_wmb() wmb()
++#define smp_read_barrier_depends() do { } while(0)
++#endif
++
++#define read_barrier_depends() ((void)0)
++
++/*
++ * The following defines change how the scheduler calls the switch_to()
++ * macro.
++ *
++ * 1) The first causes the runqueue to be unlocked on entry to
++ * switch_to(). Since our ctx code does not play with the runqueue
++ * we do not need it unlocked.
++ *
++ * 2) The later turns interrupts on during a ctxsw to reduce the latency of
++ * interrupts during ctx. At this point in the port, we believe that this
++ * latency is not a problem since we have very little code to perform a ctxsw.
++ */
++// #define __ARCH_WANT_UNLOCKED_CTXSW
++// #define __ARCH_WANT_INTERRUPTS_ON_CTXSW
++
++#endif /* _ASM_UBICOM32_SYSTEM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/termbits.h
+@@ -0,0 +1,227 @@
++/*
++ * arch/ubicom32/include/asm/termbits.h
++ * Terminal/serial port 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TERMBITS_H
++#define _ASM_UBICOM32_TERMBITS_H
++
++#include
++
++typedef unsigned char cc_t;
++typedef unsigned int speed_t;
++typedef unsigned int tcflag_t;
++
++#define NCCS 19
++struct termios {
++ tcflag_t c_iflag; /* input mode flags */
++ tcflag_t c_oflag; /* output mode flags */
++ tcflag_t c_cflag; /* control mode flags */
++ tcflag_t c_lflag; /* local mode flags */
++ cc_t c_line; /* line discipline */
++ cc_t c_cc[NCCS]; /* control characters */
++};
++
++struct termios2 {
++ tcflag_t c_iflag; /* input mode flags */
++ tcflag_t c_oflag; /* output mode flags */
++ tcflag_t c_cflag; /* control mode flags */
++ tcflag_t c_lflag; /* local mode flags */
++ cc_t c_line; /* line discipline */
++ cc_t c_cc[NCCS]; /* control characters */
++ speed_t c_ispeed; /* input speed */
++ speed_t c_ospeed; /* output speed */
++};
++
++struct ktermios {
++ tcflag_t c_iflag; /* input mode flags */
++ tcflag_t c_oflag; /* output mode flags */
++ tcflag_t c_cflag; /* control mode flags */
++ tcflag_t c_lflag; /* local mode flags */
++ cc_t c_line; /* line discipline */
++ cc_t c_cc[NCCS]; /* control characters */
++ speed_t c_ispeed; /* input speed */
++ speed_t c_ospeed; /* output speed */
++};
++
++/* c_cc characters */
++#define VINTR 0
++#define VQUIT 1
++#define VERASE 2
++#define VKILL 3
++#define VEOF 4
++#define VTIME 5
++#define VMIN 6
++#define VSWTC 7
++#define VSTART 8
++#define VSTOP 9
++#define VSUSP 10
++#define VEOL 11
++#define VREPRINT 12
++#define VDISCARD 13
++#define VWERASE 14
++#define VLNEXT 15
++#define VEOL2 16
++
++
++/* c_iflag bits */
++#define IGNBRK 0000001
++#define BRKINT 0000002
++#define IGNPAR 0000004
++#define PARMRK 0000010
++#define INPCK 0000020
++#define ISTRIP 0000040
++#define INLCR 0000100
++#define IGNCR 0000200
++#define ICRNL 0000400
++#define IUCLC 0001000
++#define IXON 0002000
++#define IXANY 0004000
++#define IXOFF 0010000
++#define IMAXBEL 0020000
++#define IUTF8 0040000
++
++/* c_oflag bits */
++#define OPOST 0000001
++#define OLCUC 0000002
++#define ONLCR 0000004
++#define OCRNL 0000010
++#define ONOCR 0000020
++#define ONLRET 0000040
++#define OFILL 0000100
++#define OFDEL 0000200
++#define NLDLY 0000400
++#define NL0 0000000
++#define NL1 0000400
++#define CRDLY 0003000
++#define CR0 0000000
++#define CR1 0001000
++#define CR2 0002000
++#define CR3 0003000
++#define TABDLY 0014000
++#define TAB0 0000000
++#define TAB1 0004000
++#define TAB2 0010000
++#define TAB3 0014000
++#define XTABS 0014000
++#define BSDLY 0020000
++#define BS0 0000000
++#define BS1 0020000
++#define VTDLY 0040000
++#define VT0 0000000
++#define VT1 0040000
++#define FFDLY 0100000
++#define FF0 0000000
++#define FF1 0100000
++
++/* c_cflag bit meaning */
++#define CBAUD 0010017
++#define B0 0000000 /* hang up */
++#define B50 0000001
++#define B75 0000002
++#define B110 0000003
++#define B134 0000004
++#define B150 0000005
++#define B200 0000006
++#define B300 0000007
++#define B600 0000010
++#define B1200 0000011
++#define B1800 0000012
++#define B2400 0000013
++#define B4800 0000014
++#define B9600 0000015
++#define B19200 0000016
++#define B38400 0000017
++#define EXTA B19200
++#define EXTB B38400
++#define CSIZE 0000060
++#define CS5 0000000
++#define CS6 0000020
++#define CS7 0000040
++#define CS8 0000060
++#define CSTOPB 0000100
++#define CREAD 0000200
++#define PARENB 0000400
++#define PARODD 0001000
++#define HUPCL 0002000
++#define CLOCAL 0004000
++#define CBAUDEX 0010000
++#define BOTHER 0010000
++#define B57600 0010001
++#define B115200 0010002
++#define B230400 0010003
++#define B460800 0010004
++#define B500000 0010005
++#define B576000 0010006
++#define B921600 0010007
++#define B1000000 0010010
++#define B1152000 0010011
++#define B1500000 0010012
++#define B2000000 0010013
++#define B2500000 0010014
++#define B3000000 0010015
++#define B3500000 0010016
++#define B4000000 0010017
++#define CIBAUD 002003600000 /* input baud rate */
++#define CMSPAR 010000000000 /* mark or space (stick) parity */
++#define CRTSCTS 020000000000 /* flow control */
++
++#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
++
++/* c_lflag bits */
++#define ISIG 0000001
++#define ICANON 0000002
++#define XCASE 0000004
++#define ECHO 0000010
++#define ECHOE 0000020
++#define ECHOK 0000040
++#define ECHONL 0000100
++#define NOFLSH 0000200
++#define TOSTOP 0000400
++#define ECHOCTL 0001000
++#define ECHOPRT 0002000
++#define ECHOKE 0004000
++#define FLUSHO 0010000
++#define PENDIN 0040000
++#define IEXTEN 0100000
++
++
++/* tcflow() and TCXONC use these */
++#define TCOOFF 0
++#define TCOON 1
++#define TCIOFF 2
++#define TCION 3
++
++/* tcflush() and TCFLSH use these */
++#define TCIFLUSH 0
++#define TCOFLUSH 1
++#define TCIOFLUSH 2
++
++/* tcsetattr uses these */
++#define TCSANOW 0
++#define TCSADRAIN 1
++#define TCSAFLUSH 2
++
++#endif /* _ASM_UBICOM32_TERMBITS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/termios.h
+@@ -0,0 +1,119 @@
++/*
++ * arch/ubicom32/include/asm/termios.h
++ * Ubicom32 termio 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TERMIOS_H
++#define _ASM_UBICOM32_TERMIOS_H
++
++#include
++#include
++
++struct winsize {
++ unsigned short ws_row;
++ unsigned short ws_col;
++ unsigned short ws_xpixel;
++ unsigned short ws_ypixel;
++};
++
++#define NCC 8
++struct termio {
++ unsigned short c_iflag; /* input mode flags */
++ unsigned short c_oflag; /* output mode flags */
++ unsigned short c_cflag; /* control mode flags */
++ unsigned short c_lflag; /* local mode flags */
++ unsigned char c_line; /* line discipline */
++ unsigned char c_cc[NCC]; /* control characters */
++};
++
++#ifdef __KERNEL__
++/* intr=^C quit=^| erase=del kill=^U
++ eof=^D vtime=\0 vmin=\1 sxtc=\0
++ start=^Q stop=^S susp=^Z eol=\0
++ reprint=^R discard=^U werase=^W lnext=^V
++ eol2=\0
++*/
++#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
++#endif
++
++/* modem lines */
++#define TIOCM_LE 0x001
++#define TIOCM_DTR 0x002
++#define TIOCM_RTS 0x004
++#define TIOCM_ST 0x008
++#define TIOCM_SR 0x010
++#define TIOCM_CTS 0x020
++#define TIOCM_CAR 0x040
++#define TIOCM_RNG 0x080
++#define TIOCM_DSR 0x100
++#define TIOCM_CD TIOCM_CAR
++#define TIOCM_RI TIOCM_RNG
++#define TIOCM_OUT1 0x2000
++#define TIOCM_OUT2 0x4000
++#define TIOCM_LOOP 0x8000
++
++/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
++
++#ifdef __KERNEL__
++
++/*
++ * Translate a "termio" structure into a "termios". Ugh.
++ */
++#define user_termio_to_kernel_termios(termios, termio) \
++({ \
++ unsigned short tmp; \
++ get_user(tmp, &(termio)->c_iflag); \
++ (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
++ get_user(tmp, &(termio)->c_oflag); \
++ (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
++ get_user(tmp, &(termio)->c_cflag); \
++ (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
++ get_user(tmp, &(termio)->c_lflag); \
++ (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
++ get_user((termios)->c_line, &(termio)->c_line); \
++ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
++})
++
++/*
++ * Translate a "termios" structure into a "termio". Ugh.
++ */
++#define kernel_termios_to_user_termio(termio, termios) \
++({ \
++ put_user((termios)->c_iflag, &(termio)->c_iflag); \
++ put_user((termios)->c_oflag, &(termio)->c_oflag); \
++ put_user((termios)->c_cflag, &(termio)->c_cflag); \
++ put_user((termios)->c_lflag, &(termio)->c_lflag); \
++ put_user((termios)->c_line, &(termio)->c_line); \
++ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
++})
++
++#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
++#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
++#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
++#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_UBICOM32_TERMIOS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/thread-asm.h
+@@ -0,0 +1,49 @@
++/*
++ * arch/ubicom32/include/asm/thread-asm.h
++ * Ubicom32 architecture specific thread 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_THREAD_ASM_H
++#define _ASM_UBICOM32_THREAD_ASM_H
++
++/*
++ * thread_get_self
++ * Read and shift the current thread into reg
++ */
++.macro thread_get_self reg
++ lsr.4 \reg, ROSR, #2
++ and.4 \reg, #31, \reg /* Mask to get thread number into register */
++.endm
++
++/*
++ * thread_get_self_mask
++ * Read and shift the current thread mask into reg
++ */
++.macro thread_get_self_mask reg
++ lsr.4 \reg, ROSR, #2
++ lsl.4 \reg, #1, \reg /* Thread bit */
++.endm
++
++#endif /* _ASM_UBICOM32_THREAD_ASM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/thread.h
+@@ -0,0 +1,313 @@
++/*
++ * arch/ubicom32/include/asm/thread.h
++ * Ubicom32 architecture specific thread 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_THREAD_H
++#define _ASM_UBICOM32_THREAD_H
++
++#if !defined(__ASSEMBLY__)
++
++#include
++#include
++
++typedef int thread_t;
++typedef unsigned char thread_type_t;
++typedef void (*thread_exec_fn_t)(void *arg);
++
++#define THREAD_NULL 0x40
++#define THREAD_TYPE_HRT (1 << 0)
++#define THREAD_TYPE_SPECIAL 0
++#define THREAD_TYPE_NORMAL 0
++#define THREAD_TYPE_BACKGROUND (1 << 1)
++
++/*
++ * This is the upper bound on the maximum hardware threads that one will find
++ * on a Ubicom processor. It is used to size per hardware thread data structures.
++ */
++#define THREAD_ARCHITECTURAL_MAX 16
++
++/*
++ * TODO: Rename this at some point to be thread_
++ */
++extern unsigned int sw_ksp[THREAD_ARCHITECTURAL_MAX];
++
++
++/*
++ * thread_get_self()
++ */
++static inline thread_t thread_get_self(void)
++{
++ thread_t result;
++ asm (
++ "lsr.4 %0, ROSR, #2 \n\t"
++ : "=d" (result)
++ :
++ : "cc"
++ );
++ return result & 31;
++}
++
++/*
++ * thread_suspend()
++ */
++static inline void thread_suspend(void)
++{
++ asm volatile (
++ "suspend\n\t"
++ :
++ :
++ );
++}
++
++/*
++ * thread_resume()
++ */
++static inline void thread_resume(thread_t thread)
++{
++ asm volatile (
++ "move.4 MT_ACTIVE_SET, %0 \n\t"
++ "pipe_flush 0 \n\t"
++ "pipe_flush 0 \n\t"
++ :
++ : "d" (1 << thread)
++ );
++}
++
++
++
++/*
++ * thread_enable_mask()
++ * Enable all threads in the mask.
++ *
++ * All writes to MT_EN must be protected by the MT_EN_LOCK bit
++ */
++static inline void thread_enable_mask(unsigned int mask)
++{
++ /*
++ * must flush the pipeline twice.
++ * first pipe_flush is to ensure write to MT_EN is completed
++ * second one is to ensure any new instructions from
++ * the targeted thread (the one being disabled), that
++ * are issued while the write to MT_EN is being executed,
++ * are completed.
++ */
++ UBICOM32_LOCK(MT_EN_LOCK_BIT);
++ asm volatile (
++ "or.4 MT_EN, MT_EN, %0 \n\t"
++ "pipe_flush 0 \n\t"
++ "pipe_flush 0 \n\t"
++ :
++ : "d" (mask)
++ : "cc"
++ );
++ UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
++}
++
++/*
++ * thread_enable()
++ */
++static inline void thread_enable(thread_t thread)
++{
++ thread_enable_mask(1 << thread);
++}
++
++/*
++ * thread_disable_mask()
++ * Disable all threads in the mask.
++ *
++ * All writes to MT_EN must be protected by the MT_EN_LOCK bit
++ */
++static inline void thread_disable_mask(unsigned int mask)
++{
++ /*
++ * must flush the pipeline twice.
++ * first pipe_flush is to ensure write to MT_EN is completed
++ * second one is to ensure any new instructions from
++ * the targeted thread (the one being disabled), that
++ * are issued while the write to MT_EN is being executed,
++ * are completed.
++ */
++ UBICOM32_LOCK(MT_EN_LOCK_BIT);
++ asm volatile (
++ "and.4 MT_EN, MT_EN, %0 \n\t"
++ "pipe_flush 0 \n\t"
++ "pipe_flush 0 \n\t"
++ :
++ : "d" (~mask)
++ : "cc"
++ );
++ UBICOM32_UNLOCK(MT_EN_LOCK_BIT);
++}
++
++/*
++ * thread_disable()
++ */
++static inline void thread_disable(thread_t thread)
++{
++ thread_disable_mask(1 << thread);
++}
++
++/*
++ * thread_disable_others()
++ * Disable all other threads
++ */
++static inline void thread_disable_others(void)
++{
++ thread_t self = thread_get_self();
++ thread_disable_mask(~(1 << self));
++}
++
++/*
++ * thread_is_trapped()
++ * Is the specified tid trapped?
++ */
++static inline int thread_is_trapped(thread_t tid)
++{
++ int thread_mask = (1 << tid);
++ int trap_thread;
++
++ asm (
++ "move.4 %0, MT_TRAP \n\t"
++ : "=d" (trap_thread)
++ :
++ );
++ return (trap_thread & thread_mask);
++}
++
++/*
++ * thread_is_enabled()
++ * Is the specified tid enabled?
++ */
++static inline int thread_is_enabled(thread_t tid)
++{
++ int thread_mask = (1 << tid);
++ int enabled_threads;
++
++ asm (
++ "move.4 %0, MT_EN \n\t"
++ : "=d" (enabled_threads)
++ :
++ );
++ return (enabled_threads & thread_mask);
++}
++
++/*
++ * thread_get_instruction_count()
++ */
++static inline unsigned int thread_get_instruction_count(void)
++{
++ unsigned int result;
++ asm (
++ "move.4 %0, INST_CNT \n\t"
++ : "=r" (result)
++ );
++ return result;
++}
++
++/*
++ * thread_get_pc()
++ * pc could point to a speculative and cancelled instruction unless thread is disabled
++ */
++static inline void *thread_get_pc(thread_t thread)
++{
++ void *result;
++ asm (
++ "move.4 csr, %1 \n\t"
++ "setcsr_flush 0 \n\t"
++ "move.4 %0, pc \n\t"
++ "move.4 csr, #0 \n\t"
++ "setcsr_flush 0 \n\t"
++ : "=r" (result)
++ : "r" ((thread << 9) | (1 << 8))
++ );
++ return result;
++}
++
++/*
++ * thread_get_trap_cause()
++ * This should be called only when the thread is not running
++ */
++static inline unsigned int thread_get_trap_cause(thread_t thread)
++{
++ unsigned int result;
++ asm (
++ "move.4 csr, %1 \n\t"
++ "setcsr_flush 0 \n\t"
++ "move.4 %0, trap_cause \n\t"
++ "move.4 csr, #0 \n\t"
++ "setcsr_flush 0 \n\t"
++ : "=r" (result)
++ : "r" ((thread << 9) | (1 << 8))
++ );
++ return result;
++}
++
++/*
++ * THREAD_STALL macro.
++ */
++#define THREAD_STALL \
++ asm volatile ( \
++ "move.4 mt_dbg_active_clr, #-1 \n\t" \
++ "pipe_flush 0 \n\t" \
++ : \
++ : \
++ )
++
++extern unsigned int thread_get_mainline(void);
++extern void thread_set_mainline(thread_t tid);
++extern thread_t thread_alloc(void);
++extern thread_t thread_start(thread_t thread, thread_exec_fn_t exec, void *arg, unsigned int *sp_high, thread_type_t type);
++
++/*
++ * asm macros
++ */
++asm (
++/*
++ * thread_get_self
++ * Read and shift the current thread into reg
++ */
++".macro thread_get_self reg \n\t"
++" lsr.4 \\reg, ROSR, #2 \n\t"
++" and.4 \\reg, #31, \\reg \n\t"/* Mask to get thread number into
++ * register */
++".endm \n\t"
++
++/*
++ * thread_get_self_mask
++ * Read and shift the current thread mask into reg
++ */
++".macro thread_get_self_mask reg \n\t"
++" lsr.4 \\reg, ROSR, #2 \n\t"
++" lsl.4 \\reg, #1, \\reg \n\t" /* Thread bit */
++".endm \n\t"
++ );
++
++#else /* __ASSEMBLY__ */
++
++#include
++
++#endif /* __ASSEMBLY__ */
++#endif /* _ASM_UBICOM32_THREAD_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/thread_info.h
+@@ -0,0 +1,134 @@
++/*
++ * arch/ubicom32/include/asm/thread_info.h
++ * Ubicom32 architecture low-level thread information.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Adapted from the i386 and PPC versions by Greg Ungerer (gerg@snapgear.com)
++ * Copyright (C) 2002 David Howells (dhowells@redhat.com)
++ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_THREAD_INFO_H
++#define _ASM_UBICOM32_THREAD_INFO_H
++
++#include
++
++/*
++ * Size of kernel stack for each process. This must be a power of 2...
++ */
++#ifdef CONFIG_4KSTACKS
++#define THREAD_SIZE_ORDER (0)
++#else
++#define THREAD_SIZE_ORDER (1)
++#endif
++
++/*
++ * for asm files, THREAD_SIZE is now generated by asm-offsets.c
++ */
++#define THREAD_SIZE (PAGE_SIZE< preemptable, <0 => BUG */
++ int interrupt_nesting; /* Interrupt nesting level. */
++ struct restart_block restart_block;
++};
++
++/*
++ * macros/functions for gaining access to the thread information structure
++ */
++#define INIT_THREAD_INFO(tsk) \
++{ \
++ .task = &tsk, \
++ .exec_domain = &default_exec_domain, \
++ .flags = 0, \
++ .cpu = 0, \
++ .interrupt_nesting = 0, \
++ .restart_block = { \
++ .fn = do_no_restart_syscall, \
++ }, \
++}
++
++#define init_thread_info (init_thread_union.thread_info)
++#define init_stack (init_thread_union.stack)
++
++
++/* how to get the thread information struct from C */
++static inline struct thread_info *current_thread_info(void)
++{
++ struct thread_info *ti;
++
++ asm (
++ "and.4 %0, sp, %1\n\t"
++ : "=&r" (ti)
++ : "d" (~(THREAD_SIZE-1))
++ : "cc"
++ );
++
++ return ti;
++}
++
++#define STACK_WARN (THREAD_SIZE / 8)
++
++#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR 1
++
++/* thread information allocation */
++#define alloc_thread_info(tsk) ((struct thread_info *) \
++ __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER))
++#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_SIZE_ORDER)
++#endif /* __ASSEMBLY__ */
++
++#define PREEMPT_ACTIVE 0x4000000
++
++/*
++ * thread information flag bit numbers
++ */
++#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
++#define TIF_SIGPENDING 1 /* signal pending */
++#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
++#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
++ TIF_NEED_RESCHED */
++#define TIF_MEMDIE 4
++
++/* as above, but as bit values */
++#define _TIF_SYSCALL_TRACE (1<.
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TIMEX_H
++#define _ASM_UBICOM32_TIMEX_H
++
++#define CLOCK_TICK_RATE 266000000
++
++// #define ARCH_HAS_READ_CURRENT_TIMER
++
++typedef unsigned long cycles_t;
++
++static inline cycles_t get_cycles(void)
++{
++ return 0;
++}
++
++extern int timer_alloc(void);
++extern void timer_set(int timervector, unsigned int cycles);
++extern int timer_reset(int timervector, unsigned int cycles);
++extern void timer_tick_init(void);
++extern void timer_device_init(void);
++
++#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
++extern void local_timer_interrupt(void);
++#endif
++
++#if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
++extern int local_timer_setup(unsigned int cpu);
++#endif
++
++#endif /* _ASM_UBICOM32_TIMEX_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/tlbflush.h
+@@ -0,0 +1,79 @@
++/*
++ * arch/ubicom32/include/asm/tlbflush.h
++ * TLB operations for Ubicom32 architecture.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * Copyright (C) 2000 Lineo, David McCullough
++ * Copyright (C) 2000-2002, Greg Ungerer
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TLB_FLUSH_H
++#define _ASM_UBICOM32_TLB_FLUSH_H
++
++#include
++
++/*
++ * flush all user-space atc entries.
++ */
++static inline void __flush_tlb(void)
++{
++ BUG();
++}
++
++static inline void __flush_tlb_one(unsigned long addr)
++{
++ BUG();
++}
++
++#define flush_tlb() __flush_tlb()
++
++/*
++ * flush all atc entries (both kernel and user-space entries).
++ */
++static inline void flush_tlb_all(void)
++{
++ BUG();
++}
++
++static inline void flush_tlb_mm(struct mm_struct *mm)
++{
++ BUG();
++}
++
++static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
++{
++ BUG();
++}
++
++static inline void flush_tlb_range(struct mm_struct *mm,
++ unsigned long start, unsigned long end)
++{
++ BUG();
++}
++
++static inline void flush_tlb_kernel_page(unsigned long addr)
++{
++ BUG();
++}
++
++#endif /* _ASM_UBICOM32_TLB_FLUSH_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/tlb.h
+@@ -0,0 +1,47 @@
++/*
++ * arch/ubicom32/include/asm/tlb.h
++ * Ubicom32 architecture TLB operations.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TLB_H
++#define _ASM_UBICOM32_TLB_H
++
++/*
++ * ubicom32 doesn't need any special per-pte or
++ * per-vma handling..
++ */
++#define tlb_start_vma(tlb, vma) do { } while (0)
++#define tlb_end_vma(tlb, vma) do { } while (0)
++#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
++
++/*
++ * .. because we flush the whole mm when it
++ * fills up.
++ */
++#define tlb_flush(tlb)
++
++#include
++
++#endif /* _ASM_UBICOM32_TLB_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/topology.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/topology.h
++ * Generic topology.h 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TOPOLOGY_H
++#define _ASM_UBICOM32_TOPOLOGY_H
++
++#include
++
++#endif /* _ASM_UBICOM32_TOPOLOGY_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/traps.h
+@@ -0,0 +1,55 @@
++/*
++ * arch/ubicom32/include/asm/traps.h
++ * Trap related 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_TRAPS_H
++#define _ASM_UBICOM32_TRAPS_H
++
++/*
++ * Trap causes passed from ultra to Host OS
++ */
++#define TRAP_CAUSE_TOTAL 13
++#define TRAP_CAUSE_DST_RANGE_ERR 12
++#define TRAP_CAUSE_SRC1_RANGE_ERR 11
++#define TRAP_CAUSE_I_RANGE_ERR 10
++#define TRAP_CAUSE_DCAPT 9
++#define TRAP_CAUSE_DST_SERROR 8
++#define TRAP_CAUSE_SRC1_SERROR 7
++#define TRAP_CAUSE_DST_MISALIGNED 6
++#define TRAP_CAUSE_SRC1_MISALIGNED 5
++#define TRAP_CAUSE_DST_DECODE_ERR 4
++#define TRAP_CAUSE_SRC1_DECODE_ERR 3
++#define TRAP_CAUSE_ILLEGAL_INST 2
++#define TRAP_CAUSE_I_SERROR 1
++#define TRAP_CAUSE_I_DECODE_ERR 0
++
++extern void trap_handler(int irq, struct pt_regs *regs);
++extern void trap_init_interrupt(void);
++extern void unaligned_emulate(unsigned int thread);
++extern int unaligned_only(unsigned int cause);
++
++#endif /* _ASM_UBICOM32_TRAPS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/types.h
+@@ -0,0 +1,75 @@
++/*
++ * arch/ubicom32/include/asm/types.h
++ * Date type 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_TYPES_H
++#define _ASM_UBICOM32_TYPES_H
++
++/*
++ * This file is never included by application software unless
++ * explicitly requested (e.g., via linux/types.h) in which case the
++ * application is Linux specific so (user-) name space pollution is
++ * not a major issue. However, for interoperability, libraries still
++ * need to be careful to avoid a name clashes.
++ */
++
++#include
++
++#ifndef __ASSEMBLY__
++
++typedef unsigned short umode_t;
++
++#endif /* __ASSEMBLY__ */
++
++/*
++ * These aren't exported outside the kernel to avoid name space clashes
++ */
++#ifdef __KERNEL__
++
++#define BITS_PER_LONG 32
++
++#ifndef __ASSEMBLY__
++
++/* DMA addresses are always 32-bits wide */
++
++typedef u32 dma_addr_t;
++typedef u32 dma64_addr_t;
++
++/*
++ * XXX These are "Ubicom style" typedefs. They should be removed in all files used by linux.
++ */
++typedef u32 u32_t;
++typedef s32 s32_t;
++typedef u16 u16_t;
++typedef s16 s16_t;
++typedef u8 u8_t;
++typedef s8 s8_t;
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_UBICOM32_TYPES_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/uaccess.h
+@@ -0,0 +1,347 @@
++/*
++ * arch/ubicom32/include/asm/uaccess.h
++ * User space memory access 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ * arch/alpha
++ */
++#ifndef _ASM_UBICOM32_UACCESS_H
++#define _ASM_UBICOM32_UACCESS_H
++
++/*
++ * User space memory access functions
++ */
++#include
++#include
++#include
++
++#include
++
++#define VERIFY_READ 0
++#define VERIFY_WRITE 1
++
++/*
++ * The exception table consists of pairs of addresses: the first is the
++ * address of an instruction that is allowed to fault, and the second is
++ * the address at which the program should continue. No registers are
++ * modified, so it is entirely up to the continuation code to figure out
++ * what to do.
++ *
++ * All the routines below use bits of fixup code that are out of line
++ * with the main instruction path. This means when everything is well,
++ * we don't even have to jump over them. Further, they do not intrude
++ * on our cache or tlb entries.
++ */
++struct exception_table_entry
++{
++ unsigned long insn, fixup;
++};
++
++/*
++ * Ubicom32 does not currently support the exception table handling.
++ */
++extern unsigned long search_exception_table(unsigned long);
++
++
++#if defined(CONFIG_ACCESS_OK_CHECKS_ENABLED)
++extern int __access_ok(unsigned long addr, unsigned long size);
++#else
++static inline int __access_ok(unsigned long addr, unsigned long size)
++{
++ return 1;
++}
++#endif
++#define access_ok(type, addr, size) \
++ likely(__access_ok((unsigned long)(addr), (size)))
++
++/*
++ * The following functions do not exist. They keep callers
++ * of put_user and get_user from passing unsupported argument
++ * types. They result in a link time error.
++ */
++extern int __put_user_bad(void);
++extern int __get_user_bad(void);
++
++/*
++ * __put_user_no_check()
++ * Put the requested data into the user space verifying the address
++ *
++ * Careful to not
++ * (a) re-use the arguments for side effects (sizeof/typeof is ok)
++ * (b) require any knowledge of processes at this stage
++ */
++#define __put_user_no_check(x, ptr, size) \
++({ \
++ int __pu_err = 0; \
++ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
++ switch (size) { \
++ case 1: \
++ case 2: \
++ case 4: \
++ case 8: \
++ *__pu_addr = (__typeof__(*(ptr)))x; \
++ break; \
++ default: \
++ __pu_err = __put_user_bad(); \
++ break; \
++ } \
++ __pu_err; \
++})
++
++/*
++ * __put_user_check()
++ * Put the requested data into the user space verifying the address
++ *
++ * Careful to not
++ * (a) re-use the arguments for side effects (sizeof/typeof is ok)
++ * (b) require any knowledge of processes at this stage
++ *
++ * If requested, access_ok() will verify that ptr is a valid user
++ * pointer.
++ */
++#define __put_user_check(x, ptr, size) \
++({ \
++ int __pu_err = -EFAULT; \
++ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
++ if (access_ok(VERIFY_WRITE, __pu_addr, size)) { \
++ __pu_err = 0; \
++ switch (size) { \
++ case 1: \
++ case 2: \
++ case 4: \
++ case 8: \
++ *__pu_addr = (__typeof__(*(ptr)))x; \
++ break; \
++ default: \
++ __pu_err = __put_user_bad(); \
++ break; \
++ } \
++ } \
++ __pu_err; \
++})
++
++/*
++ * __get_user_no_check()
++ * Read the value at ptr into x.
++ *
++ * If requested, access_ok() will verify that ptr is a valid user
++ * pointer. If the caller passes a modifying argument for ptr (e.g. x++)
++ * this macro will not work.
++ */
++#define __get_user_no_check(x, ptr, size) \
++({ \
++ int __gu_err = 0; \
++ __typeof__((x)) __gu_val = 0; \
++ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
++ switch (size) { \
++ case 1: \
++ case 2: \
++ case 4: \
++ case 8: \
++ __gu_val = (__typeof__((x)))*(__gu_addr); \
++ break; \
++ default: \
++ __gu_err = __get_user_bad(); \
++ (x) = 0; \
++ break; \
++ } \
++ (x) = __gu_val; \
++ __gu_err; \
++})
++
++/*
++ * __get_user_check()
++ * Read the value at ptr into x.
++ *
++ * If requested, access_ok() will verify that ptr is a valid user
++ * pointer.
++ */
++#define __get_user_check(x, ptr, size) \
++({ \
++ int __gu_err = -EFAULT; \
++ __typeof__(x) __gu_val = 0; \
++ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
++ if (access_ok(VERIFY_READ, __gu_addr, size)) { \
++ __gu_err = 0; \
++ switch (size) { \
++ case 1: \
++ case 2: \
++ case 4: \
++ case 8: \
++ __gu_val = (__typeof__((x)))*(__gu_addr); \
++ break; \
++ default: \
++ __gu_err = __get_user_bad(); \
++ (x) = 0; \
++ break; \
++ } \
++ } \
++ (x) = __gu_val; \
++ __gu_err; \
++})
++
++/*
++ * The "xxx" versions are allowed to perform some amount of address
++ * space checking. See access_ok().
++ */
++#define put_user(x,ptr) \
++ __put_user_check((__typeof__(*(ptr)))(x),(ptr), sizeof(*(ptr)))
++#define get_user(x,ptr) \
++ __get_user_check((x), (ptr), sizeof(*(ptr)))
++
++/*
++ * The "__xxx" versions do not do address space checking, useful when
++ * doing multiple accesses to the same area (the programmer has to do the
++ * checks by hand with "access_ok()")
++ */
++#define __put_user(x,ptr) \
++ __put_user_no_check((__typeof__(*(ptr)))(x),(ptr), sizeof(*(ptr)))
++#define __get_user(x,ptr) \
++ __get_user_no_check((x), (ptr), sizeof(*(ptr)))
++
++/*
++ * __copy_tofrom_user_no_check()
++ * Copy the data either to or from user space.
++ *
++ * Return the number of bytes NOT copied.
++ */
++static inline unsigned long
++__copy_tofrom_user_no_check(void *to, const void *from, unsigned long n)
++{
++ memcpy(to, from, n);
++ return 0;
++}
++
++/*
++ * copy_to_user()
++ * Copy the kernel data to user space.
++ *
++ * Return the number of bytes that were copied.
++ */
++static inline unsigned long
++copy_to_user(void __user *to, const void *from, unsigned long n)
++{
++ if (!access_ok(VERIFY_WRITE, to, n)) {
++ return n;
++ }
++ return __copy_tofrom_user_no_check((__force void *)to, from, n);
++}
++
++/*
++ * copy_from_user()
++ * Copy the user data to kernel space.
++ *
++ * Return the number of bytes that were copied. On error, we zero
++ * out the destination.
++ */
++static inline unsigned long
++copy_from_user(void *to, const void __user *from, unsigned long n)
++{
++ if (!access_ok(VERIFY_READ, from, n)) {
++ return n;
++ }
++ return __copy_tofrom_user_no_check(to, (__force void *)from, n);
++}
++
++#define __copy_to_user(to, from, n) \
++ __copy_tofrom_user_no_check((__force void *)to, from, n)
++#define __copy_from_user(to, from, n) \
++ __copy_tofrom_user_no_check(to, (__force void *)from, n)
++#define __copy_to_user_inatomic(to, from, n) \
++ __copy_tofrom_user_no_check((__force void *)to, from, n)
++#define __copy_from_user_inatomic(to, from, n) \
++ __copy_tofrom_user_no_check(to, (__force void *)from, n)
++
++#define copy_to_user_ret(to, from, n, retval) \
++ ({ if (copy_to_user(to, from, n)) return retval; })
++
++#define copy_from_user_ret(to, from, n, retval) \
++ ({ if (copy_from_user(to, from, n)) return retval; })
++
++/*
++ * strncpy_from_user()
++ * Copy a null terminated string from userspace.
++ *
++ * dst - Destination in kernel space. The buffer must be at least count.
++ * src - Address of string in user space.
++ * count - Maximum number of bytes to copy (including the trailing NULL).
++ *
++ * Returns the length of the string (not including the trailing NULL. If
++ * count is smaller than the length of the string, we copy count bytes
++ * and return count.
++ *
++ */
++static inline long strncpy_from_user(char *dst, const __user char *src, long count)
++{
++ char *tmp;
++ if (!access_ok(VERIFY_READ, src, 1)) {
++ return -EFAULT;
++ }
++
++ strncpy(dst, src, count);
++ for (tmp = dst; *tmp && count > 0; tmp++, count--) {
++ ;
++ }
++ return(tmp - dst);
++}
++
++/*
++ * strnlen_user()
++ * Return the size of a string (including the ending 0)
++ *
++ * Return -EFAULT on exception, a value greater than if too long
++ */
++static inline long strnlen_user(const __user char *src, long n)
++{
++ if (!access_ok(VERIFY_READ, src, 1)) {
++ return -EFAULT;
++ }
++ return(strlen(src) + 1);
++}
++
++#define strlen_user(str) strnlen_user(str, 32767)
++
++/*
++ * __clear_user()
++ * Zero Userspace
++ */
++static inline unsigned long __clear_user(__user void *to, unsigned long n)
++{
++ memset(to, 0, n);
++ return 0;
++}
++
++/*
++ * clear_user()
++ * Zero user space (check for valid addresses)
++ */
++static inline unsigned long clear_user(__user void *to, unsigned long n)
++{
++ if (!access_ok(VERIFY_WRITE, to, n)) {
++ return -EFAULT;
++ }
++ return __clear_user(to, n);
++}
++
++#endif /* _ASM_UBICOM32_UACCESS_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubi32-cs4384.h
+@@ -0,0 +1,53 @@
++/*
++ * arch/ubicom32/include/asm/ubi32-cs4384.h
++ * Ubicom32 architecture CS4384 driver platform data 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 .
++ */
++#ifndef _ASM_UBICOM32_UBI32_CS4384_H
++#define _ASM_UBICOM32_UBI32_CS4384_H
++
++enum ubi32_cs4384_mclk_source {
++ UBI32_CS4384_MCLK_PWM_0,
++ UBI32_CS4384_MCLK_PWM_1,
++ UBI32_CS4384_MCLK_PWM_2,
++ UBI32_CS4384_MCLK_CLKDIV_1,
++ UBI32_CS4384_MCLK_OTHER,
++};
++
++struct ubi32_cs4384_mclk_entry {
++ /*
++ * Rate, in Hz, of this entry
++ */
++ int rate;
++
++ /*
++ * The divider to program to get the rate
++ */
++ int div;
++};
++
++struct ubi32_cs4384_platform_data {
++ enum ubi32_cs4384_mclk_source mclk_src;
++
++ int n_mclk;
++ struct ubi32_cs4384_mclk_entry *mclk_entries;
++};
++#endif /* _ASM_UBICOM32_UBI32_CS4384_H */
++
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubi32-pcm.h
+@@ -0,0 +1,53 @@
++/*
++ * arch/ubicom32/include/asm/ubi32-pcm.h
++ * Ubicom32 architecture PCM driver platform data 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 .
++ */
++#ifndef _ASM_UBICOM32_UBI32_PCM_H
++#define _ASM_UBICOM32_UBI32_PCM_H
++
++/*
++ * This function is called when the sample rate has changed
++ */
++typedef int (*ubi32_pcm_set_rate_fn_t)(void *appdata, int rate);
++
++struct ubi32pcm_platform_data {
++ /*
++ * Name of the audiotio node
++ */
++ const char *node_name;
++
++ /*
++ * Application specific data provided when calling functions
++ */
++ void *appdata;
++
++ /*
++ * Functions called when various things happen
++ */
++ ubi32_pcm_set_rate_fn_t set_rate;
++
++ /*
++ * Pointer to optional upper layer data (i.e. DAC config, etc)
++ */
++ void *priv_data;
++};
++#endif /* _ASM_UBICOM32_UBI32_PCM_H */
++
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32bl.h
+@@ -0,0 +1,84 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32bl.h
++ * Ubicom32 architecture backlight driver platform data 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_BL_H
++#define _ASM_UBICOM32_UBICOM32_BL_H
++
++/*
++ * Different backlight control mechanisms
++ */
++enum ubicom32bl_pwm_types {
++ /*
++ * PWM controlled backlight
++ */
++ UBICOM32BL_TYPE_PWM,
++
++ /*
++ * HRT based PWM backlight
++ */
++ UBICOM32BL_TYPE_PWM_HRT,
++
++ /*
++ * No dimming, just on or off
++ */
++ UBICOM32BL_TYPE_BINARY,
++};
++
++struct ubicom32bl_platform_data {
++ /*
++ * Default intensity of the backlight 0-255
++ */
++ u8_t default_intensity;
++
++ /*
++ * TRUE if the backlight sense is active low. (inverted)
++ * FALSE if the backlight sense is active high.
++ */
++ bool invert;
++
++ /*
++ * Type of the backlight
++ */
++ enum ubicom32bl_pwm_types type;
++
++ /*
++ * GPIO of the backlight if UBICOM32BL_TYPE_PWM_HRT, UBICOM32BL_TYPE_BINARY
++ */
++ unsigned gpio;
++
++ /*
++ * PWM channel and parameters of the backlight if UBICOM32BL_TYPE_PWM
++ * pre_scaler: sets the rate at which the PWM timer is clocked. (clk_core / 2^pre_scaler)
++ * period: sets the period of the timer in timer cycles
++ * The duty cycle will be directly proportional to the brightness setting.
++ */
++ u32_t pwm_channel;
++ u8_t pwm_prescale;
++ u16_t pwm_period;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_BL_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32-common-asm.h
+@@ -0,0 +1,49 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32-common-asm.h
++ * Ubicom32 atomic lock operations.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
++#define _ASM_UBICOM32_UBICOM32_COMMON_ASM_H
++
++/*
++ * atomic_lock_acquire macro
++ * Equivalent to __atomic_lock_acquire()
++ */
++.macro atomic_lock_acquire
++ bset scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
++ jmpne.f .-4
++.endm
++
++/*
++ * atomic_lock_release macro
++ * Equivalent to __atomic_lock_release()
++ */
++.macro atomic_lock_release
++ bclr scratchpad1, scratchpad1, #ATOMIC_LOCK_BIT
++.endm
++
++#endif /* _ASM_UBICOM32_UBICOM32_COMMON_ASM_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32-common.h
+@@ -0,0 +1,124 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32-common.h
++ * Ubicom32 atomic lock operations.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_UBICOM32_COMMON_H
++#define _ASM_UBICOM32_UBICOM32_COMMON_H
++
++#define S(arg) #arg
++#define D(arg) S(arg)
++/*
++ * scratchpad1 is owned by the LDSR.
++ *
++ * The upper bits provide 16 global spinlocks. Acquiring one of these
++ * global spinlocks synchornizes across multiple threads and prevents
++ * the LDSR from delivering any interrupts while the lock is held.
++ * Use these locks only when absolutely required.
++ *
++ * The lower 16 bits of scratchpad1 are used as per thread interrupt
++ * enable/disable bits. These bits will prevent a thread from receiving
++ * any interrupts.
++ *
++ * Bit Usage:
++ * - MT_EN_LOCK_BIT - Protects writes to MT_EN, so code can read current value
++ * then write a new value atomically (profiler for example)
++ * - ATOMIC_LOCK_BIT - Used to provide general purpose atomic handling.
++ * - LDSR_LOCK_BIT - Used by the LDSR exclusively to provide protection.
++ * - LSB 16 bits - Used by the LDSR to represent thread enable/disable bits.
++ */
++#define MT_EN_LOCK_BIT 31
++#define ATOMIC_LOCK_BIT 30
++#define LDSR_LOCK_BIT 29
++#define PCI_LOCK_BIT 28
++
++#if !defined(__ASSEMBLY__)
++
++#define UBICOM32_TRYLOCK(bit) \
++ asm volatile ( \
++ " move.4 %0, #0 \n\t" \
++ " bset scratchpad1, scratchpad1, #"D(bit)" \n\t" \
++ " jmpne.f 1f \n\t" \
++ " move.4 %0, #1 \n\t" \
++ "1: \n\t" \
++ : "=r" (ret) \
++ : \
++ : "cc", "memory" \
++ ); \
++
++#define UBICOM32_UNLOCK(bit) \
++ asm volatile ( \
++ " bclr scratchpad1, scratchpad1, #"D(bit)" \n\t" \
++ : \
++ : \
++ : "cc", "memory" \
++ ); \
++
++#define UBICOM32_LOCK(bit) \
++ asm volatile ( \
++ "1: bset scratchpad1, scratchpad1, #"D(bit)" \n\t" \
++ " jmpne.f 1b \n\t" \
++ : \
++ : \
++ : "cc", "memory" \
++ ); \
++
++/*
++ * __atomic_lock_trylock()
++ * Attempt to acquire the lock, return TRUE if acquired.
++ */
++static inline int __atomic_lock_trylock(void)
++{
++ int ret;
++ UBICOM32_TRYLOCK(ATOMIC_LOCK_BIT);
++ return ret;
++}
++
++/*
++ * __atomic_lock_release()
++ * Release the global atomic lock.
++ *
++ * Note: no one is suspended waiting since this lock is a spinning lock.
++ */
++static inline void __atomic_lock_release(void)
++{
++ UBICOM32_UNLOCK(ATOMIC_LOCK_BIT);
++}
++
++/*
++ * __atomic_lock_acquire()
++ * Acquire the global atomic lock, spin if not available.
++ */
++static inline void __atomic_lock_acquire(void)
++{
++ UBICOM32_LOCK(ATOMIC_LOCK_BIT);
++}
++#else /* __ASSEMBLY__ */
++
++#include
++
++#endif /* __ASSEMBLY__ */
++#endif /* _ASM_UBICOM32_UBICOM32_COMMON_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32fb.h
+@@ -0,0 +1,56 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32fb.h
++ * Ubicom32 architecture video frame buffer 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 .
++ */
++#ifndef _ASM_UBICOM32_UBICOM32FB_H
++#define _ASM_UBICOM32_UBICOM32FB_H
++
++#include
++
++/*
++ * Set next frame
++ */
++#define UBICOM32FB_IOCTL_SET_NEXT_FRAME _IOW('r', 1, void *)
++#define UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC _IOW('r', 2, void *)
++
++/*
++ * Set Mode
++ */
++#define UBICOM32FB_IOCTL_SET_MODE _IOW('r', 3, void *)
++struct ubicom32fb_mode {
++ unsigned long width;
++ unsigned long height;
++ unsigned long flags;
++ void *next_frame;
++};
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER (1 << 8)
++
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER (1 << 7)
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV (1 << 6)
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB (1 << 5)
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255 (1 << 4)
++
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255 (1 << 3)
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1 (1 << 2)
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1 (1 << 1)
++#define UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE (1 << 0)
++
++#endif /* _ASM_UBICOM32_UBICOM32FB_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32hid.h
+@@ -0,0 +1,133 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32hid.h
++ * Ubicom32 architecture HID driver platform data 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_HID_H
++#define _ASM_UBICOM32_UBICOM32_HID_H
++
++enum ubicom32hid_bl_types {
++ /*
++ * On or off, using command SET_BL_EN, PB4
++ */
++ UBICOM32HID_BL_TYPE_BINARY,
++
++ /*
++ * Dimmable, using command SET_PWM, PB3
++ */
++ UBICOM32HID_BL_TYPE_PWM,
++};
++
++/*
++ * IR code mapping to event code.
++ * If there are no button mappings and no ir mappings
++ * then no input driver will be registered.
++ */
++struct ubicom32hid_ir {
++ /*
++ * Input event code (KEY_*, SW_*, etc)
++ */
++ int code;
++
++ /*
++ * Input event type (EV_KEY, EV_SW, etc)
++ */
++ int type;
++
++ /*
++ * The IR code of this button.
++ */
++ uint32_t ir_code;
++};
++
++/*
++ * Button mapping to event code.
++ * If there are no button mappings and no ir mappings
++ * then no input driver will be registered.
++ */
++struct ubicom32hid_button {
++ /*
++ * Input event code (KEY_*, SW_*, etc)
++ */
++ int code;
++
++ /*
++ * Input event type (EV_KEY, EV_SW, etc)
++ */
++ int type;
++
++ /*
++ * Bit number of this button.
++ */
++ uint8_t bit;
++};
++
++struct ubicom32hid_platform_data {
++ /*
++ * Default intensity of the backlight 0-255
++ */
++ u8_t default_intensity;
++
++ /*
++ * GPIO number of the reset line and its polarity.
++ */
++ unsigned gpio_reset;
++ int gpio_reset_polarity;
++
++ /*
++ * TRUE if the backlight sense is active low. (inverted)
++ * FALSE if the backlight sense is active high.
++ */
++ bool invert;
++
++ /*
++ * Type of the backlight we are controlling
++ */
++ enum ubicom32hid_bl_types type;
++
++ /*
++ * Optional polling rate for input, in ms, defaults to 100ms
++ */
++ int poll_interval;
++
++ /*
++ * Optional name to register as input device
++ */
++ const char *input_name;
++
++ /*
++ * Button mapping array
++ */
++ const struct ubicom32hid_button *buttons;
++ int nbuttons;
++
++ /*
++ * IR mapping array
++ */
++ const struct ubicom32hid_ir *ircodes;
++ int nircodes;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_HID_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32input.h
+@@ -0,0 +1,76 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32input.h
++ * Ubicom32 Input driver, based on gpio-keys
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ *
++ * TODO: add groups for inputs which can be sampled together
++ */
++
++#ifndef _ASM_UBICOM32_UBICOM32_INPUT_H
++#define _ASM_UBICOM32_UBICOM32_INPUT_H
++
++struct ubicom32input_button {
++ /*
++ * Input event code (KEY_*, SW_*, etc)
++ */
++ int code;
++
++ /*
++ * Input event type (EV_KEY, EV_SW, etc)
++ */
++ int type;
++
++ /*
++ * GPIO to poll
++ */
++ int gpio;
++
++ /*
++ * 1 for active low, 0 for active high
++ */
++ int active_low;
++
++ /*
++ * Description, used for reserving GPIOs
++ */
++ const char *desc;
++};
++
++struct ubicom32input_platform_data {
++ struct ubicom32input_button *buttons;
++ int nbuttons;
++
++ /*
++ * Optional poll interval, in ms, defaults to 50ms
++ */
++ int poll_interval;
++
++ /*
++ * Option Name of this driver
++ */
++ const char *name;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_INPUT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32input_i2c.h
+@@ -0,0 +1,71 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32input_i2c.h
++ * Ubicom32 architecture Input driver over I2C platform data 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ *
++ * TODO: add groups for inputs which can be sampled together
++ */
++
++#ifndef _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
++#define _ASM_UBICOM32_UBICOM32_INPUT_I2C_H
++
++struct ubicom32input_i2c_button {
++ /*
++ * Input event code (KEY_*, SW_*, etc)
++ */
++ int code;
++
++ /*
++ * Input event type (EV_KEY, EV_SW, etc)
++ */
++ int type;
++
++ /*
++ * Bit number of this button. (0 - ngpio)
++ */
++ int bit;
++
++ /*
++ * 1 for active low, 0 for active high
++ */
++ int active_low;
++};
++
++struct ubicom32input_i2c_platform_data {
++ struct ubicom32input_i2c_button *buttons;
++ int nbuttons;
++
++ /*
++ * Optional poll interval, in ms, defaults to 100ms
++ */
++ int poll_interval;
++
++ /*
++ * Option Name of this driver
++ */
++ const char *name;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_INPUT_I2C_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32lcd.h
+@@ -0,0 +1,39 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32lcd.h
++ * Ubicom32 architecture LCD driver platform data 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_LCD_H
++#define _ASM_UBICOM32_UBICOM32_LCD_H
++
++struct ubicom32lcd_platform_data {
++ /*
++ * GPIO and polarity for VGH signal. A FALSE polarity is active low, TRUE is active high.
++ */
++ int vgh_gpio;
++ bool vgh_polarity;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_LCD_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32ring.h
+@@ -0,0 +1,103 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32ring.h
++ * Userspace I/O platform driver for Ubicom32 ring buffers
++ *
++ * (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 .
++ */
++
++#ifndef _ASM_UBICOM32_UBICOM32RING_H
++#define _ASM_UBICOM32_UBICOM32RING_H
++
++#define UIO_UBICOM32RING_REG_VERSION 2
++
++struct uio_ubicom32ring_desc {
++ volatile unsigned int head;
++ volatile unsigned int tail;
++ unsigned int entries;
++ volatile unsigned int ring[0];
++};
++
++struct uio_ubicom32ring_regs {
++ unsigned int version;
++
++ /*
++ * Magic type used to identify the ring set. Each driver will
++ * have a different magic value.
++ */
++ unsigned int magic;
++
++ /*
++ * Registers defined by the driver
++ */
++ unsigned int regs_size;
++ void *regs;
++
++ /*
++ * The locations of the rings
++ *
++ * DO NOT ADD ANYTHING BELOW THIS LINE
++ */
++ unsigned int num_rings;
++ struct uio_ubicom32ring_desc *rings[0];
++};
++
++/*
++ * ringtio_ring_flush
++ */
++static inline void ringtio_ring_flush(struct uio_ubicom32ring_desc *rd)
++{
++ rd->head = rd->tail = 0;
++}
++
++/*
++ * ringtio_ring_get
++ */
++static inline int ringtio_ring_get(struct uio_ubicom32ring_desc *rd, void **val)
++{
++ if (rd->head == rd->tail) {
++ return 0;
++ }
++
++ *val = (void *)rd->ring[rd->head++];
++ if (rd->head == rd->entries) {
++ rd->head = 0;
++ }
++ return 1;
++}
++
++/*
++ * ringtio_ring_put
++ */
++static inline int ringtio_ring_put(struct uio_ubicom32ring_desc *rd, void *val)
++{
++ unsigned int newtail = rd->tail + 1;
++ if (newtail == rd->entries) {
++ newtail = 0;
++ }
++
++ if (newtail == rd->head) {
++ return 0;
++ }
++
++ rd->ring[rd->tail] = (unsigned int)val;
++ rd->tail = newtail;
++ return 1;
++}
++
++#endif /* _ASM_UBICOM32_UBICOM32RING_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32sd.h
+@@ -0,0 +1,45 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32sd.h
++ * Ubicom32SD public 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 .
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_SD_H
++#define _ASM_UBICOM32_UBICOM32_SD_H
++
++struct ubicom32sd_card {
++ /*
++ * GPIOs of PWR, WP and CD lines.
++ * Polarity is 1 for active high and 0 for active low
++ */
++ int pin_pwr;
++ bool pwr_polarity;
++ int pin_wp;
++ bool wp_polarity;
++ int pin_cd;
++ bool cd_polarity;
++};
++
++struct ubicom32sd_platform_data {
++ int ncards;
++
++ struct ubicom32sd_card *cards;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_SD_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32-spi-gpio.h
+@@ -0,0 +1,62 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32-spi-gpio.h
++ * Platform driver data definitions for GPIO based SPI driver.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
++#define _ASM_UBICOM32_UBICOM32_SPI_GPIO_H
++
++struct ubicom32_spi_gpio_platform_data {
++ /*
++ * GPIO to use for MOSI, MISO, CLK
++ */
++ int pin_mosi;
++ int pin_miso;
++ int pin_clk;
++
++ /*
++ * Default state of CLK line
++ */
++ int clk_default;
++
++ /*
++ * Number of chip selects on this bus
++ */
++ int num_chipselect;
++
++ /*
++ * The bus number of this chip
++ */
++ int bus_num;
++};
++
++struct ubicom32_spi_gpio_controller_data {
++ /*
++ * GPIO to use for chip select
++ */
++ int pin_cs;
++};
++
++#endif /* _ASM_UBICOM32_UBICOM32_SPI_GPIO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32suart.h
+@@ -0,0 +1,36 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32suart.h
++ *
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_SUART_H
++#define _ASM_UBICOM32_UBICOM32_SUART_H
++
++/*
++ * Platform resource id for serdes uart clock parameter
++ */
++#define UBICOM32_SUART_IORESOURCE_CLOCK (1)
++
++#endif /* _ASM_UBICOM32_UBICOM32_SUART_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ubicom32-tio.h
+@@ -0,0 +1,42 @@
++/*
++ * arch/ubicom32/include/asm/ubicom32-tio.h
++ * Threaded I/O 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UBICOM32_TIO_H
++#define _ASM_UBICOM32_UBICOM32_TIO_H
++
++extern u8_t usb_tio_read_u16(u32_t address, u16_t *data);
++extern u8_t usb_tio_read_u8(u32_t address, u8_t *data);
++
++extern u8_t usb_tio_write_u16(u32_t address, u16_t data);
++extern u8_t usb_tio_write_u8(u32_t address, u8_t data);
++
++extern u8_t usb_tio_read_fifo(u32_t address, u32_t buffer, u32_t bytes);
++extern u8_t usb_tio_write_fifo(u32_t address, u32_t buffer, u32_t bytes);
++extern u8_t usb_tio_write_fifo_sync(u32_t address, u32_t buffer, u32_t bytes);
++extern void usb_tio_read_int_status(u8_t *int_usb, u16_t *int_tx, u16_t *int_rx);
++
++#endif /* _ASM_UBICOM32_UBICOM32_TIO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/ucontext.h
+@@ -0,0 +1,39 @@
++/*
++ * arch/ubicom32/include/asm/ucontext.h
++ * Definition of ucontext structure 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UCONTEXT_H
++#define _ASM_UBICOM32_UCONTEXT_H
++
++struct ucontext {
++ unsigned long uc_flags;
++ struct ucontext *uc_link;
++ stack_t uc_stack;
++ struct sigcontext uc_mcontext;
++ sigset_t uc_sigmask; /* mask last for extensibility */
++};
++
++#endif /* _ASM_UBICOM32_UCONTEXT_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/unaligned.h
+@@ -0,0 +1,44 @@
++/*
++ * arch/ubicom32/include/asm/unaligned.h
++ * Ubicom32 architecture unaligned memory access 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ *
++ * TODO: This is a copy of arm unaligned handling that probably needs
++ * to be optimized for UBICOM32, but it works for now.
++ */
++
++#ifndef _ASM_UBICOM32_UNALIGNED_H
++#define _ASM_UBICOM32_UNALIGNED_H
++
++#include
++
++#include
++#include
++#include
++
++#define get_unaligned __get_unaligned_be
++#define put_unaligned __put_unaligned_be
++
++#endif /* _ASM_UBICOM32_UNALIGNED_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/unistd.h
+@@ -0,0 +1,400 @@
++/*
++ * arch/ubicom32/include/asm/unistd.h
++ * Ubicom32 architecture syscall 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_UNISTD_H
++#define _ASM_UBICOM32_UNISTD_H
++
++/*
++ * This file contains the system call numbers.
++ */
++
++#define __NR_restart_syscall 0
++#define __NR_exit 1
++#define __NR_fork 2
++#define __NR_read 3
++#define __NR_write 4
++#define __NR_open 5
++#define __NR_close 6
++#define __NR_waitpid 7
++#define __NR_creat 8
++#define __NR_link 9
++#define __NR_unlink 10
++#define __NR_execve 11
++#define __NR_chdir 12
++#define __NR_time 13
++#define __NR_mknod 14
++#define __NR_chmod 15
++#define __NR_chown 16
++#define __NR_break 17
++#define __NR_oldstat 18
++#define __NR_lseek 19
++#define __NR_getpid 20
++#define __NR_mount 21
++#define __NR_umount 22
++#define __NR_setuid 23
++#define __NR_getuid 24
++#define __NR_stime 25
++#define __NR_ptrace 26
++#define __NR_alarm 27
++#define __NR_oldfstat 28
++#define __NR_pause 29
++#define __NR_utime 30
++#define __NR_stty 31
++#define __NR_gtty 32
++#define __NR_access 33
++#define __NR_nice 34
++#define __NR_ftime 35
++#define __NR_sync 36
++#define __NR_kill 37
++#define __NR_rename 38
++#define __NR_mkdir 39
++#define __NR_rmdir 40
++#define __NR_dup 41
++#define __NR_pipe 42
++#define __NR_times 43
++#define __NR_prof 44
++#define __NR_brk 45
++#define __NR_setgid 46
++#define __NR_getgid 47
++#define __NR_signal 48
++#define __NR_geteuid 49
++#define __NR_getegid 50
++#define __NR_acct 51
++#define __NR_umount2 52
++#define __NR_lock 53
++#define __NR_ioctl 54
++#define __NR_fcntl 55
++#define __NR_mpx 56
++#define __NR_setpgid 57
++#define __NR_ulimit 58
++#define __NR_oldolduname 59
++#define __NR_umask 60
++#define __NR_chroot 61
++#define __NR_ustat 62
++#define __NR_dup2 63
++#define __NR_getppid 64
++#define __NR_getpgrp 65
++#define __NR_setsid 66
++#define __NR_sigaction 67
++#define __NR_sgetmask 68
++#define __NR_ssetmask 69
++#define __NR_setreuid 70
++#define __NR_setregid 71
++#define __NR_sigsuspend 72
++#define __NR_sigpending 73
++#define __NR_sethostname 74
++#define __NR_setrlimit 75
++#define __NR_getrlimit 76
++#define __NR_getrusage 77
++#define __NR_gettimeofday 78
++#define __NR_settimeofday 79
++#define __NR_getgroups 80
++#define __NR_setgroups 81
++#define __NR_select 82
++#define __NR_symlink 83
++#define __NR_oldlstat 84
++#define __NR_readlink 85
++#define __NR_uselib 86
++#define __NR_swapon 87
++#define __NR_reboot 88
++#define __NR_readdir 89
++#define __NR_mmap 90
++#define __NR_munmap 91
++#define __NR_truncate 92
++#define __NR_ftruncate 93
++#define __NR_fchmod 94
++#define __NR_fchown 95
++#define __NR_getpriority 96
++#define __NR_setpriority 97
++#define __NR_profil 98
++#define __NR_statfs 99
++#define __NR_fstatfs 100
++#define __NR_ioperm 101
++#define __NR_socketcall 102
++#define __NR_syslog 103
++#define __NR_setitimer 104
++#define __NR_getitimer 105
++#define __NR_stat 106
++#define __NR_lstat 107
++#define __NR_fstat 108
++#define __NR_olduname 109
++#define __NR_iopl /* 110 */ not supported
++#define __NR_vhangup 111
++#define __NR_idle /* 112 */ Obsolete
++#define __NR_vm86 /* 113 */ not supported
++#define __NR_wait4 114
++#define __NR_swapoff 115
++#define __NR_sysinfo 116
++#define __NR_ipc 117
++#define __NR_fsync 118
++#define __NR_sigreturn 119
++#define __NR_clone 120
++#define __NR_setdomainname 121
++#define __NR_uname 122
++#define __NR_cacheflush 123
++#define __NR_adjtimex 124
++#define __NR_mprotect 125
++#define __NR_sigprocmask 126
++#define __NR_create_module 127
++#define __NR_init_module 128
++#define __NR_delete_module 129
++#define __NR_get_kernel_syms 130
++#define __NR_quotactl 131
++#define __NR_getpgid 132
++#define __NR_fchdir 133
++#define __NR_bdflush 134
++#define __NR_sysfs 135
++#define __NR_personality 136
++#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
++#define __NR_setfsuid 138
++#define __NR_setfsgid 139
++#define __NR__llseek 140
++#define __NR_getdents 141
++#define __NR__newselect 142
++#define __NR_flock 143
++#define __NR_msync 144
++#define __NR_readv 145
++#define __NR_writev 146
++#define __NR_getsid 147
++#define __NR_fdatasync 148
++#define __NR__sysctl 149
++#define __NR_mlock 150
++#define __NR_munlock 151
++#define __NR_mlockall 152
++#define __NR_munlockall 153
++#define __NR_sched_setparam 154
++#define __NR_sched_getparam 155
++#define __NR_sched_setscheduler 156
++#define __NR_sched_getscheduler 157
++#define __NR_sched_yield 158
++#define __NR_sched_get_priority_max 159
++#define __NR_sched_get_priority_min 160
++#define __NR_sched_rr_get_interval 161
++#define __NR_nanosleep 162
++#define __NR_mremap 163
++#define __NR_setresuid 164
++#define __NR_getresuid 165
++#define __NR_getpagesize 166
++#define __NR_query_module 167
++#define __NR_poll 168
++#define __NR_nfsservctl 169
++#define __NR_setresgid 170
++#define __NR_getresgid 171
++#define __NR_prctl 172
++#define __NR_rt_sigreturn 173
++#define __NR_rt_sigaction 174
++#define __NR_rt_sigprocmask 175
++#define __NR_rt_sigpending 176
++#define __NR_rt_sigtimedwait 177
++#define __NR_rt_sigqueueinfo 178
++#define __NR_rt_sigsuspend 179
++#define __NR_pread64 180
++#define __NR_pwrite64 181
++#define __NR_lchown 182
++#define __NR_getcwd 183
++#define __NR_capget 184
++#define __NR_capset 185
++#define __NR_sigaltstack 186
++#define __NR_sendfile 187
++#define __NR_getpmsg 188 /* some people actually want streams */
++#define __NR_putpmsg 189 /* some people actually want streams */
++#define __NR_vfork 190
++#define __NR_ugetrlimit 191
++#define __NR_mmap2 192
++#define __NR_truncate64 193
++#define __NR_ftruncate64 194
++#define __NR_stat64 195
++#define __NR_lstat64 196
++#define __NR_fstat64 197
++#define __NR_chown32 198
++#define __NR_getuid32 199
++#define __NR_getgid32 200
++#define __NR_geteuid32 201
++#define __NR_getegid32 202
++#define __NR_setreuid32 203
++#define __NR_setregid32 204
++#define __NR_getgroups32 205
++#define __NR_setgroups32 206
++#define __NR_fchown32 207
++#define __NR_setresuid32 208
++#define __NR_getresuid32 209
++#define __NR_setresgid32 210
++#define __NR_getresgid32 211
++#define __NR_lchown32 212
++#define __NR_setuid32 213
++#define __NR_setgid32 214
++#define __NR_setfsuid32 215
++#define __NR_setfsgid32 216
++#define __NR_pivot_root 217
++#define __NR_getdents64 220
++#define __NR_gettid 221
++#define __NR_tkill 222
++#define __NR_setxattr 223
++#define __NR_lsetxattr 224
++#define __NR_fsetxattr 225
++#define __NR_getxattr 226
++#define __NR_lgetxattr 227
++#define __NR_fgetxattr 228
++#define __NR_listxattr 229
++#define __NR_llistxattr 230
++#define __NR_flistxattr 231
++#define __NR_removexattr 232
++#define __NR_lremovexattr 233
++#define __NR_fremovexattr 234
++#define __NR_futex 235
++#define __NR_sendfile64 236
++#define __NR_mincore 237
++#define __NR_madvise 238
++#define __NR_fcntl64 239
++#define __NR_readahead 240
++#define __NR_io_setup 241
++#define __NR_io_destroy 242
++#define __NR_io_getevents 243
++#define __NR_io_submit 244
++#define __NR_io_cancel 245
++#define __NR_fadvise64 246
++#define __NR_exit_group 247
++#define __NR_lookup_dcookie 248
++#define __NR_epoll_create 249
++#define __NR_epoll_ctl 250
++#define __NR_epoll_wait 251
++#define __NR_remap_file_pages 252
++#define __NR_set_tid_address 253
++#define __NR_timer_create 254
++#define __NR_timer_settime 255
++#define __NR_timer_gettime 256
++#define __NR_timer_getoverrun 257
++#define __NR_timer_delete 258
++#define __NR_clock_settime 259
++#define __NR_clock_gettime 260
++#define __NR_clock_getres 261
++#define __NR_clock_nanosleep 262
++#define __NR_statfs64 263
++#define __NR_fstatfs64 264
++#define __NR_tgkill 265
++#define __NR_utimes 266
++#define __NR_fadvise64_64 267
++#define __NR_mbind 268
++#define __NR_get_mempolicy 269
++#define __NR_set_mempolicy 270
++#define __NR_mq_open 271
++#define __NR_mq_unlink 272
++#define __NR_mq_timedsend 273
++#define __NR_mq_timedreceive 274
++#define __NR_mq_notify 275
++#define __NR_mq_getsetattr 276
++#define __NR_waitid 277
++#define __NR_vserver 278
++#define __NR_add_key 279
++#define __NR_request_key 280
++#define __NR_keyctl 281
++#define __NR_ioprio_set 282
++#define __NR_ioprio_get 283
++#define __NR_inotify_init 284
++#define __NR_inotify_add_watch 285
++#define __NR_inotify_rm_watch 286
++#define __NR_migrate_pages 287
++#define __NR_openat 288
++#define __NR_mkdirat 289
++#define __NR_mknodat 290
++#define __NR_fchownat 291
++#define __NR_futimesat 292
++#define __NR_fstatat64 293
++#define __NR_unlinkat 294
++#define __NR_renameat 295
++#define __NR_linkat 296
++#define __NR_symlinkat 297
++#define __NR_readlinkat 298
++#define __NR_fchmodat 299
++#define __NR_faccessat 300
++#define __NR_pselect6 301
++#define __NR_ppoll 302
++#define __NR_unshare 303
++#define __NR_set_robust_list 304
++#define __NR_get_robust_list 305
++#define __NR_splice 306
++#define __NR_sync_file_range 307
++#define __NR_tee 308
++#define __NR_vmsplice 309
++#define __NR_move_pages 310
++#define __NR_sched_setaffinity 311
++#define __NR_sched_getaffinity 312
++#define __NR_kexec_load 313
++#define __NR_getcpu 314
++#define __NR_epoll_pwait 315
++#define __NR_utimensat 316
++#define __NR_signalfd 317
++#define __NR_timerfd_create 318
++#define __NR_eventfd 319
++#define __NR_fallocate 320
++#define __NR_timerfd_settime 321
++#define __NR_timerfd_gettime 322
++#define __NR_signalfd4 323
++#define __NR_eventfd2 324
++#define __NR_epoll_create1 325
++#define __NR_dup3 326
++#define __NR_pipe2 327
++#define __NR_inotify_init1 328
++
++#ifdef __KERNEL__
++
++#define NR_syscalls 329
++
++#define __ARCH_WANT_IPC_PARSE_VERSION
++#define __ARCH_WANT_OLD_READDIR
++#define __ARCH_WANT_OLD_STAT
++#define __ARCH_WANT_STAT64
++#define __ARCH_WANT_SYS_ALARM
++#define __ARCH_WANT_SYS_GETHOSTNAME
++#define __ARCH_WANT_SYS_PAUSE
++#define __ARCH_WANT_SYS_SGETMASK
++#define __ARCH_WANT_SYS_SIGNAL
++#define __ARCH_WANT_SYS_TIME
++#define __ARCH_WANT_SYS_UTIME
++#define __ARCH_WANT_SYS_WAITPID
++#define __ARCH_WANT_SYS_SOCKETCALL
++#define __ARCH_WANT_SYS_FADVISE64
++#define __ARCH_WANT_SYS_GETPGRP
++#define __ARCH_WANT_SYS_LLSEEK
++#define __ARCH_WANT_SYS_NICE
++#define __ARCH_WANT_SYS_OLD_GETRLIMIT
++#define __ARCH_WANT_SYS_OLDUMOUNT
++#define __ARCH_WANT_SYS_SIGPENDING
++#define __ARCH_WANT_SYS_SIGPROCMASK
++#define __ARCH_WANT_SYS_RT_SIGACTION
++
++/*
++ * "Conditional" syscalls
++ *
++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
++ * but it doesn't work on all toolchains, so we just do it by hand
++ */
++//#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
++#define cond_syscall(x) long x(void) __attribute__((weak,alias("sys_ni_syscall")))
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_UBICOM32_UNISTD_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/user.h
+@@ -0,0 +1,82 @@
++/*
++ * arch/ubicom32/include/asm/user.h
++ * Ubicom32 architecture core file 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_USER_H
++#define _ASM_UBICOM32_USER_H
++
++#include
++#include
++/*
++ * Adapted from
++ *
++ * Core file format: The core file is written in such a way that gdb
++ * can understand it and provide useful information to the user (under
++ * linux we use the `trad-core' bfd, NOT the osf-core). The file contents
++ * are as follows:
++ *
++ * upage: 1 page consisting of a user struct that tells gdb
++ * what is present in the file. Directly after this is a
++ * copy of the task_struct, which is currently not used by gdb,
++ * but it may come in handy at some point. All of the registers
++ * are stored as part of the upage. The upage should always be
++ * only one page long.
++ * data: The data segment follows next. We use current->end_text to
++ * current->brk to pick up all of the user variables, plus any memory
++ * that may have been sbrk'ed. No attempt is made to determine if a
++ * page is demand-zero or if a page is totally unused, we just cover
++ * the entire range. All of the addresses are rounded in such a way
++ * that an integral number of pages is written.
++ * stack: We need the stack information in order to get a meaningful
++ * backtrace. We need to write the data from usp to
++ * current->start_stack, so we round each of these in order to be able
++ * to write an integer number of pages.
++ */
++
++struct user_ubicom32fp_struct {
++};
++
++struct user {
++ struct pt_regs regs; /* entire machine state */
++ size_t u_tsize; /* text size (pages) */
++ size_t u_dsize; /* data size (pages) */
++ size_t u_ssize; /* stack size (pages) */
++ unsigned long start_code; /* text starting address */
++ unsigned long start_data; /* data starting address */
++ unsigned long start_stack; /* stack starting address */
++ long int signal; /* signal causing core dump */
++ unsigned long u_ar0; /* help gdb find registers */
++ unsigned long magic; /* identifies a core file */
++ char u_comm[32]; /* user command name */
++};
++
++#define NBPG PAGE_SIZE
++#define UPAGES 1
++#define HOST_TEXT_START_ADDR (u.start_code)
++#define HOST_DATA_START_ADDR (u.start_data)
++#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
++
++#endif /* _ASM_UBICOM32_USER_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/vdc_tio.h
+@@ -0,0 +1,129 @@
++/*
++ * arch/ubicom32/include/asm/vdc_tio.h
++ * Ubicom32 architecture VDC TIO 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_VDC_TIO_H
++#define _ASM_UBICOM32_VDC_TIO_H
++
++#include
++
++#define VDCTIO_VP_VERSION 5
++
++#define VDCTIO_SCALE_FLAG_VSUB (1 << 9)
++#define VDCTIO_SCALE_FLAG_YUV_SCAN_ORDER (1 << 8)
++#define VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER (1 << 7)
++#define VDCTIO_SCALE_FLAG_YUV (1 << 6)
++#define VDCTIO_SCALE_FLAG_VRANGE_16_255 (1 << 5)
++#define VDCTIO_SCALE_FLAG_VRANGE_0_255 (1 << 4)
++#define VDCTIO_SCALE_FLAG_HSUB_2_1 (1 << 3)
++#define VDCTIO_SCALE_FLAG_HSUB_1_1 (1 << 2)
++#define VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER (1 << 1)
++#define VDCTIO_SCALE_FLAG_ENABLE (1 << 0)
++
++#define VDCTIO_NEXT_FRAME_FLAG_YUV_BIT 0
++#define VDCTIO_NEXT_FRAME_FLAG_YUV (1 << (VDCTIO_NEXT_FRAME_FLAG_YUV_BIT))
++
++#define VDCTIO_CAPS_SUPPORTS_SCALING (1 << 0)
++
++#define VDCTIO_COMMAND_START (1 << 3)
++#define VDCTIO_COMMAND_SET_COEFF (1 << 2)
++#define VDCTIO_COMMAND_SET_LUT (1 << 1)
++#define VDCTIO_COMMAND_SET_SCALE_MODE (1 << 0)
++
++/*
++ * Command / Data registers to access the VDC
++ */
++struct vdc_tio_vp_regs {
++ /*
++ * Version of this TIO register map
++ */
++ u32_t version;
++
++ volatile u32_t command;
++
++ /*
++ * Next frame pointer, when the command VDCTIO_COMMAND_SET_FRAME_BUFFER is set,
++ * the vdc will take the pointer here and display it.
++ */
++ void *next_frame;
++ u32_t next_frame_flags;
++
++ /*
++ * These map directly into the PIXP registers 0x20-0x80.
++ * DO NOT change the order of these three variables.
++ */
++ u32_t red_lut[6];
++ u32_t blue_lut[6];
++ u32_t green_lut[13];
++
++ /*
++ * These map directly into the PIXP registers 0x04, 0x08
++ */
++ u32_t coeff0;
++ u32_t coeff1;
++
++ /*
++ * There are used to set the scaling parameters
++ */
++ u32_t x_in;
++ u32_t x_out;
++ u32_t y_in;
++ u32_t y_out;
++ u32_t scale_flags;
++
++ /*
++ * Current frame number, monotonically increasing number
++ */
++ u32_t frame_number;
++
++ /*
++ * These variables tell the guest OS what the underlying hardware looks like
++ */
++ u32_t caps;
++ u32_t xres;
++ u32_t yres;
++ u32_t fb_align;
++ u8_t bpp;
++ u8_t rbits;
++ u8_t gbits;
++ u8_t bbits;
++ u8_t rshift;
++ u8_t gshift;
++ u8_t bshift;
++};
++
++/*
++ * Devtree node for VDC
++ */
++struct vdc_tio_node {
++ struct devtree_node dn;
++
++ struct vdc_tio_vp_regs *regs;
++};
++
++extern void vdc_tio_init(void);
++
++#endif /* _ASM_UBICOM32_VDC_TIO_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/vga.h
+@@ -0,0 +1,71 @@
++/*
++ * arch/ubicom32/include/asm/vga.h
++ * Ubicom32 low level VGA/frame buffer definitions.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * (c) 1998 Martin Mares
++ *
++ * 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#ifndef _ASM_UBICOM32_VGA_H
++#define _ASM_UBICOM32_VGA_H
++
++#include
++
++/*
++ * On the PC, we can just recalculate addresses and then
++ * access the videoram directly without any black magic.
++ */
++
++#define VGA_MAP_MEM(x, s) (0xb0000000L + (unsigned long)(x))
++
++#define vga_readb(x) (*(x))
++#define vga_writeb(x, y) (*(y) = (x))
++
++#define VT_BUF_HAVE_RW
++/*
++ * These are only needed for supporting VGA or MDA text mode, which use little
++ * endian byte ordering.
++ * In other cases, we can optimize by using native byte ordering and
++ * has already done the right job for us.
++ */
++
++#undef scr_writew
++#undef scr_readw
++
++static inline void scr_writew(u16 val, volatile u16 *addr)
++{
++ *addr = cpu_to_le16(val);
++}
++
++static inline u16 scr_readw(volatile const u16 *addr)
++{
++ return le16_to_cpu(*addr);
++}
++
++#define scr_memcpyw(d, s, c) memcpy(d, s, c)
++#define scr_memmovew(d, s, c) memmove(d, s, c)
++#define VT_BUF_HAVE_MEMCPYW
++#define VT_BUF_HAVE_MEMMOVEW
++
++#endif /* _ASM_UBICOM32_VGA_H */
+--- /dev/null
++++ b/arch/ubicom32/include/asm/xor.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/ubicom32/include/asm/xor.h
++ * Generic xor.h 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#ifndef _ASM_UBICOM32_XOR_H
++#define _ASM_UBICOM32_XOR_H
++
++#include
++
++#endif /* _ASM_UBICOM32_XOR_H */
+--- /dev/null
++++ b/arch/ubicom32/Kconfig
+@@ -0,0 +1,455 @@
++#
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.txt.
++#
++
++mainmenu "uClinux/ubicom32 (w/o MMU) Kernel Configuration"
++
++config RAMBASE
++ hex
++ default "0x40000000"
++ help
++ Define the address that RAM starts at.
++
++config UBICOM32
++ bool
++ select HAVE_OPROFILE
++ default y
++
++config RAMKERNEL
++ bool
++ default y
++
++config CPU_BIG_ENDIAN
++ bool
++ default y
++
++config FORCE_MAX_ZONEORDER
++ int
++ default "14"
++
++config HAVE_CLK
++ bool
++ default y
++
++config MMU
++ bool
++ default n
++
++config FPU
++ bool
++ default n
++
++config ZONE_DMA
++ bool
++ default y
++
++config RWSEM_GENERIC_SPINLOCK
++ bool
++ default y
++
++config RWSEM_XCHGADD_ALGORITHM
++ bool
++ default n
++
++config ARCH_HAS_ILOG2_U32
++ bool
++ default n
++
++config ARCH_HAS_ILOG2_U64
++ bool
++ default n
++
++config GENERIC_FIND_NEXT_BIT
++ bool
++ default y
++
++config GENERIC_GPIO
++ bool
++ default y
++
++config GPIOLIB
++ bool
++ default y
++
++config GENERIC_HWEIGHT
++ bool
++ default y
++
++config GENERIC_HARDIRQS
++ bool
++ default y
++
++config STACKTRACE_SUPPORT
++ bool
++ default y
++
++config LOCKDEP_SUPPORT
++ bool
++ default y
++
++config GENERIC_CALIBRATE_DELAY
++ bool
++ default y
++
++config GENERIC_TIME
++ bool
++ default y
++
++config TIME_LOW_RES
++ bool
++ default y
++
++config GENERIC_CLOCKEVENTS
++ bool
++ default y
++
++config GENERIC_CLOCKEVENTS_BROADCAST
++ bool
++ depends on GENERIC_CLOCKEVENTS
++ default y if SMP && !LOCAL_TIMERS
++
++config NO_IOPORT
++ def_bool y
++
++config ARCH_SUPPORTS_AOUT
++ def_bool y
++
++config IRQ_PER_CPU
++ bool
++ default y
++
++config SCHED_NO_NO_OMIT_FRAME_POINTER
++ bool
++ default y
++
++menu "Processor type and features"
++
++config BRD_32MB
++ bool
++ depends on IP5160EVAL
++ help
++ Board has 32MB of RAM on it. It is a hidden option used to select default for size of RAM
++ default n
++
++config BRD_64MB
++ bool
++ depends on IP7145DPF || IP7160RGW || IP7160BRINGUP || IP7160DPF || IP5170DPF || IP5160DEV
++ help
++ Board has 64MB of RAM on it. It is a hidden option used to select default for size of RAM
++ default n
++
++config BRD_128MB
++ bool
++ depends on IP7500MODULE || IP7500AV || IP7500MEDIA
++ help
++ Board has 128MB of RAM on it. It is a hidden option used to select default for size of RAM
++ default n
++
++comment "Processor type will be selected by Board"
++
++config UBICOM32_V3
++ bool
++ help
++ Ubicom IP5xxx series processor support.
++
++config UBICOM32_V4
++ bool
++ help
++ Ubicom IP7xxx series processor support.
++
++comment "Board"
++choice
++ prompt "Board type"
++ help
++ Select your board.
++
++config NOBOARD
++ bool "No board selected"
++ help
++ Default. Don't select any board specific config. Will not build unless you change!
++
++# Add your boards here
++source "arch/ubicom32/mach-ip5k/Kconfig"
++source "arch/ubicom32/mach-ip7k/Kconfig"
++
++endchoice
++
++comment "Kernel Options"
++config SMP
++ bool "Symmetric multi-processing support"
++ select USE_GENERIC_SMP_HELPERS
++ default n
++ help
++ Enables multithreading support. Enabling SMP support increases
++ the size of system data structures. SMP support can have either
++ positive or negative impact on performance depending on workloads.
++
++ If you do not know what to do here, say N.
++
++config NR_CPUS
++ int "Number of configured CPUs"
++ range 2 32
++ default 2
++ depends on SMP
++ help
++ Upper bound on the number of CPUs. Space is reserved
++ at compile time for this many CPUs.
++
++config LOCAL_TIMERS
++ bool "Use local timer interrupts"
++ depends on SMP
++ default y
++ help
++ Enable support for local timers on SMP platforms, rather then the
++ legacy IPI broadcast method. Local timers allows the system
++ accounting to be spread across the timer interval, preventing a
++ "thundering herd" at every timer tick. A physical timer is allocated
++ per cpu.
++
++config TIMER_EXTRA_ALLOC
++ int "Number of additional physical timer events to create"
++ depends on GENERIC_CLOCKEVENTS
++ default 0
++ help
++ The Ubicom32 processor has a number of event timers that can be wrapped
++ in Linux clock event structures (assuming that the timers are not being
++ used for another purpose). Based on the value of LOCAL_TIMERS, either
++ 2 timers will be used or a timer will be used for every CPU. This value
++ allows the programmer to select additional timers over that amount.
++
++config IRQSTACKS
++ bool "Create separate stacks for interrupt handling"
++ default n
++ help
++ Selecting this causes interrupts to be created on a separate
++ stack instead of nesting the interrupts on the kernel stack.
++
++config IRQSTACKS_USEOCM
++ bool "Use OCM for interrupt stacks"
++ default n
++ depends on IRQSTACKS
++ help
++ Selecting this cause the interrupt stacks to be placed in OCM
++ reducing cache misses at the expense of using the OCM for servicing
++ interrupts.
++
++menu "OCM Instruction Heap"
++
++config OCM_MODULES_RESERVATION
++ int "OCM Instruction heap reservation. 0-192 kB"
++ range 0 192
++ default "0"
++ help
++ The minimum amount of OCM memory to reserve for kernel loadable module
++ code. If you are not using this memory it cannot be used for anything
++ else. Leave it as 0 if you have prebuilt modules that are compiled with
++ OCM support.
++
++config OCM_MODULES_MAY_CONSUME_REMAINING_CODESPACE
++ bool "Give all unused ocm code space to the ocm instruction heap."
++ default n
++ help
++ Allow the OCM instruction heap allocation to consume any remaining
++ unused OCM code space. The result of this is that you will not have
++ and deterministic results, but you will not have any waste either.
++
++config OCM_MODULES_FALLBACK_TO_DDR
++ bool "Loadable Modules requiring OCM may fallback to use DDR."
++ default n
++ help
++ If a module cannot get the OCM code it requires allow DDR to
++ be used instead.
++endmenu
++
++config HZ
++ int "Frequency of 'jiffies' (for polling)"
++ default 1000
++ help
++ 100 is common for embedded systems, but 1000 allows
++ you to do more drivers without actually having
++ interrupts working properly.
++
++comment "RAM configuration"
++
++if BRD_32MB
++
++config RAMSIZE
++ hex "Size of RAM (in bytes)"
++ range 0x00000000 0x02000000
++ default "0x02000000"
++ help
++ Define the size of the system RAM. If you select 0 then the
++ kernel will try to probe the RAM size at runtime. This is not
++ supported on all CPU types.
++
++endif
++
++if BRD_64MB
++
++config RAMSIZE
++ hex "Size of RAM (in bytes)"
++ range 0x00000000 0x04000000
++ default "0x04000000"
++ help
++ Define the size of the system RAM. If you select 0 then the
++ kernel will try to probe the RAM size at runtime. This is not
++ supported on all CPU types.
++
++endif
++
++if BRD_128MB
++
++config RAMSIZE
++ hex "Size of RAM (in bytes)"
++ range 0x00000000 0x08000000
++ default "0x08000000"
++ help
++ Define the size of the system RAM. If you select 0 then the
++ kernel will try to probe the RAM size at runtime. This is not
++ supported on all CPU types.
++
++endif
++
++config KERNELBASE
++ hex "Address of the base of kernel code"
++ default "0x40400000"
++ help
++ For the time being we are going to start the Kernel at a 4 meg offset.
++
++comment "Build options"
++config LINKER_RELAXATION
++ bool "Linker Relaxation"
++ default y
++ help
++ Turns on linker relaxation that will produce smaller
++ faster code. Increases link time.
++
++comment "Driver options"
++menu "PCI Bus"
++config PCI
++ bool "PCI bus"
++ default true
++ help
++ Enable/Disable PCI bus
++ source "drivers/pci/Kconfig"
++
++
++config PCI_DEV0_IDSEL
++ hex "slot 0 address"
++ depends on PCI
++ default "0x01000000"
++ help
++ Slot 0 address. This address should correspond to the address line
++ which the IDSEL bit for this slot is connected to.
++
++config PCI_DEV1_IDSEL
++ hex "slot 1 address"
++ depends on PCI
++ default "0x02000000"
++ help
++ Slot 1 address. This address should correspond to the address line
++ which the IDSEL bit for this slot is connected to.
++endmenu
++# End PCI
++
++menu "Input devices"
++config UBICOM_INPUT
++ bool "Ubicom polled GPIO input driver"
++ select INPUT
++ select INPUT_POLLDEV
++ help
++ Polling input driver, much like the GPIO input driver, except that it doesn't
++ rely on interrupts. It will report events via the input subsystem.
++ default n
++
++config UBICOM_INPUT_I2C
++ bool "Ubicom polled GPIO input driver over I2C"
++ select INPUT
++ select INPUT_POLLDEV
++ help
++ Polling input driver, much like the PCA953x driver, it can support a variety of
++ different I2C I/O expanders. This device polls the I2C I/O expander for events
++ and reports them via the input subsystem.
++ default n
++endmenu
++# Input devices
++
++menu "Misc devices"
++config UBICOM_HID
++ bool "Ubicom HID driver"
++ select INPUT
++ select INPUT_POLLDEV
++ select LCD_CLASS_DEVICE
++ help
++ Driver for HID chip found on some Ubicom reference designs. This chip handles
++ PWM, button input, and IR remote control. It registers as an input device and
++ a backlight device.
++ default n
++endmenu
++# Misc devices
++
++config CMDLINE_BOOL
++ bool "Built-in kernel command line"
++ default n
++ help
++ Allow for specifying boot arguments to the kernel at
++ build time. On some systems (e.g. embedded ones), it is
++ necessary or convenient to provide some or all of the
++ kernel boot arguments with the kernel itself (that is,
++ to not rely on the boot loader to provide them.)
++
++ To compile command line arguments into the kernel,
++ set this option to 'Y', then fill in the
++ the boot arguments in CONFIG_CMDLINE.
++
++ Systems with fully functional boot loaders (i.e. non-embedded)
++ should leave this option set to 'N'.
++
++config CMDLINE
++ string "Built-in kernel command string"
++ depends on CMDLINE_BOOL
++ default ""
++ help
++ Enter arguments here that should be compiled into the kernel
++ image and used at boot time. If the boot loader provides a
++ command line at boot time, it is appended to this string to
++ form the full kernel command line, when the system boots.
++
++ However, you can use the CONFIG_CMDLINE_OVERRIDE option to
++ change this behavior.
++
++ In most cases, the command line (whether built-in or provided
++ by the boot loader) should specify the device for the root
++ file system.
++
++config CMDLINE_OVERRIDE
++ bool "Built-in command line overrides boot loader arguments"
++ default n
++ depends on CMDLINE_BOOL
++ help
++ Set this option to 'Y' to have the kernel ignore the boot loader
++ command line, and use ONLY the built-in command line.
++
++ This is used to work around broken boot loaders. This should
++ be set to 'N' under normal conditions.
++
++endmenu
++# End Processor type and features
++
++source "arch/ubicom32/Kconfig.debug"
++
++menu "Executable file formats"
++source "fs/Kconfig.binfmt"
++endmenu
++
++source "init/Kconfig"
++source "kernel/Kconfig.preempt"
++source "kernel/time/Kconfig"
++source "mm/Kconfig"
++source "net/Kconfig"
++source "drivers/Kconfig"
++source "fs/Kconfig"
++source "security/Kconfig"
++source "crypto/Kconfig"
++source "lib/Kconfig"
+--- /dev/null
++++ b/arch/ubicom32/Kconfig.debug
+@@ -0,0 +1,117 @@
++menu "Kernel hacking"
++
++config TRACE_IRQFLAGS_SUPPORT
++ def_bool y
++
++config PROTECT_KERNEL
++ default y
++ bool 'Enable Kernel range register Protection'
++ help
++ Adds code to enable/disable range registers to protect static
++ kernel code/data from userspace. Currently the ranges covered
++ do no protect kernel loadable modules or dynamically allocated
++ kernel data.
++
++config NO_KERNEL_MSG
++ bool "Suppress Kernel BUG Messages"
++ help
++ Do not output any debug BUG messages within the kernel.
++
++config EARLY_PRINTK
++ bool "Use the driver that you selected as console also for early printk (to debug kernel bootup)."
++ default n
++ help
++ If you want to use the serdes driver (console=ttyUS0) for
++ early printk, you must also supply an additional kernel boot
++ parameter like this:
++
++ serdes=ioportaddr,irq,clockrate,baud
++
++ For an IP7160RGW eval board, you could use this:
++
++ serdes=0x2004000,61,250000000,57600
++
++ which will let you see early printk output at 57600 baud.
++
++config STOP_ON_TRAP
++ bool "Enable stopping at the LDSR for all traps"
++ default n
++ help
++ Cause the LDSR to stop all threads whenever a trap is about to be serviced
++
++config STOP_ON_BUG
++ bool "Enable stopping on failed BUG_ON()"
++ default n
++ help
++ Cause all BUG_ON failures to stop all threads
++
++config DEBUG_IRQMEASURE
++ bool "Enable IRQ handler measurements"
++ default n
++ help
++ When enabled each IRQ's min/avg/max times will be printed. If the handler
++ re-enables interrupt, the times will show the full time including to service
++ nested interrupts. See /proc/irq_measurements.
++
++config DEBUG_PCIMEASURE
++ bool "Enable PCI transaction measurements"
++ default n
++ help
++ When enabled the system will measure the min/avg/max timer for each PCI transactions.
++ See /proc/pci_measurements.
++
++config ACCESS_OK_CHECKS_ENABLED
++ bool "Enable user space access checks"
++ default n
++ help
++ Enabling this check causes the kernel to verify that addresses passed
++ to the kernel by the user space code are within the processes
++ address space. On a no-mmu system, this is done by examining the
++ processes memory data structures (adversly affecting performance) but
++ ensuring that a process does not ask the kernel to violate another
++ processes address space. Sadly, the kernel uses access_ok() for
++ address that are in the kernel which results in a large volume of
++ false positives.
++
++choice
++ prompt "Unaligned Access Support"
++ default UNALIGNED_ACCESS_ENABLED
++ help
++ Kernel / Userspace unaligned access handling.
++
++config UNALIGNED_ACCESS_ENABLED
++ bool "Kernel and Userspace"
++ help
++
++config UNALIGNED_ACCESS_USERSPACE_ONLY
++ bool "Userspace Only"
++ help
++
++config UNALIGNED_ACCESS_DISABLED
++ bool "Disabled"
++ help
++
++endchoice
++
++config DEBUG_STACKOVERFLOW
++ bool "Check for stack overflows"
++ default n
++ depends on DEBUG_KERNEL
++ help
++ This option will cause messages to be printed if free kernel stack space
++ drops below a certain limit (THREAD_SIZE /8).
++
++config DEBUG_STACK_USAGE
++ bool "Stack utilization instrumentation"
++ default n
++ depends on DEBUG_KERNEL
++ help
++ Enables the display of the minimum amount of free kernel stack which each
++ task has ever had available in the sysrq-T and sysrq-P debug output.
++
++ This option will slow down process creation somewhat.
++
++source "lib/Kconfig.debug"
++
++endmenu
++
+--- /dev/null
++++ b/arch/ubicom32/kernel/asm-offsets.c
+@@ -0,0 +1,162 @@
++/*
++ * arch/ubicom32/kernel/asm-offsets.c
++ * Ubicom32 architecture definitions needed by assembly language modules.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++/*
++ * This program is used to generate definitions needed by
++ * assembly language modules.
++ *
++ * We use the technique used in the OSF Mach kernel code:
++ * generate asm statements containing #defines,
++ * compile this file to assembler, and then extract the
++ * #defines from the assembly-language output.
++ */
++
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++
++#define DEFINE(sym, val) \
++ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
++
++#define BLANK() asm volatile("\n->" : : )
++
++int main(void)
++{
++ /* offsets into the task struct */
++ DEFINE(TASK_STATE, offsetof(struct task_struct, state));
++ DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
++ DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
++ DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
++ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
++ DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
++ DEFINE(TASK_MM, offsetof(struct task_struct, mm));
++ DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
++
++ /* offsets into the kernel_stat struct */
++ DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
++
++ /* offsets into the irq_cpustat_t struct */
++ DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
++
++ /* offsets into the thread struct */
++ DEFINE(THREAD_D10, offsetof(struct thread_struct, d10));
++ DEFINE(THREAD_D11, offsetof(struct thread_struct, d11));
++ DEFINE(THREAD_D12, offsetof(struct thread_struct, d12));
++ DEFINE(THREAD_D13, offsetof(struct thread_struct, d13));
++ DEFINE(THREAD_A1, offsetof(struct thread_struct, a1));
++ DEFINE(THREAD_A2, offsetof(struct thread_struct, a2));
++ DEFINE(THREAD_A5, offsetof(struct thread_struct, a5));
++ DEFINE(THREAD_A6, offsetof(struct thread_struct, a6));
++ DEFINE(THREAD_SP, offsetof(struct thread_struct, sp));
++
++ /* offsets into the pt_regs */
++ DEFINE(PT_D0, offsetof(struct pt_regs, dn[0]));
++ DEFINE(PT_D1, offsetof(struct pt_regs, dn[1]));
++ DEFINE(PT_D2, offsetof(struct pt_regs, dn[2]));
++ DEFINE(PT_D3, offsetof(struct pt_regs, dn[3]));
++ DEFINE(PT_D4, offsetof(struct pt_regs, dn[4]));
++ DEFINE(PT_D5, offsetof(struct pt_regs, dn[5]));
++ DEFINE(PT_D6, offsetof(struct pt_regs, dn[6]));
++ DEFINE(PT_D7, offsetof(struct pt_regs, dn[7]));
++ DEFINE(PT_D8, offsetof(struct pt_regs, dn[8]));
++ DEFINE(PT_D9, offsetof(struct pt_regs, dn[9]));
++ DEFINE(PT_D10, offsetof(struct pt_regs, dn[10]));
++ DEFINE(PT_D11, offsetof(struct pt_regs, dn[11]));
++ DEFINE(PT_D12, offsetof(struct pt_regs, dn[12]));
++ DEFINE(PT_D13, offsetof(struct pt_regs, dn[13]));
++ DEFINE(PT_D14, offsetof(struct pt_regs, dn[14]));
++ DEFINE(PT_D15, offsetof(struct pt_regs, dn[15]));
++ DEFINE(PT_A0, offsetof(struct pt_regs, an[0]));
++ DEFINE(PT_A1, offsetof(struct pt_regs, an[1]));
++ DEFINE(PT_A2, offsetof(struct pt_regs, an[2]));
++ DEFINE(PT_A3, offsetof(struct pt_regs, an[3]));
++ DEFINE(PT_A4, offsetof(struct pt_regs, an[4]));
++ DEFINE(PT_A5, offsetof(struct pt_regs, an[5]));
++ DEFINE(PT_A6, offsetof(struct pt_regs, an[6]));
++ DEFINE(PT_A7, offsetof(struct pt_regs, an[7]));
++ DEFINE(PT_SP, offsetof(struct pt_regs, an[7]));
++
++ DEFINE(PT_ACC0HI, offsetof(struct pt_regs, acc0[0]));
++ DEFINE(PT_ACC0LO, offsetof(struct pt_regs, acc0[1]));
++ DEFINE(PT_MAC_RC16, offsetof(struct pt_regs, mac_rc16));
++
++ DEFINE(PT_ACC1HI, offsetof(struct pt_regs, acc1[0]));
++ DEFINE(PT_ACC1LO, offsetof(struct pt_regs, acc1[1]));
++
++ DEFINE(PT_SOURCE3, offsetof(struct pt_regs, source3));
++ DEFINE(PT_INST_CNT, offsetof(struct pt_regs, inst_cnt));
++ DEFINE(PT_CSR, offsetof(struct pt_regs, csr));
++ DEFINE(PT_DUMMY_UNUSED, offsetof(struct pt_regs, dummy_unused));
++
++ DEFINE(PT_INT_MASK0, offsetof(struct pt_regs, int_mask0));
++ DEFINE(PT_INT_MASK1, offsetof(struct pt_regs, int_mask1));
++
++ DEFINE(PT_PC, offsetof(struct pt_regs, pc));
++
++ DEFINE(PT_TRAP_CAUSE, offsetof(struct pt_regs, trap_cause));
++
++ DEFINE(PT_SIZE, sizeof(struct pt_regs));
++
++ DEFINE(PT_FRAME_TYPE, offsetof(struct pt_regs, frame_type));
++
++ DEFINE(PT_ORIGINAL_D0, offsetof(struct pt_regs, original_dn_0));
++ DEFINE(PT_PREVIOUS_PC, offsetof(struct pt_regs, previous_pc));
++
++ /* offsets into the kernel_stat struct */
++ DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
++
++ /* signal defines */
++ DEFINE(SIGSEGV, SIGSEGV);
++ //DEFINE(SEGV_MAPERR, SEGV_MAPERR);
++ DEFINE(SIGTRAP, SIGTRAP);
++ //DEFINE(TRAP_TRACE, TRAP_TRACE);
++
++ DEFINE(PT_PTRACED, PT_PTRACED);
++ DEFINE(PT_DTRACE, PT_DTRACE);
++
++ DEFINE(ASM_THREAD_SIZE, THREAD_SIZE);
++
++ /* Offsets in thread_info structure */
++ DEFINE(TI_TASK, offsetof(struct thread_info, task));
++ DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
++ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
++ DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
++ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
++ DEFINE(TI_INTR_NESTING, offsetof(struct thread_info, interrupt_nesting));
++ DEFINE(ASM_TIF_NEED_RESCHED, TIF_NEED_RESCHED);
++ DEFINE(ASM_TIF_SYSCALL_TRACE, TIF_SYSCALL_TRACE);
++ DEFINE(ASM_TIF_SIGPENDING, TIF_SIGPENDING);
++
++ DEFINE(ASM_RAM_END, (CONFIG_RAMBASE + CONFIG_RAMSIZE));
++ return 0;
++}
+--- /dev/null
++++ b/arch/ubicom32/kernel/devtree.c
+@@ -0,0 +1,173 @@
++/*
++ * arch/ubicom32/kernel/devtree.c
++ * Ubicom32 architecture device tree implementation.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++
++#include
++#include
++#include
++#include
++#include
++
++/*
++ * The device tree.
++ */
++struct devtree_node *devtree;
++
++/*
++ * devtree_print()
++ * Print the device tree.
++ */
++void devtree_print(void)
++{
++ struct devtree_node *p = devtree;
++ printk(KERN_INFO "Device Tree:\n");
++ while (p) {
++ if (p->magic != DEVTREE_NODE_MAGIC) {
++ printk(KERN_EMERG
++ "device tree has improper node: %p\n", p);
++ return;
++ }
++ printk(KERN_INFO "\t%p: sendirq=%03d, recvirq=%03d, "
++ " name=%s\n", p, p->sendirq, p->recvirq, p->name);
++ p = p->next;
++ }
++}
++EXPORT_SYMBOL(devtree_print);
++
++/*
++ * devtree_irq()
++ * Return the IRQ(s) associated with devtree node.
++ */
++int devtree_irq(struct devtree_node *dn,
++ unsigned char *sendirq,
++ unsigned char *recvirq)
++{
++ if (dn->magic != DEVTREE_NODE_MAGIC) {
++ printk(KERN_EMERG "improper node: %p\n", dn);
++ if (sendirq) {
++ *sendirq = DEVTREE_IRQ_NONE;
++ }
++ if (recvirq) {
++ *recvirq = DEVTREE_IRQ_NONE;
++ }
++ return -EFAULT;
++ }
++
++ /*
++ * Copy the devtree irq(s) to the output parameters.
++ */
++ if (sendirq) {
++ *sendirq = dn->sendirq;
++ }
++ if (recvirq) {
++ *recvirq = dn->recvirq;
++ }
++ return 0;
++}
++EXPORT_SYMBOL(devtree_irq);
++
++/*
++ * devtree_find_next()
++ * Provide an iterator for walking the device tree.
++ */
++struct devtree_node *devtree_find_next(struct devtree_node **cur)
++{
++ struct devtree_node *p = *cur;
++ if (!p) {
++ *cur = devtree;
++ return devtree;
++ }
++ p = p->next;
++ *cur = p;
++ return p;
++}
++
++/*
++ * devtree_find_by_irq()
++ * Return the node associated with a given irq.
++ */
++struct devtree_node *devtree_find_by_irq(uint8_t sendirq, uint8_t recvirq)
++{
++ struct devtree_node *p = devtree;
++
++ if (sendirq == recvirq) {
++ printk(KERN_EMERG "identical request makes no sense sendirq = "
++ "%d, recvirq= %d\n", sendirq, recvirq);
++ return NULL;
++ }
++
++ while (p) {
++ if (p->magic != DEVTREE_NODE_MAGIC) {
++ printk(KERN_EMERG
++ "device tree has improper node: %p\n", p);
++ return NULL;
++ }
++
++ /*
++ * See if we can find a match on the IRQ(s) specified.
++ */
++ if ((sendirq == p->sendirq) && (recvirq == p->recvirq)) {
++ return p;
++ }
++
++ if ((sendirq == DEVTREE_IRQ_DONTCARE) &&
++ (p->recvirq == recvirq)) {
++ return p;
++ }
++
++ if ((recvirq == DEVTREE_IRQ_DONTCARE) &&
++ (p->sendirq == sendirq)) {
++ return p;
++ }
++
++ p = p->next;
++ }
++ return NULL;
++}
++EXPORT_SYMBOL(devtree_find_by_irq);
++
++/*
++ * devtree_find_node()
++ * Find a node in the device tree by name.
++ */
++struct devtree_node *devtree_find_node(const char *str)
++{
++ struct devtree_node *p = devtree;
++ while (p) {
++ if (p->magic != DEVTREE_NODE_MAGIC) {
++ printk(KERN_EMERG
++ "device tree has improper node: %p\n", p);
++ return NULL;
++ }
++ if (strcmp(p->name, str) == 0) {
++ return p;
++ }
++ p = p->next;
++ }
++ return NULL;
++}
++EXPORT_SYMBOL(devtree_find_node);
+--- /dev/null
++++ b/arch/ubicom32/kernel/dma.c
+@@ -0,0 +1,60 @@
++/*
++ * arch/ubicom32/kernel/dma.c
++ * Ubicom32 architecture dynamic DMA mapping 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ *
++ * We never have any address translations to worry about, so this
++ * is just alloc/free.
++ */
++
++#include
++#include
++#include
++#include
++#include
++
++void *dma_alloc_coherent(struct device *dev, size_t size,
++ dma_addr_t *dma_handle, int gfp)
++{
++ void *ret;
++ /* ignore region specifiers */
++ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
++
++ if (dev == NULL || (*dev->dma_mask < 0xffffffff))
++ gfp |= GFP_DMA;
++ ret = (void *)__get_free_pages(gfp, get_order(size));
++
++ if (ret != NULL) {
++ memset(ret, 0, size);
++ *dma_handle = virt_to_phys(ret);
++ }
++ return ret;
++}
++
++void dma_free_coherent(struct device *dev, size_t size,
++ void *vaddr, dma_addr_t dma_handle)
++{
++ free_pages((unsigned long)vaddr, get_order(size));
++}
+--- /dev/null
++++ b/arch/ubicom32/kernel/flat.c
+@@ -0,0 +1,206 @@
++/*
++ * arch/ubicom32/kernel/flat.c
++ * Ubicom32 architecture flat executable format 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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++
++unsigned long ubicom32_flat_get_addr_from_rp(unsigned long *rp,
++ u32_t relval,
++ u32_t flags,
++ unsigned long *persistent)
++{
++ u32_t relval_reloc_type = relval >> 27;
++ u32_t insn = *rp;
++
++ if (*persistent) {
++ /*
++ * relval holds the relocation that has to be adjusted.
++ */
++ if (relval == 0) {
++ *persistent = 0;
++ }
++
++ return relval;
++ }
++
++ if (relval_reloc_type == R_UBICOM32_32) {
++ /*
++ * insn holds the relocation
++ */
++ return insn;
++ }
++
++ /*
++ * We don't know this one.
++ */
++ return 0;
++}
++
++void ubicom32_flat_put_addr_at_rp(unsigned long *rp,
++ u32_t val,
++ u32_t relval,
++ unsigned long *persistent)
++{
++ u32_t reloc_type = (relval >> 27) & 0x1f;
++ u32_t insn = *rp;
++
++ /*
++ * If persistent is set then it contains the relocation type.
++ */
++ if (*persistent) {
++ /*
++ * If persistent is set then it contains the relocation type.
++ */
++ reloc_type = (*persistent >> 27) & 0x1f;
++ }
++
++ switch (reloc_type) {
++ case R_UBICOM32_32:
++ /*
++ * Store the 32 bits as is.
++ */
++ *rp = val;
++ break;
++ case R_UBICOM32_HI24:
++ {
++ /*
++ * 24 bit relocation that is part of the MOVEAI
++ * instruction. The 24 bits come from bits 7 - 30 of the
++ * relocation. The 24 bits eventually get split into 2
++ * fields in the instruction encoding.
++ *
++ * - Bits 7 - 27 of the relocation are encoded into bits
++ * 0 - 20 of the instruction.
++ *
++ * - Bits 28 - 30 of the relocation are encoded into bit
++ * 24 - 26 of the instruction.
++ */
++ u32_t mask = 0x1fffff | (0x7 << 24);
++ u32_t valid24bits = (val >> 7) & 0xffffff;
++ u32_t bot_21 = valid24bits & 0x1fffff;
++ u32_t upper_3_bits = ((valid24bits & 0xe00000) << 3);
++ insn &= ~mask;
++
++ insn |= bot_21;
++ insn |= upper_3_bits;
++ *rp = insn;
++ }
++ break;
++ case R_UBICOM32_LO7_S:
++ case R_UBICOM32_LO7_2_S:
++ case R_UBICOM32_LO7_4_S:
++ {
++ /*
++ * Bits 0 - 6 of the relocation are encoded into the
++ * 7bit unsigned immediate fields of the SOURCE-1 field
++ * of the instruction. The immediate value is left
++ * shifted by (0, 1, 2) based on the operand size.
++ */
++ u32_t mask = 0x1f | (0x3 << 8);
++ u32_t bottom, top;
++ val &= 0x7f;
++ if (reloc_type == R_UBICOM32_LO7_2_S) {
++ val >>= 1;
++ } else if (reloc_type == R_UBICOM32_LO7_4_S) {
++ val >>= 2;
++ }
++
++ bottom = val & 0x1f;
++ top = val >> 5;
++ insn &= ~mask;
++ insn |= bottom;
++ insn |= (top << 8);
++ BUG_ON(*rp != insn);
++ *rp = insn;
++ break;
++ }
++ case R_UBICOM32_LO7_D:
++ case R_UBICOM32_LO7_2_D:
++ case R_UBICOM32_LO7_4_D:
++ {
++ /*
++ * Bits 0 - 6 of the relocation are encoded into the
++ * 7bit unsigned immediate fields of the DESTINATION
++ * field of the instruction. The immediate value is
++ * left shifted by (0, 1, 2) based on the operand size.
++ */
++ u32_t mask = (0x1f | (0x3 << 8)) << 16;
++ u32_t bottom, top;
++ val &= 0x7f;
++ if (reloc_type == R_UBICOM32_LO7_2_D) {
++ val >>= 1;
++ } else if (reloc_type == R_UBICOM32_LO7_4_D) {
++ val >>= 2;
++ }
++ bottom = (val & 0x1f) << 16;
++ top = (val >> 5) << 16;
++ insn &= ~mask;
++ insn |= bottom;
++ insn |= (top << 8);
++ BUG_ON(*rp != insn);
++ *rp = insn;
++ break;
++ }
++ case R_UBICOM32_LO7_CALLI:
++ case R_UBICOM32_LO16_CALLI:
++ {
++ /*
++ * Extract the offset for a CALLI instruction. The
++ * offsets can be either 7 bits or 18 bits. Since all
++ * instructions in ubicom32 architecture are at work
++ * aligned addresses the truncated offset is right
++ * shifted by 2 before being encoded in the instruction.
++ */
++ if (reloc_type == R_UBICOM32_LO7_CALLI) {
++ val &= 0x7f;
++ } else {
++ val &= 0x3ffff;
++ }
++
++ val >>= 2;
++
++ insn &= ~0x071f071f;
++ insn |= (val & 0x1f) << 0;
++ val >>= 5;
++ insn |= (val & 0x07) << 8;
++ val >>= 3;
++ insn |= (val & 0x1f) << 16;
++ val >>= 5;
++ insn |= (val & 0x07) << 24;
++ if (reloc_type == R_UBICOM32_LO7_CALLI) {
++ BUG_ON(*rp != insn);
++ }
++ *rp = insn;
++ }
++ break;
++ }
++
++ if (*persistent) {
++ *persistent = 0;
++ }
++}
+--- /dev/null
++++ b/arch/ubicom32/kernel/head.S
+@@ -0,0 +1,247 @@
++/*
++ * arch/ubicom32/kernel/head.S
++ *
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++#include
++#define __ASM__
++#include
++
++
++#define SRC_AN A3
++#define DST_AN A4
++
++#define PARAM_DN D0
++#define TMP_DN D15
++#define TMP2_DN D14
++
++/*
++ * The following code is placed at the start of the Linux section of memory.
++ * This is the primary entry point for Linux.
++ *
++ * However, we also want the syscall entry/exit code to be at a fixed address.
++ * So we take the primary entry point and reserve 16 bytes. That address is
++ * where the system_call entry point exists. This 16 bytes basically allows
++ * us to jump around the system_call entry point code to the actual startup
++ * code.
++ *
++ * Linux Memory Map (see vlinux.lds.S):
++ * 0x40400000 - Primary Entry Point for Linux (jump around code below).
++ * 0x40400010 - Syscall Entry Point.
++ */
++
++ .sect .skip_syscall, "ax", @progbits
++ .global __skip_syscall_section
++__skip_syscall_section:
++ moveai A3, #%hi(_start)
++ lea.1 A3, %lo(_start)(A3)
++ ret A3
++/*
++ * __os_node_offset contains the offset from KERNELBASE to the os_node, it is
++ * not intended to be used by anything except the boot code.
++ */
++__os_node_offset:
++.long (_os_node - CONFIG_KERNELBASE)
++
++.text
++.global _start
++
++/*
++ * start()
++ * This is the start of the Linux kernel.
++ */
++_start:
++ move.4 SCRATCHPAD1, #0
++
++
++/*
++ * Setup the range registers... the loader has setup a few, but we will go ahead
++ * and correct them for our own limits. Note that once set these are never
++ * changed again. The ranges are as follows
++ *
++ * D_RANGE0 - io block (set up by loaded)
++ *
++ * I_RANGE0 and D_RANGE1 - kernel/ultra loader address space bottom of ocm-> top
++ * of ram typically 0x3ffc0000 - 0x440000000
++ * I_RANGE1 - kernel / userspace transition area (aka syscalls, context switches)
++ * typically 0x40400000 - ~0x40400400
++ * I_RANGE2 / D_RANGE2 - slab area
++ * typically 0x40A00000 - ~0x44000000
++ *
++ * I_RANGE4, D_RANGE3, D_RANGE3 - unused.
++ */
++ moveai SRC_AN, #%hi(PAGE_OFFSET_RAW)
++ lea.4 SRC_AN, %lo(PAGE_OFFSET_RAW)(SRC_AN)
++ move.4 D_RANGE1_LO, SRC_AN
++ move.4 I_RANGE0_LO, SRC_AN
++
++; don't try to calculate I_RANGE_HI, see below
++; moveai SRC_AN, #%hi(___init_end-4)
++; lea.4 SRC_AN, %lo(___init_end-4)(SRC_AN)
++; move.4 I_RANGE0_HI, SRC_AN
++
++ moveai SRC_AN, #%hi(CONFIG_RAMBASE+CONFIG_RAMSIZE-4)
++ lea.4 SRC_AN, %lo(CONFIG_RAMBASE+CONFIG_RAMSIZE-4)(SRC_AN)
++ move.4 D_RANGE1_HI, SRC_AN
++
++; for now allow the whole ram to be executable as well so we don't run into problems
++; once we load user more code.
++ move.4 I_RANGE0_HI, SRC_AN
++
++#ifdef CONFIG_PROTECT_KERNEL
++; when kernel protection is enabled, we only open up syscall and non kernel text
++; for userspace apps, for now only irange registers registers 1 and 2 are used for userspace.
++
++ ;; syscall range
++ moveai SRC_AN, #%hi(_begin)
++ lea.4 SRC_AN, %lo(_begin)(SRC_AN)
++ move.4 I_RANGE1_LO, SRC_AN
++ moveai SRC_AN, #%hi(__fixed_text_end)
++ lea.4 SRC_AN, %lo(__fixed_text_end)(SRC_AN)
++ move.4 I_RANGE1_HI, SRC_AN
++
++ ;; slab instructions
++ moveai SRC_AN, #%hi(_edata)
++ lea.4 SRC_AN, %lo(_edata)(SRC_AN)
++ move.4 I_RANGE2_LO, SRC_AN
++ ;; End of DDR is already in range0 hi so just copy it.
++ move.4 I_RANGE2_HI, I_RANGE0_HI
++
++ ;; slab data (same as slab instructions but starting a little earlier).
++ moveai SRC_AN, #%hi(_data_protection_end)
++ lea.4 SRC_AN, %lo(_data_protection_end)(SRC_AN)
++ move.4 D_RANGE2_LO, SRC_AN
++ move.4 D_RANGE2_HI, I_RANGE0_HI
++
++;; enable ranges
++ ;; skip I_RANGE0_EN
++ move.4 I_RANGE1_EN, #-1
++ move.4 I_RANGE2_EN, #-1
++ move.4 I_RANGE3_EN, #0
++
++ ;; skip D_RANGE0_EN or D_RANGE1_EN
++ move.4 D_RANGE2_EN, #-1
++ move.4 D_RANGE3_EN, #0
++ move.4 D_RANGE4_EN, #0
++#endif
++
++;
++; If __ocm_free_begin is smaller than __ocm_free_end the
++; setup OCM text and data ram banks properly
++;
++ moveai DST_AN, #%hi(__ocm_free_begin)
++ lea.4 TMP_DN, %lo(__ocm_free_begin)(DST_AN)
++ moveai DST_AN, #%hi(__ocm_free_end)
++ lea.4 TMP2_DN, %lo(__ocm_free_end)(DST_AN)
++ sub.4 #0, TMP2_DN, TMP_DN
++ jmple.f 2f
++ moveai DST_AN, #%hi(__data_begin)
++ lea.4 TMP_DN, %lo(__data_begin)(DST_AN)
++ moveai DST_AN, #%hi(OCMSTART)
++ lea.4 TMP2_DN, %lo(OCMSTART)(DST_AN)
++ sub.4 TMP_DN, TMP_DN, TMP2_DN
++ lsr.4 TMP_DN, TMP_DN, #15
++ lsl.4 TMP_DN, #1, TMP_DN
++ moveai DST_AN, #%hi(OCMC_BASE)
++ add.4 OCMC_BANK_MASK(DST_AN), #-1, TMP_DN
++ pipe_flush 0
++2:
++;
++; Load .ocm_text
++;
++ moveai DST_AN, #%hi(__ocm_text_run_end)
++ lea.4 TMP_DN, %lo(__ocm_text_run_end)(DST_AN)
++ moveai DST_AN, #%hi(__ocm_text_run_begin)
++ lea.4 DST_AN, %lo(__ocm_text_run_begin)(DST_AN)
++ moveai SRC_AN, #%hi(__ocm_text_load_begin)
++ lea.4 SRC_AN, %lo(__ocm_text_load_begin)(SRC_AN)
++ jmpt.t 2f
++
++1: move.4 (DST_AN)4++, (SRC_AN)4++
++
++2: sub.4 #0, DST_AN, TMP_DN
++ jmpne.t 1b
++
++;
++; Load .ocm_data
++;
++ moveai DST_AN, #%hi(__ocm_data_run_end)
++ lea.4 TMP_DN, %lo(__ocm_data_run_end)(DST_AN)
++ moveai DST_AN, #%hi(__ocm_data_run_begin)
++ lea.4 DST_AN, %lo(__ocm_data_run_begin)(DST_AN)
++ moveai SRC_AN, #%hi(__ocm_data_load_begin)
++ lea.4 SRC_AN, %lo(__ocm_data_load_begin)(SRC_AN)
++ jmpt.t 2f
++
++1: move.4 (DST_AN)4++, (SRC_AN)4++
++
++2: sub.4 #0, DST_AN, TMP_DN
++ jmpne.t 1b
++
++; Clear .bss
++;
++ moveai SRC_AN, #%hi(_ebss)
++ lea.4 TMP_DN, %lo(_ebss)(SRC_AN)
++ moveai DST_AN, #%hi(_sbss)
++ lea.4 DST_AN, %lo(_sbss)(DST_AN)
++ jmpt.t 2f
++
++1: move.4 (DST_AN)4++, #0
++
++2: sub.4 #0, DST_AN, TMP_DN
++ jmpne.t 1b
++
++; save our parameter to devtree (after clearing .bss)
++ moveai DST_AN, #%hi(devtree)
++ lea.4 DST_AN, %lo(devtree)(DST_AN)
++ move.4 (DST_AN), PARAM_DN
++
++ moveai sp, #%hi(init_thread_union)
++ lea.4 sp, %lo(init_thread_union)(sp)
++ movei TMP_DN, #ASM_THREAD_SIZE
++ add.4 sp, sp, TMP_DN
++ move.4 -4(sp)++, #0 ; nesting level = 0
++ move.4 -4(sp)++, #1 ; KERNEL_THREAD
++
++;; ip3k-elf-gdb backend now sets scratchpad3 to 1 when either continue
++;; or single step commands are issued. scratchpad3 is set to 0 when the
++;; debugger detaches from the board.
++ move.4 TMP_DN, scratchpad3
++ lsl.4 TMP_DN, TMP_DN, #0x0
++ jmpeq.f _jump_to_start_kernel
++_ok_to_set_break_points_in_linux:
++;; THREAD_STALL
++ move.4 mt_dbg_active_clr,#-1
++;; stalling the threads isn't instantaneous.. need to flush the pipe.
++ pipe_flush 0
++ pipe_flush 0
++
++_jump_to_start_kernel:
++ moveai SRC_AN, #%hi(start_kernel)
++ lea.4 SRC_AN, %lo(start_kernel)(SRC_AN)
++ ret SRC_AN
+--- /dev/null
++++ b/arch/ubicom32/kernel/init_task.c
+@@ -0,0 +1,62 @@
++/*
++ * arch/ubicom32/kernel/init_task.c
++ * Ubicom32 architecture task initialization implementation.
++ *
++ * (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 .
++ *
++ * Ubicom32 implementation derived from (with many thanks):
++ * arch/m68knommu
++ * arch/blackfin
++ * arch/parisc
++ */
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++
++static struct fs_struct init_fs = INIT_FS;
++static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
++struct mm_struct init_mm = INIT_MM(init_mm);
++EXPORT_SYMBOL(init_mm);
++
++/*
++ * Initial task structure.
++ *
++ * All other task structs will be allocated on slabs in fork.c
++ */
++struct task_struct init_task = INIT_TASK(init_task);
++
++EXPORT_SYMBOL(init_task);
++
++/*
++ * Initial thread structure.
++ *
++ * We need to make sure that this is 8192-byte aligned due to the
++ * way process stacks are handled. This is done by having a special
++ * "init_task" linker map entry..
++ */
++union thread_union init_thread_union
++ __attribute__((__section__(".data.init_task"))) =
++ { INIT_THREAD_INFO(init_task) };
+--- /dev/null
++++ b/arch/ubicom32/kernel/irq.c
+@@ -0,0 +1,596 @@
++/*
++ * arch/ubicom32/kernel/irq.c
++ * Ubicom32 architecture IRQ support.
++ *
++ * (C) Copyright 2009, Ubicom, Inc.
++ * (C) Copyright 2007, Greg Ungerer
++ *
++ * 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