aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Sledz <sledz@dresearch.de>2010-01-15 08:24:34 +0100
committerSteffen Sledz <sledz@dresearch.de>2010-01-15 08:26:26 +0100
commit61f3b32f0aa16d051afb4c8a82ee7b8e86fd753b (patch)
tree171d91904566eb593c3b1456edf0d4b2b046d54c
parent04e3f04a8c6cedaf20a45a568f969129ded21ec2 (diff)
downloadopenembedded-61f3b32f0aa16d051afb4c8a82ee7b8e86fd753b.tar.gz
linux_2.6.24: secure NAND access against PCI activity at hipox machine
Signed-off-by: Steffen Sledz <sledz@dresearch.de>
-rw-r--r--recipes/linux/linux-2.6.24/hipox/hipox-nand-vs-pci.patch212
-rw-r--r--recipes/linux/linux_2.6.24.bb1
2 files changed, 213 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 */
diff --git a/recipes/linux/linux_2.6.24.bb b/recipes/linux/linux_2.6.24.bb
index c4549795d6..8176df5a70 100644
--- a/recipes/linux/linux_2.6.24.bb
+++ b/recipes/linux/linux_2.6.24.bb
@@ -106,6 +106,7 @@ SRC_URI_append_hipox = " \
file://hipox-sata-module.patch;patch=1 \
file://hipox-OXE-INT2.patch;patch=1 \
file://hipox-rtc.patch;patch=1 \
+ file://hipox-nand-vs-pci.patch;patch=1 \
"
EXTRA_OEMAKE_smartq5 = " OBJCOPY=${OBJCOPY}"