diff options
author | Steffen Sledz <sledz@dresearch.de> | 2010-01-15 08:24:34 +0100 |
---|---|---|
committer | Steffen Sledz <sledz@dresearch.de> | 2010-01-15 08:26:26 +0100 |
commit | 61f3b32f0aa16d051afb4c8a82ee7b8e86fd753b (patch) | |
tree | 171d91904566eb593c3b1456edf0d4b2b046d54c /recipes/linux/linux-2.6.24 | |
parent | 04e3f04a8c6cedaf20a45a568f969129ded21ec2 (diff) |
linux_2.6.24: secure NAND access against PCI activity at hipox machine
Signed-off-by: Steffen Sledz <sledz@dresearch.de>
Diffstat (limited to 'recipes/linux/linux-2.6.24')
-rw-r--r-- | recipes/linux/linux-2.6.24/hipox/hipox-nand-vs-pci.patch | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/recipes/linux/linux-2.6.24/hipox/hipox-nand-vs-pci.patch b/recipes/linux/linux-2.6.24/hipox/hipox-nand-vs-pci.patch new file mode 100644 index 0000000000..a56e20db05 --- /dev/null +++ b/recipes/linux/linux-2.6.24/hipox/hipox-nand-vs-pci.patch @@ -0,0 +1,212 @@ +diff -Nurd linux-2.6.24.orig//drivers/mtd/nand/hipox_nand.c linux-2.6.24/drivers/mtd/nand/hipox_nand.c +--- linux-2.6.24.orig//drivers/mtd/nand/hipox_nand.c 2010-01-08 10:57:15.000000000 +0100 ++++ linux-2.6.24/drivers/mtd/nand/hipox_nand.c 2010-01-08 10:58:33.000000000 +0100 +@@ -21,6 +21,7 @@ + #include <linux/mtd/nand.h> + #include <linux/mtd/partitions.h> + #include <linux/delay.h> ++#include <linux/jiffies.h> + #include <asm/io.h> + #include <asm/arch/hardware.h> + #include <asm/sizes.h> +@@ -58,9 +59,52 @@ + }; + #endif + ++static unsigned int timestamp = 0; ++/* ++ * Request PCI_ARB to grant access to the STATIC core. ++ */ ++static void request_bus(void) ++{ ++ unsigned maxtries = 10; /* wait for maxtries jiffies at maximum */ ++ ++ /* set PCI_ARB request bit in Sysctrl_PCI_Ctrl1 */ ++ writel(readl(SYS_CTRL_PCI_CTRL1) | (1UL << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ), SYS_CTRL_PCI_CTRL1); ++ ++ /* check if STATIC core has been granted access to the PCI bus ++ and can use PCI_AD[31:0] pins */ ++ for (;maxtries > 0; maxtries--) ++ { ++ if (readl(SYS_CTRL_PCI_STAT) & (1UL << SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT)) ++ break; ++ udelay(10); ++ } ++ ++ /* check for timeout granting access */ ++ if (!(readl(SYS_CTRL_PCI_STAT) & (1UL << SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT))) ++ printk(KERN_WARNING "%s: timeout requesting access to PCI bus for static memory interface\n", __func__); ++ ++ timestamp = jiffies_to_msecs(get_jiffies_64()); ++} + + /* +- * hardware specific access to control-lines ++ * Release access to PCI bus. ++ */ ++static void release_bus(void) ++{ ++ const unsigned int timeout = 100; /* ms */ ++ unsigned int delta = jiffies_to_msecs(get_jiffies_64()) - timestamp; ++ ++ /* set PCI_ARB request bit in Sysctrl_PCI_Ctrl1 */ ++ writel(readl(SYS_CTRL_PCI_CTRL1) & ~(1UL << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ), SYS_CTRL_PCI_CTRL1); ++ ++ if (delta > timeout) ++ { ++ printk(KERN_WARNING "%s: static memory interface blocked PCI bus for %u ms\n", __func__, delta); ++ } ++} ++ ++/* ++ * Hardware specific access to control-lines + */ + static void hipox_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) + { +@@ -85,30 +129,110 @@ + } + + if (cmd != NAND_CMD_NONE) ++ { ++ request_bus(); + writeb(cmd, this->IO_ADDR_W); ++ release_bus(); ++ } + } + +-static void hipox_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ++/** ++ * hipox_nand_read_byte - read one byte from the chip ++ * @mtd: MTD device structure ++ * ++ * Read function for 8bit buswith ++ */ ++static uint8_t hipox_nand_read_byte(struct mtd_info *mtd) + { +- struct nand_chip *chip = mtd->priv; +- volatile uint8_t *io = chip->IO_ADDR_R; ++ struct nand_chip *chip = mtd->priv; ++ uint8_t res; ++ request_bus(); ++ res = readb(chip->IO_ADDR_R); ++ release_bus(); ++ return res; ++} + +- if((((int)buf) & 1) || (len & 1)) +- { +- while(len-- > 0) +- *buf++ = *io; ++/** ++ * hipox_nand_read_word - read one word from the chip ++ * @mtd: MTD device structure ++ * ++ * Read function for 16bit buswith without ++ * endianess conversion ++ */ ++static u16 hipox_nand_read_word(struct mtd_info *mtd) ++{ ++ struct nand_chip *chip = mtd->priv; ++ u16 res; ++ request_bus(); ++ res = readw(chip->IO_ADDR_R); ++ release_bus(); ++ return res; ++} + +- return; +- } ++/** ++ * hipox_nand_read_buf - read chip data into buffer ++ * @mtd: MTD device structure ++ * @buf: buffer to store date ++ * @len: number of bytes to read ++ * ++ * Read function for 8bit buswith ++ */ ++static void hipox_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) ++{ ++ int i; ++ struct nand_chip *chip = mtd->priv; + +- // now it's aligned, group to 16 bit access ++ request_bus(); ++ for (i = 0; i < len; i++) ++ buf[i] = readb(chip->IO_ADDR_R); ++ release_bus(); ++} ++ ++/** ++ * hipox_nand_write_buf - write buffer to chip ++ * @mtd: MTD device structure ++ * @buf: data buffer ++ * @len: number of bytes to write ++ * ++ * Write function for 8bit buswith ++ */ ++static void hipox_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) ++{ ++ int i; ++ struct nand_chip *chip = mtd->priv; ++ ++ request_bus(); ++ for (i = 0; i < len; i++) ++ writeb(buf[i], chip->IO_ADDR_W); ++ release_bus(); ++} ++ ++/** ++ * hipox_nand_verify_buf - Verify chip data against buffer ++ * @mtd: MTD device structure ++ * @buf: buffer containing the data to compare ++ * @len: number of bytes to compare ++ * ++ * Verify function for 8bit buswith ++ */ ++static int hipox_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) ++{ ++ int i; ++ int ret = 0; ++ struct nand_chip *chip = mtd->priv; ++ ++ request_bus(); ++ for (i = 0; i < len; i++) + { +- uint16_t *ptr16 = (uint16_t *)buf; +- len >>= 1; +- +- while(len-- > 0) +- *ptr16++ = *io | (*io << 8); ++ if (buf[i] != readb(chip->IO_ADDR_R)) ++ { ++ ret = 0; ++ break; ++ } + } ++ release_bus(); ++ ++ return ret; + } + + /* +@@ -175,10 +299,18 @@ + /* insert callbacks */ + this->IO_ADDR_R = (void *)CONFIG_SYS_NAND_BASE; + this->IO_ADDR_W = (void *)CONFIG_SYS_NAND_BASE; +- this->cmd_ctrl = hipox_nand_hwcontrol; +- this->read_buf = hipox_read_buf; + this->chip_delay = 25; // 23 still worked on our EvalBoard + this->ecc.mode = NAND_ECC_SOFT; ++ /* we overwrite these funcs because we need a special lock ++ handling for use of data pins shared between PCI and ++ static memory interface of OXE810 cpu */ ++ this->cmd_ctrl = hipox_nand_hwcontrol; ++ this->read_byte = hipox_nand_read_byte; ++ this->read_word = hipox_nand_read_word; ++ this->read_buf = hipox_nand_read_buf; ++ this->write_buf = hipox_nand_write_buf; ++ this->verify_buf = hipox_nand_verify_buf; ++ + printk("Searching for NAND flash...\n"); + + /* Scan to find existence of the device */ |