From e29c22f5abe6e0f4baa6251efed6074cdfc3db79 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:20:36 +0100 Subject: MTD: Add MTD paritioning infrastructure This MTD part infrastructure will be used by the upcoming UBI support. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- drivers/mtd/Makefile | 1 + drivers/mtd/mtdcore.c | 146 ++++++++++++++ drivers/mtd/mtdpart.c | 532 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 679 insertions(+) create mode 100644 drivers/mtd/mtdcore.c create mode 100644 drivers/mtd/mtdpart.c diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 6538f7a..d225a68 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmtd.a +COBJS-$(CONFIG_CMD_UBI) += mtdcore.o mtdpart.o COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c new file mode 100644 index 0000000..64bd7d4 --- /dev/null +++ b/drivers/mtd/mtdcore.c @@ -0,0 +1,146 @@ +/* + * Core registration and callback routines for MTD + * drivers and users. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +struct mtd_info *mtd_table[MAX_MTD_DEVICES]; + +int add_mtd_device(struct mtd_info *mtd) +{ + int i; + + BUG_ON(mtd->writesize == 0); + + for (i = 0; i < MAX_MTD_DEVICES; i++) + if (!mtd_table[i]) { + mtd_table[i] = mtd; + mtd->index = i; + mtd->usecount = 0; + + printf("mtd: Giving out device %d to %s\n", + i, mtd->name); + /* No need to get a refcount on the module containing + the notifier, since we hold the mtd_table_mutex */ + + /* We _know_ we aren't being removed, because + our caller is still holding us here. So none + of this try_ nonsense, and no bitching about it + either. :) */ + return 0; + } + + return 1; +} + +/** + * del_mtd_device - unregister an MTD device + * @mtd: pointer to MTD device info structure + * + * Remove a device from the list of MTD devices present in the system, + * and notify each currently active MTD 'user' of its departure. + * Returns zero on success or 1 on failure, which currently will happen + * if the requested device does not appear to be present in the list. + */ +int del_mtd_device(struct mtd_info *mtd) +{ + int ret; + + if (mtd_table[mtd->index] != mtd) { + ret = -ENODEV; + } else if (mtd->usecount) { + printk(KERN_NOTICE "Removing MTD device #%d (%s)" + " with use count %d\n", + mtd->index, mtd->name, mtd->usecount); + ret = -EBUSY; + } else { + /* No need to get a refcount on the module containing + * the notifier, since we hold the mtd_table_mutex */ + mtd_table[mtd->index] = NULL; + + ret = 0; + } + + return ret; +} + +/** + * get_mtd_device - obtain a validated handle for an MTD device + * @mtd: last known address of the required MTD device + * @num: internal device number of the required MTD device + * + * Given a number and NULL address, return the num'th entry in the device + * table, if any. Given an address and num == -1, search the device table + * for a device with that address and return if it's still present. Given + * both, return the num'th driver only if its address matches. Return + * error code if not. + */ +struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) +{ + struct mtd_info *ret = NULL; + int i, err = -ENODEV; + + if (num == -1) { + for (i = 0; i < MAX_MTD_DEVICES; i++) + if (mtd_table[i] == mtd) + ret = mtd_table[i]; + } else if (num < MAX_MTD_DEVICES) { + ret = mtd_table[num]; + if (mtd && mtd != ret) + ret = NULL; + } + + if (!ret) + goto out_unlock; + + ret->usecount++; + return ret; + +out_unlock: + return ERR_PTR(err); +} + +/** + * get_mtd_device_nm - obtain a validated handle for an MTD device by + * device name + * @name: MTD device name to open + * + * This function returns MTD device description structure in case of + * success and an error code in case of failure. + */ +struct mtd_info *get_mtd_device_nm(const char *name) +{ + int i, err = -ENODEV; + struct mtd_info *mtd = NULL; + + for (i = 0; i < MAX_MTD_DEVICES; i++) { + if (mtd_table[i] && !strcmp(name, mtd_table[i]->name)) { + mtd = mtd_table[i]; + break; + } + } + + if (!mtd) + goto out_unlock; + + mtd->usecount++; + return mtd; + +out_unlock: + return ERR_PTR(err); +} + +void put_mtd_device(struct mtd_info *mtd) +{ + int c; + + c = --mtd->usecount; + BUG_ON(c < 0); +} diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c new file mode 100644 index 0000000..9a3bf6f --- /dev/null +++ b/drivers/mtd/mtdpart.c @@ -0,0 +1,532 @@ +/* + * Simple MTD partitioning layer + * + * (C) 2000 Nicolas Pitre + * + * This code is GPL + * + * 02-21-2002 Thomas Gleixner + * added support for read_oob, write_oob + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Our partition linked list */ +static LIST_HEAD(mtd_partitions); + +/* Our partition node structure */ +struct mtd_part { + struct mtd_info mtd; + struct mtd_info *master; + u_int32_t offset; + int index; + struct list_head list; + int registered; +}; + +/* + * Given a pointer to the MTD object in the mtd_part structure, we can retrieve + * the pointer to that structure with this macro. + */ +#define PART(x) ((struct mtd_part *)(x)) + + +/* + * MTD methods which simply translate the effective address and pass through + * to the _real_ device. + */ + +static int part_read (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct mtd_part *part = PART(mtd); + int res; + + if (from >= mtd->size) + len = 0; + else if (from + len > mtd->size) + len = mtd->size - from; + res = part->master->read (part->master, from + part->offset, + len, retlen, buf); + if (unlikely(res)) { + if (res == -EUCLEAN) + mtd->ecc_stats.corrected++; + if (res == -EBADMSG) + mtd->ecc_stats.failed++; + } + return res; +} + +#ifdef MTD_LINUX +static int part_point (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys) +{ + struct mtd_part *part = PART(mtd); + if (from >= mtd->size) + len = 0; + else if (from + len > mtd->size) + len = mtd->size - from; + return part->master->point (part->master, from + part->offset, + len, retlen, virt, phys); +} + +static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +{ + struct mtd_part *part = PART(mtd); + + part->master->unpoint(part->master, from + part->offset, len); +} +#endif + +static int part_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) +{ + struct mtd_part *part = PART(mtd); + int res; + + if (from >= mtd->size) + return -EINVAL; + if (ops->datbuf && from + ops->len > mtd->size) + return -EINVAL; + res = part->master->read_oob(part->master, from + part->offset, ops); + + if (unlikely(res)) { + if (res == -EUCLEAN) + mtd->ecc_stats.corrected++; + if (res == -EBADMSG) + mtd->ecc_stats.failed++; + } + return res; +} + +static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct mtd_part *part = PART(mtd); + return part->master->read_user_prot_reg (part->master, from, + len, retlen, buf); +} + +static int part_get_user_prot_info (struct mtd_info *mtd, + struct otp_info *buf, size_t len) +{ + struct mtd_part *part = PART(mtd); + return part->master->get_user_prot_info (part->master, buf, len); +} + +static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct mtd_part *part = PART(mtd); + return part->master->read_fact_prot_reg (part->master, from, + len, retlen, buf); +} + +static int part_get_fact_prot_info (struct mtd_info *mtd, + struct otp_info *buf, size_t len) +{ + struct mtd_part *part = PART(mtd); + return part->master->get_fact_prot_info (part->master, buf, len); +} + +static int part_write (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (to >= mtd->size) + len = 0; + else if (to + len > mtd->size) + len = mtd->size - to; + return part->master->write (part->master, to + part->offset, + len, retlen, buf); +} + +#ifdef MTD_LINUX +static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (to >= mtd->size) + len = 0; + else if (to + len > mtd->size) + len = mtd->size - to; + return part->master->panic_write (part->master, to + part->offset, + len, retlen, buf); +} +#endif + +static int part_write_oob(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) +{ + struct mtd_part *part = PART(mtd); + + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + + if (to >= mtd->size) + return -EINVAL; + if (ops->datbuf && to + ops->len > mtd->size) + return -EINVAL; + return part->master->write_oob(part->master, to + part->offset, ops); +} + +static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct mtd_part *part = PART(mtd); + return part->master->write_user_prot_reg (part->master, from, + len, retlen, buf); +} + +static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) +{ + struct mtd_part *part = PART(mtd); + return part->master->lock_user_prot_reg (part->master, from, len); +} + +#ifdef MTD_LINUX +static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, + unsigned long count, loff_t to, size_t *retlen) +{ + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + return part->master->writev (part->master, vecs, count, + to + part->offset, retlen); +} +#endif + +static int part_erase (struct mtd_info *mtd, struct erase_info *instr) +{ + struct mtd_part *part = PART(mtd); + int ret; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (instr->addr >= mtd->size) + return -EINVAL; + instr->addr += part->offset; + ret = part->master->erase(part->master, instr); + if (ret) { + if (instr->fail_addr != 0xffffffff) + instr->fail_addr -= part->offset; + instr->addr -= part->offset; + } + return ret; +} + +void mtd_erase_callback(struct erase_info *instr) +{ + if (instr->mtd->erase == part_erase) { + struct mtd_part *part = PART(instr->mtd); + + if (instr->fail_addr != 0xffffffff) + instr->fail_addr -= part->offset; + instr->addr -= part->offset; + } + if (instr->callback) + instr->callback(instr); +} +#ifdef MTD_LINUX +EXPORT_SYMBOL_GPL(mtd_erase_callback); +#endif + +#ifdef MTD_LINUX +static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) +{ + struct mtd_part *part = PART(mtd); + if ((len + ofs) > mtd->size) + return -EINVAL; + return part->master->lock(part->master, ofs + part->offset, len); +} + +static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) +{ + struct mtd_part *part = PART(mtd); + if ((len + ofs) > mtd->size) + return -EINVAL; + return part->master->unlock(part->master, ofs + part->offset, len); +} +#endif + +static void part_sync(struct mtd_info *mtd) +{ + struct mtd_part *part = PART(mtd); + part->master->sync(part->master); +} + +#ifdef MTD_LINUX +static int part_suspend(struct mtd_info *mtd) +{ + struct mtd_part *part = PART(mtd); + return part->master->suspend(part->master); +} + +static void part_resume(struct mtd_info *mtd) +{ + struct mtd_part *part = PART(mtd); + part->master->resume(part->master); +} +#endif + +static int part_block_isbad (struct mtd_info *mtd, loff_t ofs) +{ + struct mtd_part *part = PART(mtd); + if (ofs >= mtd->size) + return -EINVAL; + ofs += part->offset; + return part->master->block_isbad(part->master, ofs); +} + +static int part_block_markbad (struct mtd_info *mtd, loff_t ofs) +{ + struct mtd_part *part = PART(mtd); + int res; + + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (ofs >= mtd->size) + return -EINVAL; + ofs += part->offset; + res = part->master->block_markbad(part->master, ofs); +#ifdef MTD_LINUX + if (!res) + mtd->ecc_stats.badblocks++; +#endif + return res; +} + +/* + * This function unregisters and destroy all slave MTD objects which are + * attached to the given master MTD object. + */ + +int del_mtd_partitions(struct mtd_info *master) +{ + struct list_head *node; + struct mtd_part *slave; + + for (node = mtd_partitions.next; + node != &mtd_partitions; + node = node->next) { + slave = list_entry(node, struct mtd_part, list); + if (slave->master == master) { + struct list_head *prev = node->prev; + __list_del(prev, node->next); + if(slave->registered) + del_mtd_device(&slave->mtd); + kfree(slave); + node = prev; + } + } + + return 0; +} + +/* + * This function, given a master MTD object and a partition table, creates + * and registers slave MTD objects which are bound to the master according to + * the partition definitions. + * (Q: should we register the master MTD object as well?) + */ + +int add_mtd_partitions(struct mtd_info *master, + const struct mtd_partition *parts, + int nbparts) +{ + struct mtd_part *slave; + u_int32_t cur_offset = 0; + int i; + + printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); + + for (i = 0; i < nbparts; i++) { + + /* allocate the partition structure */ + slave = kzalloc (sizeof(*slave), GFP_KERNEL); + if (!slave) { + printk ("memory allocation error while creating partitions for \"%s\"\n", + master->name); + del_mtd_partitions(master); + return -ENOMEM; + } + list_add(&slave->list, &mtd_partitions); + + /* set up the MTD object for this partition */ + slave->mtd.type = master->type; + slave->mtd.flags = master->flags & ~parts[i].mask_flags; + slave->mtd.size = parts[i].size; + slave->mtd.writesize = master->writesize; + slave->mtd.oobsize = master->oobsize; + slave->mtd.oobavail = master->oobavail; + slave->mtd.subpage_sft = master->subpage_sft; + + slave->mtd.name = parts[i].name; + slave->mtd.owner = master->owner; + + slave->mtd.read = part_read; + slave->mtd.write = part_write; + +#ifdef MTD_LINUX + if (master->panic_write) + slave->mtd.panic_write = part_panic_write; + + if(master->point && master->unpoint){ + slave->mtd.point = part_point; + slave->mtd.unpoint = part_unpoint; + } +#endif + + if (master->read_oob) + slave->mtd.read_oob = part_read_oob; + if (master->write_oob) + slave->mtd.write_oob = part_write_oob; + if(master->read_user_prot_reg) + slave->mtd.read_user_prot_reg = part_read_user_prot_reg; + if(master->read_fact_prot_reg) + slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; + if(master->write_user_prot_reg) + slave->mtd.write_user_prot_reg = part_write_user_prot_reg; + if(master->lock_user_prot_reg) + slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; + if(master->get_user_prot_info) + slave->mtd.get_user_prot_info = part_get_user_prot_info; + if(master->get_fact_prot_info) + slave->mtd.get_fact_prot_info = part_get_fact_prot_info; + if (master->sync) + slave->mtd.sync = part_sync; +#ifdef MTD_LINUX + if (!i && master->suspend && master->resume) { + slave->mtd.suspend = part_suspend; + slave->mtd.resume = part_resume; + } + if (master->writev) + slave->mtd.writev = part_writev; + if (master->lock) + slave->mtd.lock = part_lock; + if (master->unlock) + slave->mtd.unlock = part_unlock; +#endif + if (master->block_isbad) + slave->mtd.block_isbad = part_block_isbad; + if (master->block_markbad) + slave->mtd.block_markbad = part_block_markbad; + slave->mtd.erase = part_erase; + slave->master = master; + slave->offset = parts[i].offset; + slave->index = i; + + if (slave->offset == MTDPART_OFS_APPEND) + slave->offset = cur_offset; + if (slave->offset == MTDPART_OFS_NXTBLK) { + slave->offset = cur_offset; + if ((cur_offset % master->erasesize) != 0) { + /* Round up to next erasesize */ + slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; + printk(KERN_NOTICE "Moving partition %d: " + "0x%08x -> 0x%08x\n", i, + cur_offset, slave->offset); + } + } + if (slave->mtd.size == MTDPART_SIZ_FULL) + slave->mtd.size = master->size - slave->offset; + cur_offset = slave->offset + slave->mtd.size; + + printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, + slave->offset + slave->mtd.size, slave->mtd.name); + + /* let's do some sanity checks */ + if (slave->offset >= master->size) { + /* let's register it anyway to preserve ordering */ + slave->offset = 0; + slave->mtd.size = 0; + printk ("mtd: partition \"%s\" is out of reach -- disabled\n", + parts[i].name); + } + if (slave->offset + slave->mtd.size > master->size) { + slave->mtd.size = master->size - slave->offset; + printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", + parts[i].name, master->name, slave->mtd.size); + } + if (master->numeraseregions>1) { + /* Deal with variable erase size stuff */ + int i; + struct mtd_erase_region_info *regions = master->eraseregions; + + /* Find the first erase regions which is part of this partition. */ + for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) + ; + + for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { + if (slave->mtd.erasesize < regions[i].erasesize) { + slave->mtd.erasesize = regions[i].erasesize; + } + } + } else { + /* Single erase size */ + slave->mtd.erasesize = master->erasesize; + } + + if ((slave->mtd.flags & MTD_WRITEABLE) && + (slave->offset % slave->mtd.erasesize)) { + /* Doesn't start on a boundary of major erase size */ + /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ + slave->mtd.flags &= ~MTD_WRITEABLE; + printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", + parts[i].name); + } + if ((slave->mtd.flags & MTD_WRITEABLE) && + (slave->mtd.size % slave->mtd.erasesize)) { + slave->mtd.flags &= ~MTD_WRITEABLE; + printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", + parts[i].name); + } + + slave->mtd.ecclayout = master->ecclayout; + if (master->block_isbad) { + uint32_t offs = 0; + + while(offs < slave->mtd.size) { + if (master->block_isbad(master, + offs + slave->offset)) + slave->mtd.ecc_stats.badblocks++; + offs += slave->mtd.erasesize; + } + } + +#ifdef MTD_LINUX + if (parts[i].mtdp) { + /* store the object pointer + * (caller may or may not register it */ + *parts[i].mtdp = &slave->mtd; + slave->registered = 0; + } else { + /* register our partition */ + add_mtd_device(&slave->mtd); + slave->registered = 1; + } +#else + /* register our partition */ + add_mtd_device(&slave->mtd); + slave->registered = 1; +#endif + } + + return 0; +} + +#ifdef MTD_LINUX +EXPORT_SYMBOL(add_mtd_partitions); +EXPORT_SYMBOL(del_mtd_partitions); +#endif -- cgit v1.1 From f399d4a281713d5ef2d764f05d545fe61e3bd569 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:23:06 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 1/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- drivers/mtd/ubi/Makefile | 51 ++ drivers/mtd/ubi/build.c | 1186 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/ubi/crc32.c | 518 ++++++++++++++++++++ 3 files changed, 1755 insertions(+) create mode 100644 drivers/mtd/ubi/Makefile create mode 100644 drivers/mtd/ubi/build.c create mode 100644 drivers/mtd/ubi/crc32.c diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile new file mode 100644 index 0000000..8bd82c3 --- /dev/null +++ b/drivers/mtd/ubi/Makefile @@ -0,0 +1,51 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libubi.a + +ifdef CONFIG_CMD_UBI +COBJS-y += build.o vtbl.o vmt.o upd.o kapi.o eba.o io.o wl.o scan.o crc32.o + +COBJS-y += misc.o +COBJS-y += debug.o +endif + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c new file mode 100644 index 0000000..17cabb2 --- /dev/null +++ b/drivers/mtd/ubi/build.c @@ -0,0 +1,1186 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (c) Nokia Corporation, 2007 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём), + * Frank Haverkamp + */ + +/* + * This file includes UBI initialization and building of UBI devices. + * + * When UBI is initialized, it attaches all the MTD devices specified as the + * module load parameters or the kernel boot parameters. If MTD devices were + * specified, UBI does not attach any MTD device, but it is possible to do + * later using the "UBI control device". + * + * At the moment we only attach UBI devices by scanning, which will become a + * bottleneck when flashes reach certain large size. Then one may improve UBI + * and add other methods, although it does not seem to be easy to do. + */ + +#ifdef UBI_LINUX +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#include +#include "ubi.h" + +/* Maximum length of the 'mtd=' parameter */ +#define MTD_PARAM_LEN_MAX 64 + +/** + * struct mtd_dev_param - MTD device parameter description data structure. + * @name: MTD device name or number string + * @vid_hdr_offs: VID header offset + */ +struct mtd_dev_param +{ + char name[MTD_PARAM_LEN_MAX]; + int vid_hdr_offs; +}; + +/* Numbers of elements set in the @mtd_dev_param array */ +static int mtd_devs = 0; + +/* MTD devices specification parameters */ +static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; + +/* Root UBI "class" object (corresponds to '//class/ubi/') */ +struct class *ubi_class; + +#ifdef UBI_LINUX +/* Slab cache for wear-leveling entries */ +struct kmem_cache *ubi_wl_entry_slab; + +/* UBI control character device */ +static struct miscdevice ubi_ctrl_cdev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "ubi_ctrl", + .fops = &ubi_ctrl_cdev_operations, +}; +#endif + +/* All UBI devices in system */ +struct ubi_device *ubi_devices[UBI_MAX_DEVICES]; + +#ifdef UBI_LINUX +/* Serializes UBI devices creations and removals */ +DEFINE_MUTEX(ubi_devices_mutex); + +/* Protects @ubi_devices and @ubi->ref_count */ +static DEFINE_SPINLOCK(ubi_devices_lock); + +/* "Show" method for files in '//class/ubi/' */ +static ssize_t ubi_version_show(struct class *class, char *buf) +{ + return sprintf(buf, "%d\n", UBI_VERSION); +} + +/* UBI version attribute ('//class/ubi/version') */ +static struct class_attribute ubi_version = + __ATTR(version, S_IRUGO, ubi_version_show, NULL); + +static ssize_t dev_attribute_show(struct device *dev, + struct device_attribute *attr, char *buf); + +/* UBI device attributes (correspond to files in '//class/ubi/ubiX') */ +static struct device_attribute dev_eraseblock_size = + __ATTR(eraseblock_size, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_avail_eraseblocks = + __ATTR(avail_eraseblocks, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_total_eraseblocks = + __ATTR(total_eraseblocks, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_volumes_count = + __ATTR(volumes_count, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_max_ec = + __ATTR(max_ec, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_reserved_for_bad = + __ATTR(reserved_for_bad, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_bad_peb_count = + __ATTR(bad_peb_count, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_max_vol_count = + __ATTR(max_vol_count, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_min_io_size = + __ATTR(min_io_size, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_bgt_enabled = + __ATTR(bgt_enabled, S_IRUGO, dev_attribute_show, NULL); +static struct device_attribute dev_mtd_num = + __ATTR(mtd_num, S_IRUGO, dev_attribute_show, NULL); +#endif + +/** + * ubi_get_device - get UBI device. + * @ubi_num: UBI device number + * + * This function returns UBI device description object for UBI device number + * @ubi_num, or %NULL if the device does not exist. This function increases the + * device reference count to prevent removal of the device. In other words, the + * device cannot be removed if its reference count is not zero. + */ +struct ubi_device *ubi_get_device(int ubi_num) +{ + struct ubi_device *ubi; + + spin_lock(&ubi_devices_lock); + ubi = ubi_devices[ubi_num]; + if (ubi) { + ubi_assert(ubi->ref_count >= 0); + ubi->ref_count += 1; + get_device(&ubi->dev); + } + spin_unlock(&ubi_devices_lock); + + return ubi; +} + +/** + * ubi_put_device - drop an UBI device reference. + * @ubi: UBI device description object + */ +void ubi_put_device(struct ubi_device *ubi) +{ + spin_lock(&ubi_devices_lock); + ubi->ref_count -= 1; + put_device(&ubi->dev); + spin_unlock(&ubi_devices_lock); +} + +/** + * ubi_get_by_major - get UBI device description object by character device + * major number. + * @major: major number + * + * This function is similar to 'ubi_get_device()', but it searches the device + * by its major number. + */ +struct ubi_device *ubi_get_by_major(int major) +{ + int i; + struct ubi_device *ubi; + + spin_lock(&ubi_devices_lock); + for (i = 0; i < UBI_MAX_DEVICES; i++) { + ubi = ubi_devices[i]; + if (ubi && MAJOR(ubi->cdev.dev) == major) { + ubi_assert(ubi->ref_count >= 0); + ubi->ref_count += 1; + get_device(&ubi->dev); + spin_unlock(&ubi_devices_lock); + return ubi; + } + } + spin_unlock(&ubi_devices_lock); + + return NULL; +} + +/** + * ubi_major2num - get UBI device number by character device major number. + * @major: major number + * + * This function searches UBI device number object by its major number. If UBI + * device was not found, this function returns -ENODEV, otherwise the UBI device + * number is returned. + */ +int ubi_major2num(int major) +{ + int i, ubi_num = -ENODEV; + + spin_lock(&ubi_devices_lock); + for (i = 0; i < UBI_MAX_DEVICES; i++) { + struct ubi_device *ubi = ubi_devices[i]; + + if (ubi && MAJOR(ubi->cdev.dev) == major) { + ubi_num = ubi->ubi_num; + break; + } + } + spin_unlock(&ubi_devices_lock); + + return ubi_num; +} + +#ifdef UBI_LINUX +/* "Show" method for files in '//class/ubi/ubiX/' */ +static ssize_t dev_attribute_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret; + struct ubi_device *ubi; + + /* + * The below code looks weird, but it actually makes sense. We get the + * UBI device reference from the contained 'struct ubi_device'. But it + * is unclear if the device was removed or not yet. Indeed, if the + * device was removed before we increased its reference count, + * 'ubi_get_device()' will return -ENODEV and we fail. + * + * Remember, 'struct ubi_device' is freed in the release function, so + * we still can use 'ubi->ubi_num'. + */ + ubi = container_of(dev, struct ubi_device, dev); + ubi = ubi_get_device(ubi->ubi_num); + if (!ubi) + return -ENODEV; + + if (attr == &dev_eraseblock_size) + ret = sprintf(buf, "%d\n", ubi->leb_size); + else if (attr == &dev_avail_eraseblocks) + ret = sprintf(buf, "%d\n", ubi->avail_pebs); + else if (attr == &dev_total_eraseblocks) + ret = sprintf(buf, "%d\n", ubi->good_peb_count); + else if (attr == &dev_volumes_count) + ret = sprintf(buf, "%d\n", ubi->vol_count - UBI_INT_VOL_COUNT); + else if (attr == &dev_max_ec) + ret = sprintf(buf, "%d\n", ubi->max_ec); + else if (attr == &dev_reserved_for_bad) + ret = sprintf(buf, "%d\n", ubi->beb_rsvd_pebs); + else if (attr == &dev_bad_peb_count) + ret = sprintf(buf, "%d\n", ubi->bad_peb_count); + else if (attr == &dev_max_vol_count) + ret = sprintf(buf, "%d\n", ubi->vtbl_slots); + else if (attr == &dev_min_io_size) + ret = sprintf(buf, "%d\n", ubi->min_io_size); + else if (attr == &dev_bgt_enabled) + ret = sprintf(buf, "%d\n", ubi->thread_enabled); + else if (attr == &dev_mtd_num) + ret = sprintf(buf, "%d\n", ubi->mtd->index); + else + ret = -EINVAL; + + ubi_put_device(ubi); + return ret; +} + +/* Fake "release" method for UBI devices */ +static void dev_release(struct device *dev) { } + +/** + * ubi_sysfs_init - initialize sysfs for an UBI device. + * @ubi: UBI device description object + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int ubi_sysfs_init(struct ubi_device *ubi) +{ + int err; + + ubi->dev.release = dev_release; + ubi->dev.devt = ubi->cdev.dev; + ubi->dev.class = ubi_class; + sprintf(&ubi->dev.bus_id[0], UBI_NAME_STR"%d", ubi->ubi_num); + err = device_register(&ubi->dev); + if (err) + return err; + + err = device_create_file(&ubi->dev, &dev_eraseblock_size); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_avail_eraseblocks); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_total_eraseblocks); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_volumes_count); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_max_ec); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_reserved_for_bad); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_bad_peb_count); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_max_vol_count); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_min_io_size); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_bgt_enabled); + if (err) + return err; + err = device_create_file(&ubi->dev, &dev_mtd_num); + return err; +} + +/** + * ubi_sysfs_close - close sysfs for an UBI device. + * @ubi: UBI device description object + */ +static void ubi_sysfs_close(struct ubi_device *ubi) +{ + device_remove_file(&ubi->dev, &dev_mtd_num); + device_remove_file(&ubi->dev, &dev_bgt_enabled); + device_remove_file(&ubi->dev, &dev_min_io_size); + device_remove_file(&ubi->dev, &dev_max_vol_count); + device_remove_file(&ubi->dev, &dev_bad_peb_count); + device_remove_file(&ubi->dev, &dev_reserved_for_bad); + device_remove_file(&ubi->dev, &dev_max_ec); + device_remove_file(&ubi->dev, &dev_volumes_count); + device_remove_file(&ubi->dev, &dev_total_eraseblocks); + device_remove_file(&ubi->dev, &dev_avail_eraseblocks); + device_remove_file(&ubi->dev, &dev_eraseblock_size); + device_unregister(&ubi->dev); +} +#endif + +/** + * kill_volumes - destroy all volumes. + * @ubi: UBI device description object + */ +static void kill_volumes(struct ubi_device *ubi) +{ + int i; + + for (i = 0; i < ubi->vtbl_slots; i++) + if (ubi->volumes[i]) + ubi_free_volume(ubi, ubi->volumes[i]); +} + +/** + * uif_init - initialize user interfaces for an UBI device. + * @ubi: UBI device description object + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int uif_init(struct ubi_device *ubi) +{ + int i, err; +#ifdef UBI_LINUX + dev_t dev; +#endif + + sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); + + /* + * Major numbers for the UBI character devices are allocated + * dynamically. Major numbers of volume character devices are + * equivalent to ones of the corresponding UBI character device. Minor + * numbers of UBI character devices are 0, while minor numbers of + * volume character devices start from 1. Thus, we allocate one major + * number and ubi->vtbl_slots + 1 minor numbers. + */ + err = alloc_chrdev_region(&dev, 0, ubi->vtbl_slots + 1, ubi->ubi_name); + if (err) { + ubi_err("cannot register UBI character devices"); + return err; + } + + ubi_assert(MINOR(dev) == 0); + cdev_init(&ubi->cdev, &ubi_cdev_operations); + dbg_msg("%s major is %u", ubi->ubi_name, MAJOR(dev)); + ubi->cdev.owner = THIS_MODULE; + + err = cdev_add(&ubi->cdev, dev, 1); + if (err) { + ubi_err("cannot add character device"); + goto out_unreg; + } + + err = ubi_sysfs_init(ubi); + if (err) + goto out_sysfs; + + for (i = 0; i < ubi->vtbl_slots; i++) + if (ubi->volumes[i]) { + err = ubi_add_volume(ubi, ubi->volumes[i]); + if (err) { + ubi_err("cannot add volume %d", i); + goto out_volumes; + } + } + + return 0; + +out_volumes: + kill_volumes(ubi); +out_sysfs: + ubi_sysfs_close(ubi); + cdev_del(&ubi->cdev); +out_unreg: + unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); + ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); + return err; +} + +/** + * uif_close - close user interfaces for an UBI device. + * @ubi: UBI device description object + */ +static void uif_close(struct ubi_device *ubi) +{ + kill_volumes(ubi); + ubi_sysfs_close(ubi); + cdev_del(&ubi->cdev); + unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); +} + +/** + * attach_by_scanning - attach an MTD device using scanning method. + * @ubi: UBI device descriptor + * + * This function returns zero in case of success and a negative error code in + * case of failure. + * + * Note, currently this is the only method to attach UBI devices. Hopefully in + * the future we'll have more scalable attaching methods and avoid full media + * scanning. But even in this case scanning will be needed as a fall-back + * attaching method if there are some on-flash table corruptions. + */ +static int attach_by_scanning(struct ubi_device *ubi) +{ + int err; + struct ubi_scan_info *si; + + si = ubi_scan(ubi); + if (IS_ERR(si)) + return PTR_ERR(si); + + ubi->bad_peb_count = si->bad_peb_count; + ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; + ubi->max_ec = si->max_ec; + ubi->mean_ec = si->mean_ec; + + err = ubi_read_volume_table(ubi, si); + if (err) + goto out_si; + + err = ubi_wl_init_scan(ubi, si); + if (err) + goto out_vtbl; + + err = ubi_eba_init_scan(ubi, si); + if (err) + goto out_wl; + + ubi_scan_destroy_si(si); + return 0; + +out_wl: + ubi_wl_close(ubi); +out_vtbl: + vfree(ubi->vtbl); +out_si: + ubi_scan_destroy_si(si); + return err; +} + +/** + * io_init - initialize I/O unit for a given UBI device. + * @ubi: UBI device description object + * + * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are + * assumed: + * o EC header is always at offset zero - this cannot be changed; + * o VID header starts just after the EC header at the closest address + * aligned to @io->hdrs_min_io_size; + * o data starts just after the VID header at the closest address aligned to + * @io->min_io_size + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int io_init(struct ubi_device *ubi) +{ + if (ubi->mtd->numeraseregions != 0) { + /* + * Some flashes have several erase regions. Different regions + * may have different eraseblock size and other + * characteristics. It looks like mostly multi-region flashes + * have one "main" region and one or more small regions to + * store boot loader code or boot parameters or whatever. I + * guess we should just pick the largest region. But this is + * not implemented. + */ + ubi_err("multiple regions, not implemented"); + return -EINVAL; + } + + if (ubi->vid_hdr_offset < 0) + return -EINVAL; + + /* + * Note, in this implementation we support MTD devices with 0x7FFFFFFF + * physical eraseblocks maximum. + */ + + ubi->peb_size = ubi->mtd->erasesize; + ubi->peb_count = ubi->mtd->size / ubi->mtd->erasesize; + ubi->flash_size = ubi->mtd->size; + + if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) + ubi->bad_allowed = 1; + + ubi->min_io_size = ubi->mtd->writesize; + ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; + + /* + * Make sure minimal I/O unit is power of 2. Note, there is no + * fundamental reason for this assumption. It is just an optimization + * which allows us to avoid costly division operations. + */ + if (!is_power_of_2(ubi->min_io_size)) { + ubi_err("min. I/O unit (%d) is not power of 2", + ubi->min_io_size); + return -EINVAL; + } + + ubi_assert(ubi->hdrs_min_io_size > 0); + ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size); + ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0); + + /* Calculate default aligned sizes of EC and VID headers */ + ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size); + ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size); + + dbg_msg("min_io_size %d", ubi->min_io_size); + dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size); + dbg_msg("ec_hdr_alsize %d", ubi->ec_hdr_alsize); + dbg_msg("vid_hdr_alsize %d", ubi->vid_hdr_alsize); + + if (ubi->vid_hdr_offset == 0) + /* Default offset */ + ubi->vid_hdr_offset = ubi->vid_hdr_aloffset = + ubi->ec_hdr_alsize; + else { + ubi->vid_hdr_aloffset = ubi->vid_hdr_offset & + ~(ubi->hdrs_min_io_size - 1); + ubi->vid_hdr_shift = ubi->vid_hdr_offset - + ubi->vid_hdr_aloffset; + } + + /* Similar for the data offset */ + ubi->leb_start = ubi->vid_hdr_offset + UBI_EC_HDR_SIZE; + ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); + + dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); + dbg_msg("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); + dbg_msg("vid_hdr_shift %d", ubi->vid_hdr_shift); + dbg_msg("leb_start %d", ubi->leb_start); + + /* The shift must be aligned to 32-bit boundary */ + if (ubi->vid_hdr_shift % 4) { + ubi_err("unaligned VID header shift %d", + ubi->vid_hdr_shift); + return -EINVAL; + } + + /* Check sanity */ + if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE || + ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || + ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || + ubi->leb_start & (ubi->min_io_size - 1)) { + ubi_err("bad VID header (%d) or data offsets (%d)", + ubi->vid_hdr_offset, ubi->leb_start); + return -EINVAL; + } + + /* + * It may happen that EC and VID headers are situated in one minimal + * I/O unit. In this case we can only accept this UBI image in + * read-only mode. + */ + if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { + ubi_warn("EC and VID headers are in the same minimal I/O unit, " + "switch to read-only mode"); + ubi->ro_mode = 1; + } + + ubi->leb_size = ubi->peb_size - ubi->leb_start; + + if (!(ubi->mtd->flags & MTD_WRITEABLE)) { + ubi_msg("MTD device %d is write-protected, attach in " + "read-only mode", ubi->mtd->index); + ubi->ro_mode = 1; + } + + ubi_msg("physical eraseblock size: %d bytes (%d KiB)", + ubi->peb_size, ubi->peb_size >> 10); + ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); + ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); + if (ubi->hdrs_min_io_size != ubi->min_io_size) + ubi_msg("sub-page size: %d", + ubi->hdrs_min_io_size); + ubi_msg("VID header offset: %d (aligned %d)", + ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); + ubi_msg("data offset: %d", ubi->leb_start); + + /* + * Note, ideally, we have to initialize ubi->bad_peb_count here. But + * unfortunately, MTD does not provide this information. We should loop + * over all physical eraseblocks and invoke mtd->block_is_bad() for + * each physical eraseblock. So, we skip ubi->bad_peb_count + * uninitialized and initialize it after scanning. + */ + + return 0; +} + +/** + * autoresize - re-size the volume which has the "auto-resize" flag set. + * @ubi: UBI device description object + * @vol_id: ID of the volume to re-size + * + * This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in + * the volume table to the largest possible size. See comments in ubi-header.h + * for more description of the flag. Returns zero in case of success and a + * negative error code in case of failure. + */ +static int autoresize(struct ubi_device *ubi, int vol_id) +{ + struct ubi_volume_desc desc; + struct ubi_volume *vol = ubi->volumes[vol_id]; + int err, old_reserved_pebs = vol->reserved_pebs; + + /* + * Clear the auto-resize flag in the volume in-memory copy of the + * volume table, and 'ubi_resize_volume()' will propogate this change + * to the flash. + */ + ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; + + if (ubi->avail_pebs == 0) { + struct ubi_vtbl_record vtbl_rec; + + /* + * No avalilable PEBs to re-size the volume, clear the flag on + * flash and exit. + */ + memcpy(&vtbl_rec, &ubi->vtbl[vol_id], + sizeof(struct ubi_vtbl_record)); + err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); + if (err) + ubi_err("cannot clean auto-resize flag for volume %d", + vol_id); + } else { + desc.vol = vol; + err = ubi_resize_volume(&desc, + old_reserved_pebs + ubi->avail_pebs); + if (err) + ubi_err("cannot auto-resize volume %d", vol_id); + } + + if (err) + return err; + + ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, + vol->name, old_reserved_pebs, vol->reserved_pebs); + return 0; +} + +/** + * ubi_attach_mtd_dev - attach an MTD device. + * @mtd_dev: MTD device description object + * @ubi_num: number to assign to the new UBI device + * @vid_hdr_offset: VID header offset + * + * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number + * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in + * which case this function finds a vacant device nubert and assings it + * automatically. Returns the new UBI device number in case of success and a + * negative error code in case of failure. + * + * Note, the invocations of this function has to be serialized by the + * @ubi_devices_mutex. + */ +int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) +{ + struct ubi_device *ubi; + int i, err; + + /* + * Check if we already have the same MTD device attached. + * + * Note, this function assumes that UBI devices creations and deletions + * are serialized, so it does not take the &ubi_devices_lock. + */ + for (i = 0; i < UBI_MAX_DEVICES; i++) { + ubi = ubi_devices[i]; + if (ubi && mtd->index == ubi->mtd->index) { + dbg_err("mtd%d is already attached to ubi%d", + mtd->index, i); + return -EEXIST; + } + } + + /* + * Make sure this MTD device is not emulated on top of an UBI volume + * already. Well, generally this recursion works fine, but there are + * different problems like the UBI module takes a reference to itself + * by attaching (and thus, opening) the emulated MTD device. This + * results in inability to unload the module. And in general it makes + * no sense to attach emulated MTD devices, so we prohibit this. + */ + if (mtd->type == MTD_UBIVOLUME) { + ubi_err("refuse attaching mtd%d - it is already emulated on " + "top of UBI", mtd->index); + return -EINVAL; + } + + if (ubi_num == UBI_DEV_NUM_AUTO) { + /* Search for an empty slot in the @ubi_devices array */ + for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) + if (!ubi_devices[ubi_num]) + break; + if (ubi_num == UBI_MAX_DEVICES) { + dbg_err("only %d UBI devices may be created", UBI_MAX_DEVICES); + return -ENFILE; + } + } else { + if (ubi_num >= UBI_MAX_DEVICES) + return -EINVAL; + + /* Make sure ubi_num is not busy */ + if (ubi_devices[ubi_num]) { + dbg_err("ubi%d already exists", ubi_num); + return -EEXIST; + } + } + + ubi = kzalloc(sizeof(struct ubi_device), GFP_KERNEL); + if (!ubi) + return -ENOMEM; + + ubi->mtd = mtd; + ubi->ubi_num = ubi_num; + ubi->vid_hdr_offset = vid_hdr_offset; + ubi->autoresize_vol_id = -1; + + mutex_init(&ubi->buf_mutex); + mutex_init(&ubi->ckvol_mutex); + mutex_init(&ubi->volumes_mutex); + spin_lock_init(&ubi->volumes_lock); + + ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); + + err = io_init(ubi); + if (err) + goto out_free; + + ubi->peb_buf1 = vmalloc(ubi->peb_size); + if (!ubi->peb_buf1) + goto out_free; + + ubi->peb_buf2 = vmalloc(ubi->peb_size); + if (!ubi->peb_buf2) + goto out_free; + +#ifdef CONFIG_MTD_UBI_DEBUG + mutex_init(&ubi->dbg_buf_mutex); + ubi->dbg_peb_buf = vmalloc(ubi->peb_size); + if (!ubi->dbg_peb_buf) + goto out_free; +#endif + + err = attach_by_scanning(ubi); + if (err) { + dbg_err("failed to attach by scanning, error %d", err); + goto out_free; + } + + if (ubi->autoresize_vol_id != -1) { + err = autoresize(ubi, ubi->autoresize_vol_id); + if (err) + goto out_detach; + } + + err = uif_init(ubi); + if (err) + goto out_detach; + + ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); + if (IS_ERR(ubi->bgt_thread)) { + err = PTR_ERR(ubi->bgt_thread); + ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, + err); + goto out_uif; + } + + ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); + ubi_msg("MTD device name: \"%s\"", mtd->name); + ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); + ubi_msg("number of good PEBs: %d", ubi->good_peb_count); + ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); + ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); + ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); + ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); + ubi_msg("number of user volumes: %d", + ubi->vol_count - UBI_INT_VOL_COUNT); + ubi_msg("available PEBs: %d", ubi->avail_pebs); + ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); + ubi_msg("number of PEBs reserved for bad PEB handling: %d", + ubi->beb_rsvd_pebs); + ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); + + /* Enable the background thread */ + if (!DBG_DISABLE_BGT) { + ubi->thread_enabled = 1; + wake_up_process(ubi->bgt_thread); + } + + ubi_devices[ubi_num] = ubi; + return ubi_num; + +out_uif: + uif_close(ubi); +out_detach: + ubi_eba_close(ubi); + ubi_wl_close(ubi); + vfree(ubi->vtbl); +out_free: + vfree(ubi->peb_buf1); + vfree(ubi->peb_buf2); +#ifdef CONFIG_MTD_UBI_DEBUG + vfree(ubi->dbg_peb_buf); +#endif + kfree(ubi); + return err; +} + +/** + * ubi_detach_mtd_dev - detach an MTD device. + * @ubi_num: UBI device number to detach from + * @anyway: detach MTD even if device reference count is not zero + * + * This function destroys an UBI device number @ubi_num and detaches the + * underlying MTD device. Returns zero in case of success and %-EBUSY if the + * UBI device is busy and cannot be destroyed, and %-EINVAL if it does not + * exist. + * + * Note, the invocations of this function has to be serialized by the + * @ubi_devices_mutex. + */ +int ubi_detach_mtd_dev(int ubi_num, int anyway) +{ + struct ubi_device *ubi; + + if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) + return -EINVAL; + + spin_lock(&ubi_devices_lock); + ubi = ubi_devices[ubi_num]; + if (!ubi) { + spin_unlock(&ubi_devices_lock); + return -EINVAL; + } + + if (ubi->ref_count) { + if (!anyway) { + spin_unlock(&ubi_devices_lock); + return -EBUSY; + } + /* This may only happen if there is a bug */ + ubi_err("%s reference count %d, destroy anyway", + ubi->ubi_name, ubi->ref_count); + } + ubi_devices[ubi_num] = NULL; + spin_unlock(&ubi_devices_lock); + + ubi_assert(ubi_num == ubi->ubi_num); + dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); + + /* + * Before freeing anything, we have to stop the background thread to + * prevent it from doing anything on this device while we are freeing. + */ + if (ubi->bgt_thread) + kthread_stop(ubi->bgt_thread); + + uif_close(ubi); + ubi_eba_close(ubi); + ubi_wl_close(ubi); + vfree(ubi->vtbl); + put_mtd_device(ubi->mtd); + vfree(ubi->peb_buf1); + vfree(ubi->peb_buf2); +#ifdef CONFIG_MTD_UBI_DEBUG + vfree(ubi->dbg_peb_buf); +#endif + ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); + kfree(ubi); + return 0; +} + +/** + * find_mtd_device - open an MTD device by its name or number. + * @mtd_dev: name or number of the device + * + * This function tries to open and MTD device described by @mtd_dev string, + * which is first treated as an ASCII number, and if it is not true, it is + * treated as MTD device name. Returns MTD device description object in case of + * success and a negative error code in case of failure. + */ +static struct mtd_info * __init open_mtd_device(const char *mtd_dev) +{ + struct mtd_info *mtd; + int mtd_num; + char *endp; + + mtd_num = simple_strtoul(mtd_dev, &endp, 0); + if (*endp != '\0' || mtd_dev == endp) { + /* + * This does not look like an ASCII integer, probably this is + * MTD device name. + */ + mtd = get_mtd_device_nm(mtd_dev); + } else + mtd = get_mtd_device(NULL, mtd_num); + + return mtd; +} + +int __init ubi_init(void) +{ + int err, i, k; + + /* Ensure that EC and VID headers have correct size */ + BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); + BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); + + if (mtd_devs > UBI_MAX_DEVICES) { + ubi_err("too many MTD devices, maximum is %d", UBI_MAX_DEVICES); + return -EINVAL; + } + + /* Create base sysfs directory and sysfs files */ + ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); + if (IS_ERR(ubi_class)) { + err = PTR_ERR(ubi_class); + ubi_err("cannot create UBI class"); + goto out; + } + + err = class_create_file(ubi_class, &ubi_version); + if (err) { + ubi_err("cannot create sysfs file"); + goto out_class; + } + + err = misc_register(&ubi_ctrl_cdev); + if (err) { + ubi_err("cannot register device"); + goto out_version; + } + +#ifdef UBI_LINUX + ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", + sizeof(struct ubi_wl_entry), + 0, 0, NULL); + if (!ubi_wl_entry_slab) + goto out_dev_unreg; +#endif + + /* Attach MTD devices */ + for (i = 0; i < mtd_devs; i++) { + struct mtd_dev_param *p = &mtd_dev_param[i]; + struct mtd_info *mtd; + + cond_resched(); + + mtd = open_mtd_device(p->name); + if (IS_ERR(mtd)) { + err = PTR_ERR(mtd); + goto out_detach; + } + + mutex_lock(&ubi_devices_mutex); + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, + p->vid_hdr_offs); + mutex_unlock(&ubi_devices_mutex); + if (err < 0) { + put_mtd_device(mtd); + ubi_err("cannot attach mtd%d", mtd->index); + goto out_detach; + } + } + + return 0; + +out_detach: + for (k = 0; k < i; k++) + if (ubi_devices[k]) { + mutex_lock(&ubi_devices_mutex); + ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); + mutex_unlock(&ubi_devices_mutex); + } +#ifdef UBI_LINUX + kmem_cache_destroy(ubi_wl_entry_slab); +out_dev_unreg: +#endif + misc_deregister(&ubi_ctrl_cdev); +out_version: + class_remove_file(ubi_class, &ubi_version); +out_class: + class_destroy(ubi_class); +out: + ubi_err("UBI error: cannot initialize UBI, error %d", err); + return err; +} +module_init(ubi_init); + +void __exit ubi_exit(void) +{ + int i; + + for (i = 0; i < UBI_MAX_DEVICES; i++) + if (ubi_devices[i]) { + mutex_lock(&ubi_devices_mutex); + ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1); + mutex_unlock(&ubi_devices_mutex); + } + kmem_cache_destroy(ubi_wl_entry_slab); + misc_deregister(&ubi_ctrl_cdev); + class_remove_file(ubi_class, &ubi_version); + class_destroy(ubi_class); +} +module_exit(ubi_exit); + +/** + * bytes_str_to_int - convert a string representing number of bytes to an + * integer. + * @str: the string to convert + * + * This function returns positive resulting integer in case of success and a + * negative error code in case of failure. + */ +static int __init bytes_str_to_int(const char *str) +{ + char *endp; + unsigned long result; + + result = simple_strtoul(str, &endp, 0); + if (str == endp || result < 0) { + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n", + str); + return -EINVAL; + } + + switch (*endp) { + case 'G': + result *= 1024; + case 'M': + result *= 1024; + case 'K': + result *= 1024; + if (endp[1] == 'i' && endp[2] == 'B') + endp += 2; + case '\0': + break; + default: + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n", + str); + return -EINVAL; + } + + return result; +} + +/** + * ubi_mtd_param_parse - parse the 'mtd=' UBI parameter. + * @val: the parameter value to parse + * @kp: not used + * + * This function returns zero in case of success and a negative error code in + * case of error. + */ +int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) +{ + int i, len; + struct mtd_dev_param *p; + char buf[MTD_PARAM_LEN_MAX]; + char *pbuf = &buf[0]; + char *tokens[2] = {NULL, NULL}; + + if (!val) + return -EINVAL; + + if (mtd_devs == UBI_MAX_DEVICES) { + printk(KERN_ERR "UBI error: too many parameters, max. is %d\n", + UBI_MAX_DEVICES); + return -EINVAL; + } + + len = strnlen(val, MTD_PARAM_LEN_MAX); + if (len == MTD_PARAM_LEN_MAX) { + printk(KERN_ERR "UBI error: parameter \"%s\" is too long, " + "max. is %d\n", val, MTD_PARAM_LEN_MAX); + return -EINVAL; + } + + if (len == 0) { + printk(KERN_WARNING "UBI warning: empty 'mtd=' parameter - " + "ignored\n"); + return 0; + } + + strcpy(buf, val); + + /* Get rid of the final newline */ + if (buf[len - 1] == '\n') + buf[len - 1] = '\0'; + + for (i = 0; i < 2; i++) + tokens[i] = strsep(&pbuf, ","); + + if (pbuf) { + printk(KERN_ERR "UBI error: too many arguments at \"%s\"\n", + val); + return -EINVAL; + } + + p = &mtd_dev_param[mtd_devs]; + strcpy(&p->name[0], tokens[0]); + + if (tokens[1]) + p->vid_hdr_offs = bytes_str_to_int(tokens[1]); + + if (p->vid_hdr_offs < 0) + return p->vid_hdr_offs; + + mtd_devs += 1; + return 0; +} + +module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: " + "mtd=[,].\n" + "Multiple \"mtd\" parameters may be specified.\n" + "MTD devices may be specified by their number or name.\n" + "Optional \"vid_hdr_offs\" parameter specifies UBI VID " + "header position and data starting position to be used " + "by UBI.\n" + "Example: mtd=content,1984 mtd=4 - attach MTD device" + "with name \"content\" using VID header offset 1984, and " + "MTD device number 4 with default VID header offset."); + +MODULE_VERSION(__stringify(UBI_VERSION)); +MODULE_DESCRIPTION("UBI - Unsorted Block Images"); +MODULE_AUTHOR("Artem Bityutskiy"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mtd/ubi/crc32.c b/drivers/mtd/ubi/crc32.c new file mode 100644 index 0000000..5273ca3 --- /dev/null +++ b/drivers/mtd/ubi/crc32.c @@ -0,0 +1,518 @@ +/* + * Oct 15, 2000 Matt Domsch + * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks! + * Code was from the public domain, copyright abandoned. Code was + * subsequently included in the kernel, thus was re-licensed under the + * GNU GPL v2. + * + * Oct 12, 2000 Matt Domsch + * Same crc32 function was used in 5 other places in the kernel. + * I made one version, and deleted the others. + * There are various incantations of crc32(). Some use a seed of 0 or ~0. + * Some xor at the end with ~0. The generic crc32() function takes + * seed as an argument, and doesn't xor at the end. Then individual + * users can do whatever they need. + * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0. + * fs/jffs2 uses seed 0, doesn't xor with ~0. + * fs/partitions/efi.c uses seed ~0, xor's with ~0. + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#ifdef UBI_LINUX +#include +#include +#include +#include +#endif +#include + +#include + +#ifdef UBI_LINUX +#include +#include +#include +#endif +#include "crc32defs.h" +#define CRC_LE_BITS 8 + +# define __force +#ifndef __constant_cpu_to_le32 +#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x)) +#endif +#ifndef __constant_le32_to_cpu +#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x)) +#endif + +#if CRC_LE_BITS == 8 +#define tole(x) __constant_cpu_to_le32(x) +#define tobe(x) __constant_cpu_to_be32(x) +#else +#define tole(x) (x) +#define tobe(x) (x) +#endif +#include "crc32table.h" +#ifdef UBI_LINUX +MODULE_AUTHOR("Matt Domsch "); +MODULE_DESCRIPTION("Ethernet CRC32 calculations"); +MODULE_LICENSE("GPL"); +#endif +/** + * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32 + * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for + * other uses, or the previous crc32 value if computing incrementally. + * @p: pointer to buffer over which CRC is run + * @len: length of buffer @p + */ +u32 crc32_le(u32 crc, unsigned char const *p, size_t len); + +#if CRC_LE_BITS == 1 +/* + * In fact, the table-based code will work in this case, but it can be + * simplified by inlining the table in ?: form. + */ + +u32 crc32_le(u32 crc, unsigned char const *p, size_t len) +{ + int i; + while (len--) { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); + } + return crc; +} +#else /* Table-based approach */ + +u32 crc32_le(u32 crc, unsigned char const *p, size_t len) +{ +# if CRC_LE_BITS == 8 + const u32 *b =(u32 *)p; + const u32 *tab = crc32table_le; + +# ifdef __LITTLE_ENDIAN +# define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8) +# else +# define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8) +# endif + //printf("Crc32_le crc=%x\n",crc); + crc = __cpu_to_le32(crc); + /* Align it */ + if((((long)b)&3 && len)){ + do { + u8 *p = (u8 *)b; + DO_CRC(*p++); + b = (void *)p; + } while ((--len) && ((long)b)&3 ); + } + if((len >= 4)){ + /* load data 32 bits wide, xor data 32 bits wide. */ + size_t save_len = len & 3; + len = len >> 2; + --b; /* use pre increment below(*++b) for speed */ + do { + crc ^= *++b; + DO_CRC(0); + DO_CRC(0); + DO_CRC(0); + DO_CRC(0); + } while (--len); + b++; /* point to next byte(s) */ + len = save_len; + } + /* And the last few bytes */ + if(len){ + do { + u8 *p = (u8 *)b; + DO_CRC(*p++); + b = (void *)p; + } while (--len); + } + + return __le32_to_cpu(crc); +#undef ENDIAN_SHIFT +#undef DO_CRC + +# elif CRC_LE_BITS == 4 + while (len--) { + crc ^= *p++; + crc = (crc >> 4) ^ crc32table_le[crc & 15]; + crc = (crc >> 4) ^ crc32table_le[crc & 15]; + } + return crc; +# elif CRC_LE_BITS == 2 + while (len--) { + crc ^= *p++; + crc = (crc >> 2) ^ crc32table_le[crc & 3]; + crc = (crc >> 2) ^ crc32table_le[crc & 3]; + crc = (crc >> 2) ^ crc32table_le[crc & 3]; + crc = (crc >> 2) ^ crc32table_le[crc & 3]; + } + return crc; +# endif +} +#endif +#ifdef UBI_LINUX +/** + * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32 + * @crc: seed value for computation. ~0 for Ethernet, sometimes 0 for + * other uses, or the previous crc32 value if computing incrementally. + * @p: pointer to buffer over which CRC is run + * @len: length of buffer @p + */ +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len); + +#if CRC_BE_BITS == 1 +/* + * In fact, the table-based code will work in this case, but it can be + * simplified by inlining the table in ?: form. + */ + +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) +{ + int i; + while (len--) { + crc ^= *p++ << 24; + for (i = 0; i < 8; i++) + crc = + (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : + 0); + } + return crc; +} + +#else /* Table-based approach */ +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) +{ +# if CRC_BE_BITS == 8 + const u32 *b =(u32 *)p; + const u32 *tab = crc32table_be; + +# ifdef __LITTLE_ENDIAN +# define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8) +# else +# define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8) +# endif + + crc = __cpu_to_be32(crc); + /* Align it */ + if(unlikely(((long)b)&3 && len)){ + do { + u8 *p = (u8 *)b; + DO_CRC(*p++); + b = (u32 *)p; + } while ((--len) && ((long)b)&3 ); + } + if(likely(len >= 4)){ + /* load data 32 bits wide, xor data 32 bits wide. */ + size_t save_len = len & 3; + len = len >> 2; + --b; /* use pre increment below(*++b) for speed */ + do { + crc ^= *++b; + DO_CRC(0); + DO_CRC(0); + DO_CRC(0); + DO_CRC(0); + } while (--len); + b++; /* point to next byte(s) */ + len = save_len; + } + /* And the last few bytes */ + if(len){ + do { + u8 *p = (u8 *)b; + DO_CRC(*p++); + b = (void *)p; + } while (--len); + } + return __be32_to_cpu(crc); +#undef ENDIAN_SHIFT +#undef DO_CRC + +# elif CRC_BE_BITS == 4 + while (len--) { + crc ^= *p++ << 24; + crc = (crc << 4) ^ crc32table_be[crc >> 28]; + crc = (crc << 4) ^ crc32table_be[crc >> 28]; + } + return crc; +# elif CRC_BE_BITS == 2 + while (len--) { + crc ^= *p++ << 24; + crc = (crc << 2) ^ crc32table_be[crc >> 30]; + crc = (crc << 2) ^ crc32table_be[crc >> 30]; + crc = (crc << 2) ^ crc32table_be[crc >> 30]; + crc = (crc << 2) ^ crc32table_be[crc >> 30]; + } + return crc; +# endif +} +#endif + +EXPORT_SYMBOL(crc32_le); +EXPORT_SYMBOL(crc32_be); +#endif +/* + * A brief CRC tutorial. + * + * A CRC is a long-division remainder. You add the CRC to the message, + * and the whole thing (message+CRC) is a multiple of the given + * CRC polynomial. To check the CRC, you can either check that the + * CRC matches the recomputed value, *or* you can check that the + * remainder computed on the message+CRC is 0. This latter approach + * is used by a lot of hardware implementations, and is why so many + * protocols put the end-of-frame flag after the CRC. + * + * It's actually the same long division you learned in school, except that + * - We're working in binary, so the digits are only 0 and 1, and + * - When dividing polynomials, there are no carries. Rather than add and + * subtract, we just xor. Thus, we tend to get a bit sloppy about + * the difference between adding and subtracting. + * + * A 32-bit CRC polynomial is actually 33 bits long. But since it's + * 33 bits long, bit 32 is always going to be set, so usually the CRC + * is written in hex with the most significant bit omitted. (If you're + * familiar with the IEEE 754 floating-point format, it's the same idea.) + * + * Note that a CRC is computed over a string of *bits*, so you have + * to decide on the endianness of the bits within each byte. To get + * the best error-detecting properties, this should correspond to the + * order they're actually sent. For example, standard RS-232 serial is + * little-endian; the most significant bit (sometimes used for parity) + * is sent last. And when appending a CRC word to a message, you should + * do it in the right order, matching the endianness. + * + * Just like with ordinary division, the remainder is always smaller than + * the divisor (the CRC polynomial) you're dividing by. Each step of the + * division, you take one more digit (bit) of the dividend and append it + * to the current remainder. Then you figure out the appropriate multiple + * of the divisor to subtract to being the remainder back into range. + * In binary, it's easy - it has to be either 0 or 1, and to make the + * XOR cancel, it's just a copy of bit 32 of the remainder. + * + * When computing a CRC, we don't care about the quotient, so we can + * throw the quotient bit away, but subtract the appropriate multiple of + * the polynomial from the remainder and we're back to where we started, + * ready to process the next bit. + * + * A big-endian CRC written this way would be coded like: + * for (i = 0; i < input_bits; i++) { + * multiple = remainder & 0x80000000 ? CRCPOLY : 0; + * remainder = (remainder << 1 | next_input_bit()) ^ multiple; + * } + * Notice how, to get at bit 32 of the shifted remainder, we look + * at bit 31 of the remainder *before* shifting it. + * + * But also notice how the next_input_bit() bits we're shifting into + * the remainder don't actually affect any decision-making until + * 32 bits later. Thus, the first 32 cycles of this are pretty boring. + * Also, to add the CRC to a message, we need a 32-bit-long hole for it at + * the end, so we have to add 32 extra cycles shifting in zeros at the + * end of every message, + * + * So the standard trick is to rearrage merging in the next_input_bit() + * until the moment it's needed. Then the first 32 cycles can be precomputed, + * and merging in the final 32 zero bits to make room for the CRC can be + * skipped entirely. + * This changes the code to: + * for (i = 0; i < input_bits; i++) { + * remainder ^= next_input_bit() << 31; + * multiple = (remainder & 0x80000000) ? CRCPOLY : 0; + * remainder = (remainder << 1) ^ multiple; + * } + * With this optimization, the little-endian code is simpler: + * for (i = 0; i < input_bits; i++) { + * remainder ^= next_input_bit(); + * multiple = (remainder & 1) ? CRCPOLY : 0; + * remainder = (remainder >> 1) ^ multiple; + * } + * + * Note that the other details of endianness have been hidden in CRCPOLY + * (which must be bit-reversed) and next_input_bit(). + * + * However, as long as next_input_bit is returning the bits in a sensible + * order, we can actually do the merging 8 or more bits at a time rather + * than one bit at a time: + * for (i = 0; i < input_bytes; i++) { + * remainder ^= next_input_byte() << 24; + * for (j = 0; j < 8; j++) { + * multiple = (remainder & 0x80000000) ? CRCPOLY : 0; + * remainder = (remainder << 1) ^ multiple; + * } + * } + * Or in little-endian: + * for (i = 0; i < input_bytes; i++) { + * remainder ^= next_input_byte(); + * for (j = 0; j < 8; j++) { + * multiple = (remainder & 1) ? CRCPOLY : 0; + * remainder = (remainder << 1) ^ multiple; + * } + * } + * If the input is a multiple of 32 bits, you can even XOR in a 32-bit + * word at a time and increase the inner loop count to 32. + * + * You can also mix and match the two loop styles, for example doing the + * bulk of a message byte-at-a-time and adding bit-at-a-time processing + * for any fractional bytes at the end. + * + * The only remaining optimization is to the byte-at-a-time table method. + * Here, rather than just shifting one bit of the remainder to decide + * in the correct multiple to subtract, we can shift a byte at a time. + * This produces a 40-bit (rather than a 33-bit) intermediate remainder, + * but again the multiple of the polynomial to subtract depends only on + * the high bits, the high 8 bits in this case. + * + * The multile we need in that case is the low 32 bits of a 40-bit + * value whose high 8 bits are given, and which is a multiple of the + * generator polynomial. This is simply the CRC-32 of the given + * one-byte message. + * + * Two more details: normally, appending zero bits to a message which + * is already a multiple of a polynomial produces a larger multiple of that + * polynomial. To enable a CRC to detect this condition, it's common to + * invert the CRC before appending it. This makes the remainder of the + * message+crc come out not as zero, but some fixed non-zero value. + * + * The same problem applies to zero bits prepended to the message, and + * a similar solution is used. Instead of starting with a remainder of + * 0, an initial remainder of all ones is used. As long as you start + * the same way on decoding, it doesn't make a difference. + */ + +#ifdef UNITTEST + +#include +#include + +#ifdef UBI_LINUX /*Not used at present */ +static void +buf_dump(char const *prefix, unsigned char const *buf, size_t len) +{ + fputs(prefix, stdout); + while (len--) + printf(" %02x", *buf++); + putchar('\n'); + +} +#endif + +static void bytereverse(unsigned char *buf, size_t len) +{ + while (len--) { + unsigned char x = bitrev8(*buf); + *buf++ = x; + } +} + +static void random_garbage(unsigned char *buf, size_t len) +{ + while (len--) + *buf++ = (unsigned char) random(); +} + +#ifdef UBI_LINUX /* Not used at present */ +static void store_le(u32 x, unsigned char *buf) +{ + buf[0] = (unsigned char) x; + buf[1] = (unsigned char) (x >> 8); + buf[2] = (unsigned char) (x >> 16); + buf[3] = (unsigned char) (x >> 24); +} +#endif + +static void store_be(u32 x, unsigned char *buf) +{ + buf[0] = (unsigned char) (x >> 24); + buf[1] = (unsigned char) (x >> 16); + buf[2] = (unsigned char) (x >> 8); + buf[3] = (unsigned char) x; +} + +/* + * This checks that CRC(buf + CRC(buf)) = 0, and that + * CRC commutes with bit-reversal. This has the side effect + * of bytewise bit-reversing the input buffer, and returns + * the CRC of the reversed buffer. + */ +static u32 test_step(u32 init, unsigned char *buf, size_t len) +{ + u32 crc1, crc2; + size_t i; + + crc1 = crc32_be(init, buf, len); + store_be(crc1, buf + len); + crc2 = crc32_be(init, buf, len + 4); + if (crc2) + printf("\nCRC cancellation fail: 0x%08x should be 0\n", + crc2); + + for (i = 0; i <= len + 4; i++) { + crc2 = crc32_be(init, buf, i); + crc2 = crc32_be(crc2, buf + i, len + 4 - i); + if (crc2) + printf("\nCRC split fail: 0x%08x\n", crc2); + } + + /* Now swap it around for the other test */ + + bytereverse(buf, len + 4); + init = bitrev32(init); + crc2 = bitrev32(crc1); + if (crc1 != bitrev32(crc2)) + printf("\nBit reversal fail: 0x%08x -> 0x%08x -> 0x%08x\n", + crc1, crc2, bitrev32(crc2)); + crc1 = crc32_le(init, buf, len); + if (crc1 != crc2) + printf("\nCRC endianness fail: 0x%08x != 0x%08x\n", crc1, + crc2); + crc2 = crc32_le(init, buf, len + 4); + if (crc2) + printf("\nCRC cancellation fail: 0x%08x should be 0\n", + crc2); + + for (i = 0; i <= len + 4; i++) { + crc2 = crc32_le(init, buf, i); + crc2 = crc32_le(crc2, buf + i, len + 4 - i); + if (crc2) + printf("\nCRC split fail: 0x%08x\n", crc2); + } + + return crc1; +} + +#define SIZE 64 +#define INIT1 0 +#define INIT2 0 + +int main(void) +{ + unsigned char buf1[SIZE + 4]; + unsigned char buf2[SIZE + 4]; + unsigned char buf3[SIZE + 4]; + int i, j; + u32 crc1, crc2, crc3; + + for (i = 0; i <= SIZE; i++) { + printf("\rTesting length %d...", i); + fflush(stdout); + random_garbage(buf1, i); + random_garbage(buf2, i); + for (j = 0; j < i; j++) + buf3[j] = buf1[j] ^ buf2[j]; + + crc1 = test_step(INIT1, buf1, i); + crc2 = test_step(INIT2, buf2, i); + /* Now check that CRC(buf1 ^ buf2) = CRC(buf1) ^ CRC(buf2) */ + crc3 = test_step(INIT1 ^ INIT2, buf3, i); + if (crc3 != (crc1 ^ crc2)) + printf("CRC XOR fail: 0x%08x != 0x%08x ^ 0x%08x\n", + crc3, crc1, crc2); + } + printf("\nAll test complete. No failures expected.\n"); + return 0; +} + +#endif /* UNITTEST */ -- cgit v1.1 From 961df83361aff9a14f226214224eb8a06e05ba24 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:25:44 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 2/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- drivers/mtd/ubi/crc32defs.h | 32 ++ drivers/mtd/ubi/crc32table.h | 136 +++++ drivers/mtd/ubi/debug.c | 192 +++++++ drivers/mtd/ubi/debug.h | 152 +++++ drivers/mtd/ubi/eba.c | 1256 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1768 insertions(+) create mode 100644 drivers/mtd/ubi/crc32defs.h create mode 100644 drivers/mtd/ubi/crc32table.h create mode 100644 drivers/mtd/ubi/debug.c create mode 100644 drivers/mtd/ubi/debug.h create mode 100644 drivers/mtd/ubi/eba.c diff --git a/drivers/mtd/ubi/crc32defs.h b/drivers/mtd/ubi/crc32defs.h new file mode 100644 index 0000000..f5a5401 --- /dev/null +++ b/drivers/mtd/ubi/crc32defs.h @@ -0,0 +1,32 @@ +/* + * There are multiple 16-bit CRC polynomials in common use, but this is + * *the* standard CRC-32 polynomial, first popularized by Ethernet. + * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 + */ +#define CRCPOLY_LE 0xedb88320 +#define CRCPOLY_BE 0x04c11db7 + +/* How many bits at a time to use. Requires a table of 4< 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1 +# error CRC_LE_BITS must be a power of 2 between 1 and 8 +#endif + +/* + * Big-endian CRC computation. Used with serial bit streams sent + * msbit-first. Be sure to use cpu_to_be32() to append the computed CRC. + */ +#if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1 +# error CRC_BE_BITS must be a power of 2 between 1 and 8 +#endif diff --git a/drivers/mtd/ubi/crc32table.h b/drivers/mtd/ubi/crc32table.h new file mode 100644 index 0000000..0438af4 --- /dev/null +++ b/drivers/mtd/ubi/crc32table.h @@ -0,0 +1,136 @@ +/* this file is generated - do not edit */ + +static const u32 crc32table_le[] = { +tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL), +tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L), +tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L), +tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L), +tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL), +tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L), +tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL), +tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L), +tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L), +tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL), +tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L), +tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L), +tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L), +tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL), +tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L), +tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL), +tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL), +tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L), +tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L), +tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L), +tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL), +tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L), +tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL), +tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L), +tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L), +tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL), +tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L), +tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L), +tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L), +tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL), +tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L), +tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL), +tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL), +tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L), +tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L), +tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L), +tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL), +tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L), +tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL), +tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L), +tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L), +tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL), +tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L), +tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L), +tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L), +tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL), +tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L), +tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL), +tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL), +tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L), +tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L), +tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L), +tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL), +tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L), +tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL), +tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L), +tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L), +tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL), +tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L), +tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L), +tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L), +tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL), +tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L), +tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL) +}; +#ifdef UBI_LINUX +static const u32 crc32table_be[] = { +tobe(0x00000000L), tobe(0x04c11db7L), tobe(0x09823b6eL), tobe(0x0d4326d9L), +tobe(0x130476dcL), tobe(0x17c56b6bL), tobe(0x1a864db2L), tobe(0x1e475005L), +tobe(0x2608edb8L), tobe(0x22c9f00fL), tobe(0x2f8ad6d6L), tobe(0x2b4bcb61L), +tobe(0x350c9b64L), tobe(0x31cd86d3L), tobe(0x3c8ea00aL), tobe(0x384fbdbdL), +tobe(0x4c11db70L), tobe(0x48d0c6c7L), tobe(0x4593e01eL), tobe(0x4152fda9L), +tobe(0x5f15adacL), tobe(0x5bd4b01bL), tobe(0x569796c2L), tobe(0x52568b75L), +tobe(0x6a1936c8L), tobe(0x6ed82b7fL), tobe(0x639b0da6L), tobe(0x675a1011L), +tobe(0x791d4014L), tobe(0x7ddc5da3L), tobe(0x709f7b7aL), tobe(0x745e66cdL), +tobe(0x9823b6e0L), tobe(0x9ce2ab57L), tobe(0x91a18d8eL), tobe(0x95609039L), +tobe(0x8b27c03cL), tobe(0x8fe6dd8bL), tobe(0x82a5fb52L), tobe(0x8664e6e5L), +tobe(0xbe2b5b58L), tobe(0xbaea46efL), tobe(0xb7a96036L), tobe(0xb3687d81L), +tobe(0xad2f2d84L), tobe(0xa9ee3033L), tobe(0xa4ad16eaL), tobe(0xa06c0b5dL), +tobe(0xd4326d90L), tobe(0xd0f37027L), tobe(0xddb056feL), tobe(0xd9714b49L), +tobe(0xc7361b4cL), tobe(0xc3f706fbL), tobe(0xceb42022L), tobe(0xca753d95L), +tobe(0xf23a8028L), tobe(0xf6fb9d9fL), tobe(0xfbb8bb46L), tobe(0xff79a6f1L), +tobe(0xe13ef6f4L), tobe(0xe5ffeb43L), tobe(0xe8bccd9aL), tobe(0xec7dd02dL), +tobe(0x34867077L), tobe(0x30476dc0L), tobe(0x3d044b19L), tobe(0x39c556aeL), +tobe(0x278206abL), tobe(0x23431b1cL), tobe(0x2e003dc5L), tobe(0x2ac12072L), +tobe(0x128e9dcfL), tobe(0x164f8078L), tobe(0x1b0ca6a1L), tobe(0x1fcdbb16L), +tobe(0x018aeb13L), tobe(0x054bf6a4L), tobe(0x0808d07dL), tobe(0x0cc9cdcaL), +tobe(0x7897ab07L), tobe(0x7c56b6b0L), tobe(0x71159069L), tobe(0x75d48ddeL), +tobe(0x6b93dddbL), tobe(0x6f52c06cL), tobe(0x6211e6b5L), tobe(0x66d0fb02L), +tobe(0x5e9f46bfL), tobe(0x5a5e5b08L), tobe(0x571d7dd1L), tobe(0x53dc6066L), +tobe(0x4d9b3063L), tobe(0x495a2dd4L), tobe(0x44190b0dL), tobe(0x40d816baL), +tobe(0xaca5c697L), tobe(0xa864db20L), tobe(0xa527fdf9L), tobe(0xa1e6e04eL), +tobe(0xbfa1b04bL), tobe(0xbb60adfcL), tobe(0xb6238b25L), tobe(0xb2e29692L), +tobe(0x8aad2b2fL), tobe(0x8e6c3698L), tobe(0x832f1041L), tobe(0x87ee0df6L), +tobe(0x99a95df3L), tobe(0x9d684044L), tobe(0x902b669dL), tobe(0x94ea7b2aL), +tobe(0xe0b41de7L), tobe(0xe4750050L), tobe(0xe9362689L), tobe(0xedf73b3eL), +tobe(0xf3b06b3bL), tobe(0xf771768cL), tobe(0xfa325055L), tobe(0xfef34de2L), +tobe(0xc6bcf05fL), tobe(0xc27dede8L), tobe(0xcf3ecb31L), tobe(0xcbffd686L), +tobe(0xd5b88683L), tobe(0xd1799b34L), tobe(0xdc3abdedL), tobe(0xd8fba05aL), +tobe(0x690ce0eeL), tobe(0x6dcdfd59L), tobe(0x608edb80L), tobe(0x644fc637L), +tobe(0x7a089632L), tobe(0x7ec98b85L), tobe(0x738aad5cL), tobe(0x774bb0ebL), +tobe(0x4f040d56L), tobe(0x4bc510e1L), tobe(0x46863638L), tobe(0x42472b8fL), +tobe(0x5c007b8aL), tobe(0x58c1663dL), tobe(0x558240e4L), tobe(0x51435d53L), +tobe(0x251d3b9eL), tobe(0x21dc2629L), tobe(0x2c9f00f0L), tobe(0x285e1d47L), +tobe(0x36194d42L), tobe(0x32d850f5L), tobe(0x3f9b762cL), tobe(0x3b5a6b9bL), +tobe(0x0315d626L), tobe(0x07d4cb91L), tobe(0x0a97ed48L), tobe(0x0e56f0ffL), +tobe(0x1011a0faL), tobe(0x14d0bd4dL), tobe(0x19939b94L), tobe(0x1d528623L), +tobe(0xf12f560eL), tobe(0xf5ee4bb9L), tobe(0xf8ad6d60L), tobe(0xfc6c70d7L), +tobe(0xe22b20d2L), tobe(0xe6ea3d65L), tobe(0xeba91bbcL), tobe(0xef68060bL), +tobe(0xd727bbb6L), tobe(0xd3e6a601L), tobe(0xdea580d8L), tobe(0xda649d6fL), +tobe(0xc423cd6aL), tobe(0xc0e2d0ddL), tobe(0xcda1f604L), tobe(0xc960ebb3L), +tobe(0xbd3e8d7eL), tobe(0xb9ff90c9L), tobe(0xb4bcb610L), tobe(0xb07daba7L), +tobe(0xae3afba2L), tobe(0xaafbe615L), tobe(0xa7b8c0ccL), tobe(0xa379dd7bL), +tobe(0x9b3660c6L), tobe(0x9ff77d71L), tobe(0x92b45ba8L), tobe(0x9675461fL), +tobe(0x8832161aL), tobe(0x8cf30badL), tobe(0x81b02d74L), tobe(0x857130c3L), +tobe(0x5d8a9099L), tobe(0x594b8d2eL), tobe(0x5408abf7L), tobe(0x50c9b640L), +tobe(0x4e8ee645L), tobe(0x4a4ffbf2L), tobe(0x470cdd2bL), tobe(0x43cdc09cL), +tobe(0x7b827d21L), tobe(0x7f436096L), tobe(0x7200464fL), tobe(0x76c15bf8L), +tobe(0x68860bfdL), tobe(0x6c47164aL), tobe(0x61043093L), tobe(0x65c52d24L), +tobe(0x119b4be9L), tobe(0x155a565eL), tobe(0x18197087L), tobe(0x1cd86d30L), +tobe(0x029f3d35L), tobe(0x065e2082L), tobe(0x0b1d065bL), tobe(0x0fdc1becL), +tobe(0x3793a651L), tobe(0x3352bbe6L), tobe(0x3e119d3fL), tobe(0x3ad08088L), +tobe(0x2497d08dL), tobe(0x2056cd3aL), tobe(0x2d15ebe3L), tobe(0x29d4f654L), +tobe(0xc5a92679L), tobe(0xc1683bceL), tobe(0xcc2b1d17L), tobe(0xc8ea00a0L), +tobe(0xd6ad50a5L), tobe(0xd26c4d12L), tobe(0xdf2f6bcbL), tobe(0xdbee767cL), +tobe(0xe3a1cbc1L), tobe(0xe760d676L), tobe(0xea23f0afL), tobe(0xeee2ed18L), +tobe(0xf0a5bd1dL), tobe(0xf464a0aaL), tobe(0xf9278673L), tobe(0xfde69bc4L), +tobe(0x89b8fd09L), tobe(0x8d79e0beL), tobe(0x803ac667L), tobe(0x84fbdbd0L), +tobe(0x9abc8bd5L), tobe(0x9e7d9662L), tobe(0x933eb0bbL), tobe(0x97ffad0cL), +tobe(0xafb010b1L), tobe(0xab710d06L), tobe(0xa6322bdfL), tobe(0xa2f33668L), +tobe(0xbcb4666dL), tobe(0xb8757bdaL), tobe(0xb5365d03L), tobe(0xb1f740b4L) +}; +#endif diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c new file mode 100644 index 0000000..492ab5c --- /dev/null +++ b/drivers/mtd/ubi/debug.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * Here we keep all the UBI debugging stuff which should normally be disabled + * and compiled-out, but it is extremely helpful when hunting bugs or doing big + * changes. + */ +#include + +#ifdef CONFIG_MTD_UBI_DEBUG_MSG + +#include "ubi.h" + +/** + * ubi_dbg_dump_ec_hdr - dump an erase counter header. + * @ec_hdr: the erase counter header to dump + */ +void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) +{ + dbg_msg("erase counter header dump:"); + dbg_msg("magic %#08x", be32_to_cpu(ec_hdr->magic)); + dbg_msg("version %d", (int)ec_hdr->version); + dbg_msg("ec %llu", (long long)be64_to_cpu(ec_hdr->ec)); + dbg_msg("vid_hdr_offset %d", be32_to_cpu(ec_hdr->vid_hdr_offset)); + dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset)); + dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc)); + dbg_msg("erase counter header hexdump:"); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + ec_hdr, UBI_EC_HDR_SIZE, 1); +} + +/** + * ubi_dbg_dump_vid_hdr - dump a volume identifier header. + * @vid_hdr: the volume identifier header to dump + */ +void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) +{ + dbg_msg("volume identifier header dump:"); + dbg_msg("magic %08x", be32_to_cpu(vid_hdr->magic)); + dbg_msg("version %d", (int)vid_hdr->version); + dbg_msg("vol_type %d", (int)vid_hdr->vol_type); + dbg_msg("copy_flag %d", (int)vid_hdr->copy_flag); + dbg_msg("compat %d", (int)vid_hdr->compat); + dbg_msg("vol_id %d", be32_to_cpu(vid_hdr->vol_id)); + dbg_msg("lnum %d", be32_to_cpu(vid_hdr->lnum)); + dbg_msg("leb_ver %u", be32_to_cpu(vid_hdr->leb_ver)); + dbg_msg("data_size %d", be32_to_cpu(vid_hdr->data_size)); + dbg_msg("used_ebs %d", be32_to_cpu(vid_hdr->used_ebs)); + dbg_msg("data_pad %d", be32_to_cpu(vid_hdr->data_pad)); + dbg_msg("sqnum %llu", + (unsigned long long)be64_to_cpu(vid_hdr->sqnum)); + dbg_msg("hdr_crc %08x", be32_to_cpu(vid_hdr->hdr_crc)); + dbg_msg("volume identifier header hexdump:"); +} + +/** + * ubi_dbg_dump_vol_info- dump volume information. + * @vol: UBI volume description object + */ +void ubi_dbg_dump_vol_info(const struct ubi_volume *vol) +{ + dbg_msg("volume information dump:"); + dbg_msg("vol_id %d", vol->vol_id); + dbg_msg("reserved_pebs %d", vol->reserved_pebs); + dbg_msg("alignment %d", vol->alignment); + dbg_msg("data_pad %d", vol->data_pad); + dbg_msg("vol_type %d", vol->vol_type); + dbg_msg("name_len %d", vol->name_len); + dbg_msg("usable_leb_size %d", vol->usable_leb_size); + dbg_msg("used_ebs %d", vol->used_ebs); + dbg_msg("used_bytes %lld", vol->used_bytes); + dbg_msg("last_eb_bytes %d", vol->last_eb_bytes); + dbg_msg("corrupted %d", vol->corrupted); + dbg_msg("upd_marker %d", vol->upd_marker); + + if (vol->name_len <= UBI_VOL_NAME_MAX && + strnlen(vol->name, vol->name_len + 1) == vol->name_len) { + dbg_msg("name %s", vol->name); + } else { + dbg_msg("the 1st 5 characters of the name: %c%c%c%c%c", + vol->name[0], vol->name[1], vol->name[2], + vol->name[3], vol->name[4]); + } +} + +/** + * ubi_dbg_dump_vtbl_record - dump a &struct ubi_vtbl_record object. + * @r: the object to dump + * @idx: volume table index + */ +void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) +{ + int name_len = be16_to_cpu(r->name_len); + + dbg_msg("volume table record %d dump:", idx); + dbg_msg("reserved_pebs %d", be32_to_cpu(r->reserved_pebs)); + dbg_msg("alignment %d", be32_to_cpu(r->alignment)); + dbg_msg("data_pad %d", be32_to_cpu(r->data_pad)); + dbg_msg("vol_type %d", (int)r->vol_type); + dbg_msg("upd_marker %d", (int)r->upd_marker); + dbg_msg("name_len %d", name_len); + + if (r->name[0] == '\0') { + dbg_msg("name NULL"); + return; + } + + if (name_len <= UBI_VOL_NAME_MAX && + strnlen(&r->name[0], name_len + 1) == name_len) { + dbg_msg("name %s", &r->name[0]); + } else { + dbg_msg("1st 5 characters of the name: %c%c%c%c%c", + r->name[0], r->name[1], r->name[2], r->name[3], + r->name[4]); + } + dbg_msg("crc %#08x", be32_to_cpu(r->crc)); +} + +/** + * ubi_dbg_dump_sv - dump a &struct ubi_scan_volume object. + * @sv: the object to dump + */ +void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) +{ + dbg_msg("volume scanning information dump:"); + dbg_msg("vol_id %d", sv->vol_id); + dbg_msg("highest_lnum %d", sv->highest_lnum); + dbg_msg("leb_count %d", sv->leb_count); + dbg_msg("compat %d", sv->compat); + dbg_msg("vol_type %d", sv->vol_type); + dbg_msg("used_ebs %d", sv->used_ebs); + dbg_msg("last_data_size %d", sv->last_data_size); + dbg_msg("data_pad %d", sv->data_pad); +} + +/** + * ubi_dbg_dump_seb - dump a &struct ubi_scan_leb object. + * @seb: the object to dump + * @type: object type: 0 - not corrupted, 1 - corrupted + */ +void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type) +{ + dbg_msg("eraseblock scanning information dump:"); + dbg_msg("ec %d", seb->ec); + dbg_msg("pnum %d", seb->pnum); + if (type == 0) { + dbg_msg("lnum %d", seb->lnum); + dbg_msg("scrub %d", seb->scrub); + dbg_msg("sqnum %llu", seb->sqnum); + dbg_msg("leb_ver %u", seb->leb_ver); + } +} + +/** + * ubi_dbg_dump_mkvol_req - dump a &struct ubi_mkvol_req object. + * @req: the object to dump + */ +void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) +{ + char nm[17]; + + dbg_msg("volume creation request dump:"); + dbg_msg("vol_id %d", req->vol_id); + dbg_msg("alignment %d", req->alignment); + dbg_msg("bytes %lld", (long long)req->bytes); + dbg_msg("vol_type %d", req->vol_type); + dbg_msg("name_len %d", req->name_len); + + memcpy(nm, req->name, 16); + nm[16] = 0; + dbg_msg("the 1st 16 characters of the name: %s", nm); +} + +#endif /* CONFIG_MTD_UBI_DEBUG_MSG */ diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h new file mode 100644 index 0000000..b44380b --- /dev/null +++ b/drivers/mtd/ubi/debug.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __UBI_DEBUG_H__ +#define __UBI_DEBUG_H__ + +#ifdef CONFIG_MTD_UBI_DEBUG +#ifdef UBI_LINUX +#include +#endif + +#define ubi_assert(expr) BUG_ON(!(expr)) +#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__) +#else +#define ubi_assert(expr) ({}) +#define dbg_err(fmt, ...) ({}) +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT +#define DBG_DISABLE_BGT 1 +#else +#define DBG_DISABLE_BGT 0 +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_MSG +/* Generic debugging message */ +#define dbg_msg(fmt, ...) \ + printk(KERN_DEBUG "UBI DBG: %s: " fmt "\n", \ + __FUNCTION__, ##__VA_ARGS__) + +#define ubi_dbg_dump_stack() dump_stack() + +struct ubi_ec_hdr; +struct ubi_vid_hdr; +struct ubi_volume; +struct ubi_vtbl_record; +struct ubi_scan_volume; +struct ubi_scan_leb; +struct ubi_mkvol_req; + +void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr); +void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); +void ubi_dbg_dump_vol_info(const struct ubi_volume *vol); +void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); +void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); +void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); +void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); + +#else + +#define dbg_msg(fmt, ...) ({}) +#define ubi_dbg_dump_stack() ({}) +#define ubi_dbg_dump_ec_hdr(ec_hdr) ({}) +#define ubi_dbg_dump_vid_hdr(vid_hdr) ({}) +#define ubi_dbg_dump_vol_info(vol) ({}) +#define ubi_dbg_dump_vtbl_record(r, idx) ({}) +#define ubi_dbg_dump_sv(sv) ({}) +#define ubi_dbg_dump_seb(seb, type) ({}) +#define ubi_dbg_dump_mkvol_req(req) ({}) + +#endif /* CONFIG_MTD_UBI_DEBUG_MSG */ + +#ifdef CONFIG_MTD_UBI_DEBUG_MSG_EBA +/* Messages from the eraseblock association unit */ +#define dbg_eba(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) +#else +#define dbg_eba(fmt, ...) ({}) +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_MSG_WL +/* Messages from the wear-leveling unit */ +#define dbg_wl(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) +#else +#define dbg_wl(fmt, ...) ({}) +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_MSG_IO +/* Messages from the input/output unit */ +#define dbg_io(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) +#else +#define dbg_io(fmt, ...) ({}) +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_MSG_BLD +/* Initialization and build messages */ +#define dbg_bld(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) +#else +#define dbg_bld(fmt, ...) ({}) +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_BITFLIPS +/** + * ubi_dbg_is_bitflip - if it is time to emulate a bit-flip. + * + * Returns non-zero if a bit-flip should be emulated, otherwise returns zero. + */ +static inline int ubi_dbg_is_bitflip(void) +{ + return !(random32() % 200); +} +#else +#define ubi_dbg_is_bitflip() 0 +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_WRITE_FAILURES +/** + * ubi_dbg_is_write_failure - if it is time to emulate a write failure. + * + * Returns non-zero if a write failure should be emulated, otherwise returns + * zero. + */ +static inline int ubi_dbg_is_write_failure(void) +{ + return !(random32() % 500); +} +#else +#define ubi_dbg_is_write_failure() 0 +#endif + +#ifdef CONFIG_MTD_UBI_DEBUG_EMULATE_ERASE_FAILURES +/** + * ubi_dbg_is_erase_failure - if its time to emulate an erase failure. + * + * Returns non-zero if an erase failure should be emulated, otherwise returns + * zero. + */ +static inline int ubi_dbg_is_erase_failure(void) +{ + return !(random32() % 400); +} +#else +#define ubi_dbg_is_erase_failure() 0 +#endif + +#endif /* !__UBI_DEBUG_H__ */ diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c new file mode 100644 index 0000000..d523c94 --- /dev/null +++ b/drivers/mtd/ubi/eba.c @@ -0,0 +1,1256 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * The UBI Eraseblock Association (EBA) unit. + * + * This unit is responsible for I/O to/from logical eraseblock. + * + * Although in this implementation the EBA table is fully kept and managed in + * RAM, which assumes poor scalability, it might be (partially) maintained on + * flash in future implementations. + * + * The EBA unit implements per-logical eraseblock locking. Before accessing a + * logical eraseblock it is locked for reading or writing. The per-logical + * eraseblock locking is implemented by means of the lock tree. The lock tree + * is an RB-tree which refers all the currently locked logical eraseblocks. The + * lock tree elements are &struct ubi_ltree_entry objects. They are indexed by + * (@vol_id, @lnum) pairs. + * + * EBA also maintains the global sequence counter which is incremented each + * time a logical eraseblock is mapped to a physical eraseblock and it is + * stored in the volume identifier header. This means that each VID header has + * a unique sequence number. The sequence number is only increased an we assume + * 64 bits is enough to never overflow. + */ + +#ifdef UBI_LINUX +#include +#include +#include +#endif + +#include +#include "ubi.h" + +/* Number of physical eraseblocks reserved for atomic LEB change operation */ +#define EBA_RESERVED_PEBS 1 + +/** + * next_sqnum - get next sequence number. + * @ubi: UBI device description object + * + * This function returns next sequence number to use, which is just the current + * global sequence counter value. It also increases the global sequence + * counter. + */ +static unsigned long long next_sqnum(struct ubi_device *ubi) +{ + unsigned long long sqnum; + + spin_lock(&ubi->ltree_lock); + sqnum = ubi->global_sqnum++; + spin_unlock(&ubi->ltree_lock); + + return sqnum; +} + +/** + * ubi_get_compat - get compatibility flags of a volume. + * @ubi: UBI device description object + * @vol_id: volume ID + * + * This function returns compatibility flags for an internal volume. User + * volumes have no compatibility flags, so %0 is returned. + */ +static int ubi_get_compat(const struct ubi_device *ubi, int vol_id) +{ + if (vol_id == UBI_LAYOUT_VOLUME_ID) + return UBI_LAYOUT_VOLUME_COMPAT; + return 0; +} + +/** + * ltree_lookup - look up the lock tree. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + * + * This function returns a pointer to the corresponding &struct ubi_ltree_entry + * object if the logical eraseblock is locked and %NULL if it is not. + * @ubi->ltree_lock has to be locked. + */ +static struct ubi_ltree_entry *ltree_lookup(struct ubi_device *ubi, int vol_id, + int lnum) +{ + struct rb_node *p; + + p = ubi->ltree.rb_node; + while (p) { + struct ubi_ltree_entry *le; + + le = rb_entry(p, struct ubi_ltree_entry, rb); + + if (vol_id < le->vol_id) + p = p->rb_left; + else if (vol_id > le->vol_id) + p = p->rb_right; + else { + if (lnum < le->lnum) + p = p->rb_left; + else if (lnum > le->lnum) + p = p->rb_right; + else + return le; + } + } + + return NULL; +} + +/** + * ltree_add_entry - add new entry to the lock tree. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + * + * This function adds new entry for logical eraseblock (@vol_id, @lnum) to the + * lock tree. If such entry is already there, its usage counter is increased. + * Returns pointer to the lock tree entry or %-ENOMEM if memory allocation + * failed. + */ +static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, + int vol_id, int lnum) +{ + struct ubi_ltree_entry *le, *le1, *le_free; + + le = kmalloc(sizeof(struct ubi_ltree_entry), GFP_NOFS); + if (!le) + return ERR_PTR(-ENOMEM); + + le->users = 0; + init_rwsem(&le->mutex); + le->vol_id = vol_id; + le->lnum = lnum; + + spin_lock(&ubi->ltree_lock); + le1 = ltree_lookup(ubi, vol_id, lnum); + + if (le1) { + /* + * This logical eraseblock is already locked. The newly + * allocated lock entry is not needed. + */ + le_free = le; + le = le1; + } else { + struct rb_node **p, *parent = NULL; + + /* + * No lock entry, add the newly allocated one to the + * @ubi->ltree RB-tree. + */ + le_free = NULL; + + p = &ubi->ltree.rb_node; + while (*p) { + parent = *p; + le1 = rb_entry(parent, struct ubi_ltree_entry, rb); + + if (vol_id < le1->vol_id) + p = &(*p)->rb_left; + else if (vol_id > le1->vol_id) + p = &(*p)->rb_right; + else { + ubi_assert(lnum != le1->lnum); + if (lnum < le1->lnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + } + + rb_link_node(&le->rb, parent, p); + rb_insert_color(&le->rb, &ubi->ltree); + } + le->users += 1; + spin_unlock(&ubi->ltree_lock); + + if (le_free) + kfree(le_free); + + return le; +} + +/** + * leb_read_lock - lock logical eraseblock for reading. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + * + * This function locks a logical eraseblock for reading. Returns zero in case + * of success and a negative error code in case of failure. + */ +static int leb_read_lock(struct ubi_device *ubi, int vol_id, int lnum) +{ + struct ubi_ltree_entry *le; + + le = ltree_add_entry(ubi, vol_id, lnum); + if (IS_ERR(le)) + return PTR_ERR(le); + down_read(&le->mutex); + return 0; +} + +/** + * leb_read_unlock - unlock logical eraseblock. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + */ +static void leb_read_unlock(struct ubi_device *ubi, int vol_id, int lnum) +{ + int _free = 0; + struct ubi_ltree_entry *le; + + spin_lock(&ubi->ltree_lock); + le = ltree_lookup(ubi, vol_id, lnum); + le->users -= 1; + ubi_assert(le->users >= 0); + if (le->users == 0) { + rb_erase(&le->rb, &ubi->ltree); + _free = 1; + } + spin_unlock(&ubi->ltree_lock); + + up_read(&le->mutex); + if (_free) + kfree(le); +} + +/** + * leb_write_lock - lock logical eraseblock for writing. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + * + * This function locks a logical eraseblock for writing. Returns zero in case + * of success and a negative error code in case of failure. + */ +static int leb_write_lock(struct ubi_device *ubi, int vol_id, int lnum) +{ + struct ubi_ltree_entry *le; + + le = ltree_add_entry(ubi, vol_id, lnum); + if (IS_ERR(le)) + return PTR_ERR(le); + down_write(&le->mutex); + return 0; +} + +/** + * leb_write_lock - lock logical eraseblock for writing. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + * + * This function locks a logical eraseblock for writing if there is no + * contention and does nothing if there is contention. Returns %0 in case of + * success, %1 in case of contention, and and a negative error code in case of + * failure. + */ +static int leb_write_trylock(struct ubi_device *ubi, int vol_id, int lnum) +{ + int _free; + struct ubi_ltree_entry *le; + + le = ltree_add_entry(ubi, vol_id, lnum); + if (IS_ERR(le)) + return PTR_ERR(le); + if (down_write_trylock(&le->mutex)) + return 0; + + /* Contention, cancel */ + spin_lock(&ubi->ltree_lock); + le->users -= 1; + ubi_assert(le->users >= 0); + if (le->users == 0) { + rb_erase(&le->rb, &ubi->ltree); + _free = 1; + } else + _free = 0; + spin_unlock(&ubi->ltree_lock); + if (_free) + kfree(le); + + return 1; +} + +/** + * leb_write_unlock - unlock logical eraseblock. + * @ubi: UBI device description object + * @vol_id: volume ID + * @lnum: logical eraseblock number + */ +static void leb_write_unlock(struct ubi_device *ubi, int vol_id, int lnum) +{ + int _free; + struct ubi_ltree_entry *le; + + spin_lock(&ubi->ltree_lock); + le = ltree_lookup(ubi, vol_id, lnum); + le->users -= 1; + ubi_assert(le->users >= 0); + if (le->users == 0) { + rb_erase(&le->rb, &ubi->ltree); + _free = 1; + } else + _free = 0; + spin_unlock(&ubi->ltree_lock); + + up_write(&le->mutex); + if (_free) + kfree(le); +} + +/** + * ubi_eba_unmap_leb - un-map logical eraseblock. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * + * This function un-maps logical eraseblock @lnum and schedules corresponding + * physical eraseblock for erasure. Returns zero in case of success and a + * negative error code in case of failure. + */ +int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, + int lnum) +{ + int err, pnum, vol_id = vol->vol_id; + + if (ubi->ro_mode) + return -EROFS; + + err = leb_write_lock(ubi, vol_id, lnum); + if (err) + return err; + + pnum = vol->eba_tbl[lnum]; + if (pnum < 0) + /* This logical eraseblock is already unmapped */ + goto out_unlock; + + dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum); + + vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED; + err = ubi_wl_put_peb(ubi, pnum, 0); + +out_unlock: + leb_write_unlock(ubi, vol_id, lnum); + return err; +} + +/** + * ubi_eba_read_leb - read data. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @buf: buffer to store the read data + * @offset: offset from where to read + * @len: how many bytes to read + * @check: data CRC check flag + * + * If the logical eraseblock @lnum is unmapped, @buf is filled with 0xFF + * bytes. The @check flag only makes sense for static volumes and forces + * eraseblock data CRC checking. + * + * In case of success this function returns zero. In case of a static volume, + * if data CRC mismatches - %-EBADMSG is returned. %-EBADMSG may also be + * returned for any volume type if an ECC error was detected by the MTD device + * driver. Other negative error cored may be returned in case of other errors. + */ +int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + void *buf, int offset, int len, int check) +{ + int err, pnum, scrub = 0, vol_id = vol->vol_id; + struct ubi_vid_hdr *vid_hdr; + uint32_t uninitialized_var(crc); + + err = leb_read_lock(ubi, vol_id, lnum); + if (err) + return err; + + pnum = vol->eba_tbl[lnum]; + if (pnum < 0) { + /* + * The logical eraseblock is not mapped, fill the whole buffer + * with 0xFF bytes. The exception is static volumes for which + * it is an error to read unmapped logical eraseblocks. + */ + dbg_eba("read %d bytes from offset %d of LEB %d:%d (unmapped)", + len, offset, vol_id, lnum); + leb_read_unlock(ubi, vol_id, lnum); + ubi_assert(vol->vol_type != UBI_STATIC_VOLUME); + memset(buf, 0xFF, len); + return 0; + } + + dbg_eba("read %d bytes from offset %d of LEB %d:%d, PEB %d", + len, offset, vol_id, lnum, pnum); + + if (vol->vol_type == UBI_DYNAMIC_VOLUME) + check = 0; + +retry: + if (check) { + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) { + err = -ENOMEM; + goto out_unlock; + } + + err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); + if (err && err != UBI_IO_BITFLIPS) { + if (err > 0) { + /* + * The header is either absent or corrupted. + * The former case means there is a bug - + * switch to read-only mode just in case. + * The latter case means a real corruption - we + * may try to recover data. FIXME: but this is + * not implemented. + */ + if (err == UBI_IO_BAD_VID_HDR) { + ubi_warn("bad VID header at PEB %d, LEB" + "%d:%d", pnum, vol_id, lnum); + err = -EBADMSG; + } else + ubi_ro_mode(ubi); + } + goto out_free; + } else if (err == UBI_IO_BITFLIPS) + scrub = 1; + + ubi_assert(lnum < be32_to_cpu(vid_hdr->used_ebs)); + ubi_assert(len == be32_to_cpu(vid_hdr->data_size)); + + crc = be32_to_cpu(vid_hdr->data_crc); + ubi_free_vid_hdr(ubi, vid_hdr); + } + + err = ubi_io_read_data(ubi, buf, pnum, offset, len); + if (err) { + if (err == UBI_IO_BITFLIPS) { + scrub = 1; + err = 0; + } else if (err == -EBADMSG) { + if (vol->vol_type == UBI_DYNAMIC_VOLUME) + goto out_unlock; + scrub = 1; + if (!check) { + ubi_msg("force data checking"); + check = 1; + goto retry; + } + } else + goto out_unlock; + } + + if (check) { + uint32_t crc1 = crc32(UBI_CRC32_INIT, buf, len); + if (crc1 != crc) { + ubi_warn("CRC error: calculated %#08x, must be %#08x", + crc1, crc); + err = -EBADMSG; + goto out_unlock; + } + } + + if (scrub) + err = ubi_wl_scrub_peb(ubi, pnum); + + leb_read_unlock(ubi, vol_id, lnum); + return err; + +out_free: + ubi_free_vid_hdr(ubi, vid_hdr); +out_unlock: + leb_read_unlock(ubi, vol_id, lnum); + return err; +} + +/** + * recover_peb - recover from write failure. + * @ubi: UBI device description object + * @pnum: the physical eraseblock to recover + * @vol_id: volume ID + * @lnum: logical eraseblock number + * @buf: data which was not written because of the write failure + * @offset: offset of the failed write + * @len: how many bytes should have been written + * + * This function is called in case of a write failure and moves all good data + * from the potentially bad physical eraseblock to a good physical eraseblock. + * This function also writes the data which was not written due to the failure. + * Returns new physical eraseblock number in case of success, and a negative + * error code in case of failure. + */ +static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, + const void *buf, int offset, int len) +{ + int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; + struct ubi_volume *vol = ubi->volumes[idx]; + struct ubi_vid_hdr *vid_hdr; + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) { + return -ENOMEM; + } + + mutex_lock(&ubi->buf_mutex); + +retry: + new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); + if (new_pnum < 0) { + mutex_unlock(&ubi->buf_mutex); + ubi_free_vid_hdr(ubi, vid_hdr); + return new_pnum; + } + + ubi_msg("recover PEB %d, move data to PEB %d", pnum, new_pnum); + + err = ubi_io_read_vid_hdr(ubi, pnum, vid_hdr, 1); + if (err && err != UBI_IO_BITFLIPS) { + if (err > 0) + err = -EIO; + goto out_put; + } + + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); + if (err) + goto write_error; + + data_size = offset + len; + memset(ubi->peb_buf1 + offset, 0xFF, len); + + /* Read everything before the area where the write failure happened */ + if (offset > 0) { + err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); + if (err && err != UBI_IO_BITFLIPS) + goto out_put; + } + + memcpy(ubi->peb_buf1 + offset, buf, len); + + err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); + if (err) + goto write_error; + + mutex_unlock(&ubi->buf_mutex); + ubi_free_vid_hdr(ubi, vid_hdr); + + vol->eba_tbl[lnum] = new_pnum; + ubi_wl_put_peb(ubi, pnum, 1); + + ubi_msg("data was successfully recovered"); + return 0; + +out_put: + mutex_unlock(&ubi->buf_mutex); + ubi_wl_put_peb(ubi, new_pnum, 1); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + +write_error: + /* + * Bad luck? This physical eraseblock is bad too? Crud. Let's try to + * get another one. + */ + ubi_warn("failed to write to PEB %d", new_pnum); + ubi_wl_put_peb(ubi, new_pnum, 1); + if (++tries > UBI_IO_RETRIES) { + mutex_unlock(&ubi->buf_mutex); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + } + ubi_msg("try again"); + goto retry; +} + +/** + * ubi_eba_write_leb - write data to dynamic volume. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @buf: the data to write + * @offset: offset within the logical eraseblock where to write + * @len: how many bytes to write + * @dtype: data type + * + * This function writes data to logical eraseblock @lnum of a dynamic volume + * @vol. Returns zero in case of success and a negative error code in case + * of failure. In case of error, it is possible that something was still + * written to the flash media, but may be some garbage. + */ +int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + const void *buf, int offset, int len, int dtype) +{ + int err, pnum, tries = 0, vol_id = vol->vol_id; + struct ubi_vid_hdr *vid_hdr; + + if (ubi->ro_mode) + return -EROFS; + + err = leb_write_lock(ubi, vol_id, lnum); + if (err) + return err; + + pnum = vol->eba_tbl[lnum]; + if (pnum >= 0) { + dbg_eba("write %d bytes at offset %d of LEB %d:%d, PEB %d", + len, offset, vol_id, lnum, pnum); + + err = ubi_io_write_data(ubi, buf, pnum, offset, len); + if (err) { + ubi_warn("failed to write data to PEB %d", pnum); + if (err == -EIO && ubi->bad_allowed) + err = recover_peb(ubi, pnum, vol_id, lnum, buf, + offset, len); + if (err) + ubi_ro_mode(ubi); + } + leb_write_unlock(ubi, vol_id, lnum); + return err; + } + + /* + * The logical eraseblock is not mapped. We have to get a free physical + * eraseblock and write the volume identifier header there first. + */ + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) { + leb_write_unlock(ubi, vol_id, lnum); + return -ENOMEM; + } + + vid_hdr->vol_type = UBI_VID_DYNAMIC; + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->vol_id = cpu_to_be32(vol_id); + vid_hdr->lnum = cpu_to_be32(lnum); + vid_hdr->compat = ubi_get_compat(ubi, vol_id); + vid_hdr->data_pad = cpu_to_be32(vol->data_pad); + +retry: + pnum = ubi_wl_get_peb(ubi, dtype); + if (pnum < 0) { + ubi_free_vid_hdr(ubi, vid_hdr); + leb_write_unlock(ubi, vol_id, lnum); + return pnum; + } + + dbg_eba("write VID hdr and %d bytes at offset %d of LEB %d:%d, PEB %d", + len, offset, vol_id, lnum, pnum); + + err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); + if (err) { + ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + vol_id, lnum, pnum); + goto write_error; + } + + if (len) { + err = ubi_io_write_data(ubi, buf, pnum, offset, len); + if (err) { + ubi_warn("failed to write %d bytes at offset %d of " + "LEB %d:%d, PEB %d", len, offset, vol_id, + lnum, pnum); + goto write_error; + } + } + + vol->eba_tbl[lnum] = pnum; + + leb_write_unlock(ubi, vol_id, lnum); + ubi_free_vid_hdr(ubi, vid_hdr); + return 0; + +write_error: + if (err != -EIO || !ubi->bad_allowed) { + ubi_ro_mode(ubi); + leb_write_unlock(ubi, vol_id, lnum); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + } + + /* + * Fortunately, this is the first write operation to this physical + * eraseblock, so just put it and request a new one. We assume that if + * this physical eraseblock went bad, the erase code will handle that. + */ + err = ubi_wl_put_peb(ubi, pnum, 1); + if (err || ++tries > UBI_IO_RETRIES) { + ubi_ro_mode(ubi); + leb_write_unlock(ubi, vol_id, lnum); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + } + + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + ubi_msg("try another PEB"); + goto retry; +} + +/** + * ubi_eba_write_leb_st - write data to static volume. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @buf: data to write + * @len: how many bytes to write + * @dtype: data type + * @used_ebs: how many logical eraseblocks will this volume contain + * + * This function writes data to logical eraseblock @lnum of static volume + * @vol. The @used_ebs argument should contain total number of logical + * eraseblock in this static volume. + * + * When writing to the last logical eraseblock, the @len argument doesn't have + * to be aligned to the minimal I/O unit size. Instead, it has to be equivalent + * to the real data size, although the @buf buffer has to contain the + * alignment. In all other cases, @len has to be aligned. + * + * It is prohibited to write more then once to logical eraseblocks of static + * volumes. This function returns zero in case of success and a negative error + * code in case of failure. + */ +int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, + int lnum, const void *buf, int len, int dtype, + int used_ebs) +{ + int err, pnum, tries = 0, data_size = len, vol_id = vol->vol_id; + struct ubi_vid_hdr *vid_hdr; + uint32_t crc; + + if (ubi->ro_mode) + return -EROFS; + + if (lnum == used_ebs - 1) + /* If this is the last LEB @len may be unaligned */ + len = ALIGN(data_size, ubi->min_io_size); + else + ubi_assert(!(len & (ubi->min_io_size - 1))); + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) + return -ENOMEM; + + err = leb_write_lock(ubi, vol_id, lnum); + if (err) { + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + } + + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->vol_id = cpu_to_be32(vol_id); + vid_hdr->lnum = cpu_to_be32(lnum); + vid_hdr->compat = ubi_get_compat(ubi, vol_id); + vid_hdr->data_pad = cpu_to_be32(vol->data_pad); + + crc = crc32(UBI_CRC32_INIT, buf, data_size); + vid_hdr->vol_type = UBI_VID_STATIC; + vid_hdr->data_size = cpu_to_be32(data_size); + vid_hdr->used_ebs = cpu_to_be32(used_ebs); + vid_hdr->data_crc = cpu_to_be32(crc); + +retry: + pnum = ubi_wl_get_peb(ubi, dtype); + if (pnum < 0) { + ubi_free_vid_hdr(ubi, vid_hdr); + leb_write_unlock(ubi, vol_id, lnum); + return pnum; + } + + dbg_eba("write VID hdr and %d bytes at LEB %d:%d, PEB %d, used_ebs %d", + len, vol_id, lnum, pnum, used_ebs); + + err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); + if (err) { + ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + vol_id, lnum, pnum); + goto write_error; + } + + err = ubi_io_write_data(ubi, buf, pnum, 0, len); + if (err) { + ubi_warn("failed to write %d bytes of data to PEB %d", + len, pnum); + goto write_error; + } + + ubi_assert(vol->eba_tbl[lnum] < 0); + vol->eba_tbl[lnum] = pnum; + + leb_write_unlock(ubi, vol_id, lnum); + ubi_free_vid_hdr(ubi, vid_hdr); + return 0; + +write_error: + if (err != -EIO || !ubi->bad_allowed) { + /* + * This flash device does not admit of bad eraseblocks or + * something nasty and unexpected happened. Switch to read-only + * mode just in case. + */ + ubi_ro_mode(ubi); + leb_write_unlock(ubi, vol_id, lnum); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + } + + err = ubi_wl_put_peb(ubi, pnum, 1); + if (err || ++tries > UBI_IO_RETRIES) { + ubi_ro_mode(ubi); + leb_write_unlock(ubi, vol_id, lnum); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + } + + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + ubi_msg("try another PEB"); + goto retry; +} + +/* + * ubi_eba_atomic_leb_change - change logical eraseblock atomically. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @buf: data to write + * @len: how many bytes to write + * @dtype: data type + * + * This function changes the contents of a logical eraseblock atomically. @buf + * has to contain new logical eraseblock data, and @len - the length of the + * data, which has to be aligned. This function guarantees that in case of an + * unclean reboot the old contents is preserved. Returns zero in case of + * success and a negative error code in case of failure. + * + * UBI reserves one LEB for the "atomic LEB change" operation, so only one + * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. + */ +int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, + int lnum, const void *buf, int len, int dtype) +{ + int err, pnum, tries = 0, vol_id = vol->vol_id; + struct ubi_vid_hdr *vid_hdr; + uint32_t crc; + + if (ubi->ro_mode) + return -EROFS; + + if (len == 0) { + /* + * Special case when data length is zero. In this case the LEB + * has to be unmapped and mapped somewhere else. + */ + err = ubi_eba_unmap_leb(ubi, vol, lnum); + if (err) + return err; + return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); + } + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) + return -ENOMEM; + + mutex_lock(&ubi->alc_mutex); + err = leb_write_lock(ubi, vol_id, lnum); + if (err) + goto out_mutex; + + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + vid_hdr->vol_id = cpu_to_be32(vol_id); + vid_hdr->lnum = cpu_to_be32(lnum); + vid_hdr->compat = ubi_get_compat(ubi, vol_id); + vid_hdr->data_pad = cpu_to_be32(vol->data_pad); + + crc = crc32(UBI_CRC32_INIT, buf, len); + vid_hdr->vol_type = UBI_VID_DYNAMIC; + vid_hdr->data_size = cpu_to_be32(len); + vid_hdr->copy_flag = 1; + vid_hdr->data_crc = cpu_to_be32(crc); + +retry: + pnum = ubi_wl_get_peb(ubi, dtype); + if (pnum < 0) { + err = pnum; + goto out_leb_unlock; + } + + dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d", + vol_id, lnum, vol->eba_tbl[lnum], pnum); + + err = ubi_io_write_vid_hdr(ubi, pnum, vid_hdr); + if (err) { + ubi_warn("failed to write VID header to LEB %d:%d, PEB %d", + vol_id, lnum, pnum); + goto write_error; + } + + err = ubi_io_write_data(ubi, buf, pnum, 0, len); + if (err) { + ubi_warn("failed to write %d bytes of data to PEB %d", + len, pnum); + goto write_error; + } + + if (vol->eba_tbl[lnum] >= 0) { + err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1); + if (err) + goto out_leb_unlock; + } + + vol->eba_tbl[lnum] = pnum; + +out_leb_unlock: + leb_write_unlock(ubi, vol_id, lnum); +out_mutex: + mutex_unlock(&ubi->alc_mutex); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + +write_error: + if (err != -EIO || !ubi->bad_allowed) { + /* + * This flash device does not admit of bad eraseblocks or + * something nasty and unexpected happened. Switch to read-only + * mode just in case. + */ + ubi_ro_mode(ubi); + goto out_leb_unlock; + } + + err = ubi_wl_put_peb(ubi, pnum, 1); + if (err || ++tries > UBI_IO_RETRIES) { + ubi_ro_mode(ubi); + goto out_leb_unlock; + } + + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + ubi_msg("try another PEB"); + goto retry; +} + +/** + * ubi_eba_copy_leb - copy logical eraseblock. + * @ubi: UBI device description object + * @from: physical eraseblock number from where to copy + * @to: physical eraseblock number where to copy + * @vid_hdr: VID header of the @from physical eraseblock + * + * This function copies logical eraseblock from physical eraseblock @from to + * physical eraseblock @to. The @vid_hdr buffer may be changed by this + * function. Returns: + * o %0 in case of success; + * o %1 if the operation was canceled and should be tried later (e.g., + * because a bit-flip was detected at the target PEB); + * o %2 if the volume is being deleted and this LEB should not be moved. + */ +int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, + struct ubi_vid_hdr *vid_hdr) +{ + int err, vol_id, lnum, data_size, aldata_size, idx; + struct ubi_volume *vol; + uint32_t crc; + + vol_id = be32_to_cpu(vid_hdr->vol_id); + lnum = be32_to_cpu(vid_hdr->lnum); + + dbg_eba("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to); + + if (vid_hdr->vol_type == UBI_VID_STATIC) { + data_size = be32_to_cpu(vid_hdr->data_size); + aldata_size = ALIGN(data_size, ubi->min_io_size); + } else + data_size = aldata_size = + ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); + + idx = vol_id2idx(ubi, vol_id); + spin_lock(&ubi->volumes_lock); + /* + * Note, we may race with volume deletion, which means that the volume + * this logical eraseblock belongs to might be being deleted. Since the + * volume deletion unmaps all the volume's logical eraseblocks, it will + * be locked in 'ubi_wl_put_peb()' and wait for the WL worker to finish. + */ + vol = ubi->volumes[idx]; + if (!vol) { + /* No need to do further work, cancel */ + dbg_eba("volume %d is being removed, cancel", vol_id); + spin_unlock(&ubi->volumes_lock); + return 2; + } + spin_unlock(&ubi->volumes_lock); + + /* + * We do not want anybody to write to this logical eraseblock while we + * are moving it, so lock it. + * + * Note, we are using non-waiting locking here, because we cannot sleep + * on the LEB, since it may cause deadlocks. Indeed, imagine a task is + * unmapping the LEB which is mapped to the PEB we are going to move + * (@from). This task locks the LEB and goes sleep in the + * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are + * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the + * LEB is already locked, we just do not move it and return %1. + */ + err = leb_write_trylock(ubi, vol_id, lnum); + if (err) { + dbg_eba("contention on LEB %d:%d, cancel", vol_id, lnum); + return err; + } + + /* + * The LEB might have been put meanwhile, and the task which put it is + * probably waiting on @ubi->move_mutex. No need to continue the work, + * cancel it. + */ + if (vol->eba_tbl[lnum] != from) { + dbg_eba("LEB %d:%d is no longer mapped to PEB %d, mapped to " + "PEB %d, cancel", vol_id, lnum, from, + vol->eba_tbl[lnum]); + err = 1; + goto out_unlock_leb; + } + + /* + * OK, now the LEB is locked and we can safely start moving iy. Since + * this function utilizes thie @ubi->peb1_buf buffer which is shared + * with some other functions, so lock the buffer by taking the + * @ubi->buf_mutex. + */ + mutex_lock(&ubi->buf_mutex); + dbg_eba("read %d bytes of data", aldata_size); + err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); + if (err && err != UBI_IO_BITFLIPS) { + ubi_warn("error %d while reading data from PEB %d", + err, from); + goto out_unlock_buf; + } + + /* + * Now we have got to calculate how much data we have to to copy. In + * case of a static volume it is fairly easy - the VID header contains + * the data size. In case of a dynamic volume it is more difficult - we + * have to read the contents, cut 0xFF bytes from the end and copy only + * the first part. We must do this to avoid writing 0xFF bytes as it + * may have some side-effects. And not only this. It is important not + * to include those 0xFFs to CRC because later the they may be filled + * by data. + */ + if (vid_hdr->vol_type == UBI_VID_DYNAMIC) + aldata_size = data_size = + ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); + + cond_resched(); + crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); + cond_resched(); + + /* + * It may turn out to me that the whole @from physical eraseblock + * contains only 0xFF bytes. Then we have to only write the VID header + * and do not write any data. This also means we should not set + * @vid_hdr->copy_flag, @vid_hdr->data_size, and @vid_hdr->data_crc. + */ + if (data_size > 0) { + vid_hdr->copy_flag = 1; + vid_hdr->data_size = cpu_to_be32(data_size); + vid_hdr->data_crc = cpu_to_be32(crc); + } + vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); + + err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); + if (err) + goto out_unlock_buf; + + cond_resched(); + + /* Read the VID header back and check if it was written correctly */ + err = ubi_io_read_vid_hdr(ubi, to, vid_hdr, 1); + if (err) { + if (err != UBI_IO_BITFLIPS) + ubi_warn("cannot read VID header back from PEB %d", to); + else + err = 1; + goto out_unlock_buf; + } + + if (data_size > 0) { + err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); + if (err) + goto out_unlock_buf; + + cond_resched(); + + /* + * We've written the data and are going to read it back to make + * sure it was written correctly. + */ + + err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); + if (err) { + if (err != UBI_IO_BITFLIPS) + ubi_warn("cannot read data back from PEB %d", + to); + else + err = 1; + goto out_unlock_buf; + } + + cond_resched(); + + if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { + ubi_warn("read data back from PEB %d - it is different", + to); + goto out_unlock_buf; + } + } + + ubi_assert(vol->eba_tbl[lnum] == from); + vol->eba_tbl[lnum] = to; + +out_unlock_buf: + mutex_unlock(&ubi->buf_mutex); +out_unlock_leb: + leb_write_unlock(ubi, vol_id, lnum); + return err; +} + +/** + * ubi_eba_init_scan - initialize the EBA unit using scanning information. + * @ubi: UBI device description object + * @si: scanning information + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) +{ + int i, j, err, num_volumes; + struct ubi_scan_volume *sv; + struct ubi_volume *vol; + struct ubi_scan_leb *seb; + struct rb_node *rb; + + dbg_eba("initialize EBA unit"); + + spin_lock_init(&ubi->ltree_lock); + mutex_init(&ubi->alc_mutex); + ubi->ltree = RB_ROOT; + + ubi->global_sqnum = si->max_sqnum + 1; + num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; + + for (i = 0; i < num_volumes; i++) { + vol = ubi->volumes[i]; + if (!vol) + continue; + + cond_resched(); + + vol->eba_tbl = kmalloc(vol->reserved_pebs * sizeof(int), + GFP_KERNEL); + if (!vol->eba_tbl) { + err = -ENOMEM; + goto out_free; + } + + for (j = 0; j < vol->reserved_pebs; j++) + vol->eba_tbl[j] = UBI_LEB_UNMAPPED; + + sv = ubi_scan_find_sv(si, idx2vol_id(ubi, i)); + if (!sv) + continue; + + ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { + if (seb->lnum >= vol->reserved_pebs) + /* + * This may happen in case of an unclean reboot + * during re-size. + */ + ubi_scan_move_to_list(sv, seb, &si->erase); + vol->eba_tbl[seb->lnum] = seb->pnum; + } + } + + if (ubi->avail_pebs < EBA_RESERVED_PEBS) { + ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi->avail_pebs, EBA_RESERVED_PEBS); + err = -ENOSPC; + goto out_free; + } + ubi->avail_pebs -= EBA_RESERVED_PEBS; + ubi->rsvd_pebs += EBA_RESERVED_PEBS; + + if (ubi->bad_allowed) { + ubi_calculate_reserved(ubi); + + if (ubi->avail_pebs < ubi->beb_rsvd_level) { + /* No enough free physical eraseblocks */ + ubi->beb_rsvd_pebs = ubi->avail_pebs; + ubi_warn("cannot reserve enough PEBs for bad PEB " + "handling, reserved %d, need %d", + ubi->beb_rsvd_pebs, ubi->beb_rsvd_level); + } else + ubi->beb_rsvd_pebs = ubi->beb_rsvd_level; + + ubi->avail_pebs -= ubi->beb_rsvd_pebs; + ubi->rsvd_pebs += ubi->beb_rsvd_pebs; + } + + dbg_eba("EBA unit is initialized"); + return 0; + +out_free: + for (i = 0; i < num_volumes; i++) { + if (!ubi->volumes[i]) + continue; + kfree(ubi->volumes[i]->eba_tbl); + } + return err; +} + +/** + * ubi_eba_close - close EBA unit. + * @ubi: UBI device description object + */ +void ubi_eba_close(const struct ubi_device *ubi) +{ + int i, num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; + + dbg_eba("close EBA unit"); + + for (i = 0; i < num_volumes; i++) { + if (!ubi->volumes[i]) + continue; + kfree(ubi->volumes[i]->eba_tbl); + } +} -- cgit v1.1 From 2d262c4853cb5b6ddce1a28a9641f2de3688d7ea Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:26:54 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 3/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- drivers/mtd/ubi/io.c | 1274 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/ubi/kapi.c | 638 ++++++++++++++++++++++++ drivers/mtd/ubi/misc.c | 106 ++++ 3 files changed, 2018 insertions(+) create mode 100644 drivers/mtd/ubi/io.c create mode 100644 drivers/mtd/ubi/kapi.c create mode 100644 drivers/mtd/ubi/misc.c diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c new file mode 100644 index 0000000..2d44f23 --- /dev/null +++ b/drivers/mtd/ubi/io.c @@ -0,0 +1,1274 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (c) Nokia Corporation, 2006, 2007 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * UBI input/output unit. + * + * This unit provides a uniform way to work with all kinds of the underlying + * MTD devices. It also implements handy functions for reading and writing UBI + * headers. + * + * We are trying to have a paranoid mindset and not to trust to what we read + * from the flash media in order to be more secure and robust. So this unit + * validates every single header it reads from the flash media. + * + * Some words about how the eraseblock headers are stored. + * + * The erase counter header is always stored at offset zero. By default, the + * VID header is stored after the EC header at the closest aligned offset + * (i.e. aligned to the minimum I/O unit size). Data starts next to the VID + * header at the closest aligned offset. But this default layout may be + * changed. For example, for different reasons (e.g., optimization) UBI may be + * asked to put the VID header at further offset, and even at an unaligned + * offset. Of course, if the offset of the VID header is unaligned, UBI adds + * proper padding in front of it. Data offset may also be changed but it has to + * be aligned. + * + * About minimal I/O units. In general, UBI assumes flash device model where + * there is only one minimal I/O unit size. E.g., in case of NOR flash it is 1, + * in case of NAND flash it is a NAND page, etc. This is reported by MTD in the + * @ubi->mtd->writesize field. But as an exception, UBI admits of using another + * (smaller) minimal I/O unit size for EC and VID headers to make it possible + * to do different optimizations. + * + * This is extremely useful in case of NAND flashes which admit of several + * write operations to one NAND page. In this case UBI can fit EC and VID + * headers at one NAND page. Thus, UBI may use "sub-page" size as the minimal + * I/O unit for the headers (the @ubi->hdrs_min_io_size field). But it still + * reports NAND page size (@ubi->min_io_size) as a minimal I/O unit for the UBI + * users. + * + * Example: some Samsung NANDs with 2KiB pages allow 4x 512-byte writes, so + * although the minimal I/O unit is 2K, UBI uses 512 bytes for EC and VID + * headers. + * + * Q: why not just to treat sub-page as a minimal I/O unit of this flash + * device, e.g., make @ubi->min_io_size = 512 in the example above? + * + * A: because when writing a sub-page, MTD still writes a full 2K page but the + * bytes which are no relevant to the sub-page are 0xFF. So, basically, writing + * 4x512 sub-pages is 4 times slower then writing one 2KiB NAND page. Thus, we + * prefer to use sub-pages only for EV and VID headers. + * + * As it was noted above, the VID header may start at a non-aligned offset. + * For example, in case of a 2KiB page NAND flash with a 512 bytes sub-page, + * the VID header may reside at offset 1984 which is the last 64 bytes of the + * last sub-page (EC header is always at offset zero). This causes some + * difficulties when reading and writing VID headers. + * + * Suppose we have a 64-byte buffer and we read a VID header at it. We change + * the data and want to write this VID header out. As we can only write in + * 512-byte chunks, we have to allocate one more buffer and copy our VID header + * to offset 448 of this buffer. + * + * The I/O unit does the following trick in order to avoid this extra copy. + * It always allocates a @ubi->vid_hdr_alsize bytes buffer for the VID header + * and returns a pointer to offset @ubi->vid_hdr_shift of this buffer. When the + * VID header is being written out, it shifts the VID header pointer back and + * writes the whole sub-page. + */ + +#ifdef UBI_LINUX +#include +#include +#endif + +#include +#include "ubi.h" + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); +static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); +static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_ec_hdr *ec_hdr); +static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); +static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_vid_hdr *vid_hdr); +static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, + int len); +#else +#define paranoid_check_not_bad(ubi, pnum) 0 +#define paranoid_check_peb_ec_hdr(ubi, pnum) 0 +#define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 +#define paranoid_check_peb_vid_hdr(ubi, pnum) 0 +#define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 +#define paranoid_check_all_ff(ubi, pnum, offset, len) 0 +#endif + +/** + * ubi_io_read - read data from a physical eraseblock. + * @ubi: UBI device description object + * @buf: buffer where to store the read data + * @pnum: physical eraseblock number to read from + * @offset: offset within the physical eraseblock from where to read + * @len: how many bytes to read + * + * This function reads data from offset @offset of physical eraseblock @pnum + * and stores the read data in the @buf buffer. The following return codes are + * possible: + * + * o %0 if all the requested data were successfully read; + * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but + * correctable bit-flips were detected; this is harmless but may indicate + * that this eraseblock may become bad soon (but do not have to); + * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for + * example it can be an ECC error in case of NAND; this most probably means + * that the data is corrupted; + * o %-EIO if some I/O error occurred; + * o other negative error codes in case of other errors. + */ +int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, + int len) +{ + int err, retries = 0; + size_t read; + loff_t addr; + + dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset); + + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); + ubi_assert(len > 0); + + err = paranoid_check_not_bad(ubi, pnum); + if (err) + return err > 0 ? -EINVAL : err; + + addr = (loff_t)pnum * ubi->peb_size + offset; +retry: + err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); + if (err) { + if (err == -EUCLEAN) { + /* + * -EUCLEAN is reported if there was a bit-flip which + * was corrected, so this is harmless. + */ + ubi_msg("fixable bit-flip detected at PEB %d", pnum); + ubi_assert(len == read); + return UBI_IO_BITFLIPS; + } + + if (read != len && retries++ < UBI_IO_RETRIES) { + dbg_io("error %d while reading %d bytes from PEB %d:%d, " + "read only %zd bytes, retry", + err, len, pnum, offset, read); + yield(); + goto retry; + } + + ubi_err("error %d while reading %d bytes from PEB %d:%d, " + "read %zd bytes", err, len, pnum, offset, read); + ubi_dbg_dump_stack(); + + /* + * The driver should never return -EBADMSG if it failed to read + * all the requested data. But some buggy drivers might do + * this, so we change it to -EIO. + */ + if (read != len && err == -EBADMSG) { + ubi_assert(0); + printk("%s[%d] not here\n", __func__, __LINE__); +// err = -EIO; + } + } else { + ubi_assert(len == read); + + if (ubi_dbg_is_bitflip()) { + dbg_msg("bit-flip (emulated)"); + err = UBI_IO_BITFLIPS; + } + } + + return err; +} + +/** + * ubi_io_write - write data to a physical eraseblock. + * @ubi: UBI device description object + * @buf: buffer with the data to write + * @pnum: physical eraseblock number to write to + * @offset: offset within the physical eraseblock where to write + * @len: how many bytes to write + * + * This function writes @len bytes of data from buffer @buf to offset @offset + * of physical eraseblock @pnum. If all the data were successfully written, + * zero is returned. If an error occurred, this function returns a negative + * error code. If %-EIO is returned, the physical eraseblock most probably went + * bad. + * + * Note, in case of an error, it is possible that something was still written + * to the flash media, but may be some garbage. + */ +int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, + int len) +{ + int err; + size_t written; + loff_t addr; + + dbg_io("write %d bytes to PEB %d:%d", len, pnum, offset); + + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); + ubi_assert(offset % ubi->hdrs_min_io_size == 0); + ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); + + if (ubi->ro_mode) { + ubi_err("read-only mode"); + return -EROFS; + } + + /* The below has to be compiled out if paranoid checks are disabled */ + + err = paranoid_check_not_bad(ubi, pnum); + if (err) + return err > 0 ? -EINVAL : err; + + /* The area we are writing to has to contain all 0xFF bytes */ + err = paranoid_check_all_ff(ubi, pnum, offset, len); + if (err) + return err > 0 ? -EINVAL : err; + + if (offset >= ubi->leb_start) { + /* + * We write to the data area of the physical eraseblock. Make + * sure it has valid EC and VID headers. + */ + err = paranoid_check_peb_ec_hdr(ubi, pnum); + if (err) + return err > 0 ? -EINVAL : err; + err = paranoid_check_peb_vid_hdr(ubi, pnum); + if (err) + return err > 0 ? -EINVAL : err; + } + + if (ubi_dbg_is_write_failure()) { + dbg_err("cannot write %d bytes to PEB %d:%d " + "(emulated)", len, pnum, offset); + ubi_dbg_dump_stack(); + return -EIO; + } + + addr = (loff_t)pnum * ubi->peb_size + offset; + err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); + if (err) { + ubi_err("error %d while writing %d bytes to PEB %d:%d, written" + " %zd bytes", err, len, pnum, offset, written); + ubi_dbg_dump_stack(); + } else + ubi_assert(written == len); + + return err; +} + +/** + * erase_callback - MTD erasure call-back. + * @ei: MTD erase information object. + * + * Note, even though MTD erase interface is asynchronous, all the current + * implementations are synchronous anyway. + */ +static void erase_callback(struct erase_info *ei) +{ + wake_up_interruptible((wait_queue_head_t *)ei->priv); +} + +/** + * do_sync_erase - synchronously erase a physical eraseblock. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to erase + * + * This function synchronously erases physical eraseblock @pnum and returns + * zero in case of success and a negative error code in case of failure. If + * %-EIO is returned, the physical eraseblock most probably went bad. + */ +static int do_sync_erase(struct ubi_device *ubi, int pnum) +{ + int err, retries = 0; + struct erase_info ei; + wait_queue_head_t wq; + + dbg_io("erase PEB %d", pnum); + +retry: + init_waitqueue_head(&wq); + memset(&ei, 0, sizeof(struct erase_info)); + + ei.mtd = ubi->mtd; + ei.addr = (loff_t)pnum * ubi->peb_size; + ei.len = ubi->peb_size; + ei.callback = erase_callback; + ei.priv = (unsigned long)&wq; + + err = ubi->mtd->erase(ubi->mtd, &ei); + if (err) { + if (retries++ < UBI_IO_RETRIES) { + dbg_io("error %d while erasing PEB %d, retry", + err, pnum); + yield(); + goto retry; + } + ubi_err("cannot erase PEB %d, error %d", pnum, err); + ubi_dbg_dump_stack(); + return err; + } + + err = wait_event_interruptible(wq, ei.state == MTD_ERASE_DONE || + ei.state == MTD_ERASE_FAILED); + if (err) { + ubi_err("interrupted PEB %d erasure", pnum); + return -EINTR; + } + + if (ei.state == MTD_ERASE_FAILED) { + if (retries++ < UBI_IO_RETRIES) { + dbg_io("error while erasing PEB %d, retry", pnum); + yield(); + goto retry; + } + ubi_err("cannot erase PEB %d", pnum); + ubi_dbg_dump_stack(); + return -EIO; + } + + err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); + if (err) + return err > 0 ? -EINVAL : err; + + if (ubi_dbg_is_erase_failure() && !err) { + dbg_err("cannot erase PEB %d (emulated)", pnum); + return -EIO; + } + + return 0; +} + +/** + * check_pattern - check if buffer contains only a certain byte pattern. + * @buf: buffer to check + * @patt: the pattern to check + * @size: buffer size in bytes + * + * This function returns %1 in there are only @patt bytes in @buf, and %0 if + * something else was also found. + */ +static int check_pattern(const void *buf, uint8_t patt, int size) +{ + int i; + + for (i = 0; i < size; i++) + if (((const uint8_t *)buf)[i] != patt) + return 0; + return 1; +} + +/* Patterns to write to a physical eraseblock when torturing it */ +static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; + +/** + * torture_peb - test a supposedly bad physical eraseblock. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to test + * + * This function returns %-EIO if the physical eraseblock did not pass the + * test, a positive number of erase operations done if the test was + * successfully passed, and other negative error codes in case of other errors. + */ +static int torture_peb(struct ubi_device *ubi, int pnum) +{ + int err, i, patt_count; + + patt_count = ARRAY_SIZE(patterns); + ubi_assert(patt_count > 0); + + mutex_lock(&ubi->buf_mutex); + for (i = 0; i < patt_count; i++) { + err = do_sync_erase(ubi, pnum); + if (err) + goto out; + + /* Make sure the PEB contains only 0xFF bytes */ + err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); + if (err) + goto out; + + err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); + if (err == 0) { + ubi_err("erased PEB %d, but a non-0xFF byte found", + pnum); + err = -EIO; + goto out; + } + + /* Write a pattern and check it */ + memset(ubi->peb_buf1, patterns[i], ubi->peb_size); + err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); + if (err) + goto out; + + memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); + err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); + if (err) + goto out; + + err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size); + if (err == 0) { + ubi_err("pattern %x checking failed for PEB %d", + patterns[i], pnum); + err = -EIO; + goto out; + } + } + + err = patt_count; + +out: + mutex_unlock(&ubi->buf_mutex); + if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { + /* + * If a bit-flip or data integrity error was detected, the test + * has not passed because it happened on a freshly erased + * physical eraseblock which means something is wrong with it. + */ + ubi_err("read problems on freshly erased PEB %d, must be bad", + pnum); + err = -EIO; + } + return err; +} + +/** + * ubi_io_sync_erase - synchronously erase a physical eraseblock. + * @ubi: UBI device description object + * @pnum: physical eraseblock number to erase + * @torture: if this physical eraseblock has to be tortured + * + * This function synchronously erases physical eraseblock @pnum. If @torture + * flag is not zero, the physical eraseblock is checked by means of writing + * different patterns to it and reading them back. If the torturing is enabled, + * the physical eraseblock is erased more then once. + * + * This function returns the number of erasures made in case of success, %-EIO + * if the erasure failed or the torturing test failed, and other negative error + * codes in case of other errors. Note, %-EIO means that the physical + * eraseblock is bad. + */ +int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) +{ + int err, ret = 0; + + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + + err = paranoid_check_not_bad(ubi, pnum); + if (err != 0) + return err > 0 ? -EINVAL : err; + + if (ubi->ro_mode) { + ubi_err("read-only mode"); + return -EROFS; + } + + if (torture) { + ret = torture_peb(ubi, pnum); + if (ret < 0) + return ret; + } + + err = do_sync_erase(ubi, pnum); + if (err) + return err; + + return ret + 1; +} + +/** + * ubi_io_is_bad - check if a physical eraseblock is bad. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to check + * + * This function returns a positive number if the physical eraseblock is bad, + * zero if not, and a negative error code if an error occurred. + */ +int ubi_io_is_bad(const struct ubi_device *ubi, int pnum) +{ + struct mtd_info *mtd = ubi->mtd; + + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + + if (ubi->bad_allowed) { + int ret; + + ret = mtd->block_isbad(mtd, (loff_t)pnum * ubi->peb_size); + if (ret < 0) + ubi_err("error %d while checking if PEB %d is bad", + ret, pnum); + else if (ret) + dbg_io("PEB %d is bad", pnum); + return ret; + } + + return 0; +} + +/** + * ubi_io_mark_bad - mark a physical eraseblock as bad. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to mark + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum) +{ + int err; + struct mtd_info *mtd = ubi->mtd; + + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + + if (ubi->ro_mode) { + ubi_err("read-only mode"); + return -EROFS; + } + + if (!ubi->bad_allowed) + return 0; + + err = mtd->block_markbad(mtd, (loff_t)pnum * ubi->peb_size); + if (err) + ubi_err("cannot mark PEB %d bad, error %d", pnum, err); + return err; +} + +/** + * validate_ec_hdr - validate an erase counter header. + * @ubi: UBI device description object + * @ec_hdr: the erase counter header to check + * + * This function returns zero if the erase counter header is OK, and %1 if + * not. + */ +static int validate_ec_hdr(const struct ubi_device *ubi, + const struct ubi_ec_hdr *ec_hdr) +{ + long long ec; + int vid_hdr_offset, leb_start; + + ec = be64_to_cpu(ec_hdr->ec); + vid_hdr_offset = be32_to_cpu(ec_hdr->vid_hdr_offset); + leb_start = be32_to_cpu(ec_hdr->data_offset); + + if (ec_hdr->version != UBI_VERSION) { + ubi_err("node with incompatible UBI version found: " + "this UBI version is %d, image version is %d", + UBI_VERSION, (int)ec_hdr->version); + goto bad; + } + + if (vid_hdr_offset != ubi->vid_hdr_offset) { + ubi_err("bad VID header offset %d, expected %d", + vid_hdr_offset, ubi->vid_hdr_offset); + goto bad; + } + + if (leb_start != ubi->leb_start) { + ubi_err("bad data offset %d, expected %d", + leb_start, ubi->leb_start); + goto bad; + } + + if (ec < 0 || ec > UBI_MAX_ERASECOUNTER) { + ubi_err("bad erase counter %lld", ec); + goto bad; + } + + return 0; + +bad: + ubi_err("bad EC header"); + ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dbg_dump_stack(); + return 1; +} + +/** + * ubi_io_read_ec_hdr - read and check an erase counter header. + * @ubi: UBI device description object + * @pnum: physical eraseblock to read from + * @ec_hdr: a &struct ubi_ec_hdr object where to store the read erase counter + * header + * @verbose: be verbose if the header is corrupted or was not found + * + * This function reads erase counter header from physical eraseblock @pnum and + * stores it in @ec_hdr. This function also checks CRC checksum of the read + * erase counter header. The following codes may be returned: + * + * o %0 if the CRC checksum is correct and the header was successfully read; + * o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected + * and corrected by the flash driver; this is harmless but may indicate that + * this eraseblock may become bad soon (but may be not); + * o %UBI_IO_BAD_EC_HDR if the erase counter header is corrupted (a CRC error); + * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty; + * o a negative error code in case of failure. + */ +int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, + struct ubi_ec_hdr *ec_hdr, int verbose) +{ + int err, read_err = 0; + uint32_t crc, magic, hdr_crc; + + dbg_io("read EC header from PEB %d", pnum); + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + if (UBI_IO_DEBUG) + verbose = 1; + + err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); + if (err) { + if (err != UBI_IO_BITFLIPS && err != -EBADMSG) + return err; + + /* + * We read all the data, but either a correctable bit-flip + * occurred, or MTD reported about some data integrity error, + * like an ECC error in case of NAND. The former is harmless, + * the later may mean that the read data is corrupted. But we + * have a CRC check-sum and we will detect this. If the EC + * header is still OK, we just report this as there was a + * bit-flip. + */ + read_err = err; + } + + magic = be32_to_cpu(ec_hdr->magic); + if (magic != UBI_EC_HDR_MAGIC) { + /* + * The magic field is wrong. Let's check if we have read all + * 0xFF. If yes, this physical eraseblock is assumed to be + * empty. + * + * But if there was a read error, we do not test it for all + * 0xFFs. Even if it does contain all 0xFFs, this error + * indicates that something is still wrong with this physical + * eraseblock and we anyway cannot treat it as empty. + */ + if (read_err != -EBADMSG && + check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { + /* The physical eraseblock is supposedly empty */ + + /* + * The below is just a paranoid check, it has to be + * compiled out if paranoid checks are disabled. + */ + err = paranoid_check_all_ff(ubi, pnum, 0, + ubi->peb_size); + if (err) + return err > 0 ? UBI_IO_BAD_EC_HDR : err; + + if (verbose) + ubi_warn("no EC header found at PEB %d, " + "only 0xFF bytes", pnum); + return UBI_IO_PEB_EMPTY; + } + + /* + * This is not a valid erase counter header, and these are not + * 0xFF bytes. Report that the header is corrupted. + */ + if (verbose) { + ubi_warn("bad magic number at PEB %d: %08x instead of " + "%08x", pnum, magic, UBI_EC_HDR_MAGIC); + ubi_dbg_dump_ec_hdr(ec_hdr); + } + return UBI_IO_BAD_EC_HDR; + } + + crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); + hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); + + if (hdr_crc != crc) { + if (verbose) { + ubi_warn("bad EC header CRC at PEB %d, calculated %#08x," + " read %#08x", pnum, crc, hdr_crc); + ubi_dbg_dump_ec_hdr(ec_hdr); + } + return UBI_IO_BAD_EC_HDR; + } + + /* And of course validate what has just been read from the media */ + err = validate_ec_hdr(ubi, ec_hdr); + if (err) { + ubi_err("validation failed for PEB %d", pnum); + return -EINVAL; + } + + return read_err ? UBI_IO_BITFLIPS : 0; +} + +/** + * ubi_io_write_ec_hdr - write an erase counter header. + * @ubi: UBI device description object + * @pnum: physical eraseblock to write to + * @ec_hdr: the erase counter header to write + * + * This function writes erase counter header described by @ec_hdr to physical + * eraseblock @pnum. It also fills most fields of @ec_hdr before writing, so + * the caller do not have to fill them. Callers must only fill the @ec_hdr->ec + * field. + * + * This function returns zero in case of success and a negative error code in + * case of failure. If %-EIO is returned, the physical eraseblock most probably + * went bad. + */ +int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, + struct ubi_ec_hdr *ec_hdr) +{ + int err; + uint32_t crc; + + dbg_io("write EC header to PEB %d", pnum); + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + + ec_hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); + ec_hdr->version = UBI_VERSION; + ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); + ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); + crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); + ec_hdr->hdr_crc = cpu_to_be32(crc); + + err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); + if (err) + return -EINVAL; + + err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize); + return err; +} + +/** + * validate_vid_hdr - validate a volume identifier header. + * @ubi: UBI device description object + * @vid_hdr: the volume identifier header to check + * + * This function checks that data stored in the volume identifier header + * @vid_hdr. Returns zero if the VID header is OK and %1 if not. + */ +static int validate_vid_hdr(const struct ubi_device *ubi, + const struct ubi_vid_hdr *vid_hdr) +{ + int vol_type = vid_hdr->vol_type; + int copy_flag = vid_hdr->copy_flag; + int vol_id = be32_to_cpu(vid_hdr->vol_id); + int lnum = be32_to_cpu(vid_hdr->lnum); + int compat = vid_hdr->compat; + int data_size = be32_to_cpu(vid_hdr->data_size); + int used_ebs = be32_to_cpu(vid_hdr->used_ebs); + int data_pad = be32_to_cpu(vid_hdr->data_pad); + int data_crc = be32_to_cpu(vid_hdr->data_crc); + int usable_leb_size = ubi->leb_size - data_pad; + + if (copy_flag != 0 && copy_flag != 1) { + dbg_err("bad copy_flag"); + goto bad; + } + + if (vol_id < 0 || lnum < 0 || data_size < 0 || used_ebs < 0 || + data_pad < 0) { + dbg_err("negative values"); + goto bad; + } + + if (vol_id >= UBI_MAX_VOLUMES && vol_id < UBI_INTERNAL_VOL_START) { + dbg_err("bad vol_id"); + goto bad; + } + + if (vol_id < UBI_INTERNAL_VOL_START && compat != 0) { + dbg_err("bad compat"); + goto bad; + } + + if (vol_id >= UBI_INTERNAL_VOL_START && compat != UBI_COMPAT_DELETE && + compat != UBI_COMPAT_RO && compat != UBI_COMPAT_PRESERVE && + compat != UBI_COMPAT_REJECT) { + dbg_err("bad compat"); + goto bad; + } + + if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { + dbg_err("bad vol_type"); + goto bad; + } + + if (data_pad >= ubi->leb_size / 2) { + dbg_err("bad data_pad"); + goto bad; + } + + if (vol_type == UBI_VID_STATIC) { + /* + * Although from high-level point of view static volumes may + * contain zero bytes of data, but no VID headers can contain + * zero at these fields, because they empty volumes do not have + * mapped logical eraseblocks. + */ + if (used_ebs == 0) { + dbg_err("zero used_ebs"); + goto bad; + } + if (data_size == 0) { + dbg_err("zero data_size"); + goto bad; + } + if (lnum < used_ebs - 1) { + if (data_size != usable_leb_size) { + dbg_err("bad data_size"); + goto bad; + } + } else if (lnum == used_ebs - 1) { + if (data_size == 0) { + dbg_err("bad data_size at last LEB"); + goto bad; + } + } else { + dbg_err("too high lnum"); + goto bad; + } + } else { + if (copy_flag == 0) { + if (data_crc != 0) { + dbg_err("non-zero data CRC"); + goto bad; + } + if (data_size != 0) { + dbg_err("non-zero data_size"); + goto bad; + } + } else { + if (data_size == 0) { + dbg_err("zero data_size of copy"); + goto bad; + } + } + if (used_ebs != 0) { + dbg_err("bad used_ebs"); + goto bad; + } + } + + return 0; + +bad: + ubi_err("bad VID header"); + ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dbg_dump_stack(); + return 1; +} + +/** + * ubi_io_read_vid_hdr - read and check a volume identifier header. + * @ubi: UBI device description object + * @pnum: physical eraseblock number to read from + * @vid_hdr: &struct ubi_vid_hdr object where to store the read volume + * identifier header + * @verbose: be verbose if the header is corrupted or wasn't found + * + * This function reads the volume identifier header from physical eraseblock + * @pnum and stores it in @vid_hdr. It also checks CRC checksum of the read + * volume identifier header. The following codes may be returned: + * + * o %0 if the CRC checksum is correct and the header was successfully read; + * o %UBI_IO_BITFLIPS if the CRC is correct, but bit-flips were detected + * and corrected by the flash driver; this is harmless but may indicate that + * this eraseblock may become bad soon; + * o %UBI_IO_BAD_VID_HRD if the volume identifier header is corrupted (a CRC + * error detected); + * o %UBI_IO_PEB_FREE if the physical eraseblock is free (i.e., there is no VID + * header there); + * o a negative error code in case of failure. + */ +int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, + struct ubi_vid_hdr *vid_hdr, int verbose) +{ + int err, read_err = 0; + uint32_t crc, magic, hdr_crc; + void *p; + + dbg_io("read VID header from PEB %d", pnum); + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + if (UBI_IO_DEBUG) + verbose = 1; + + p = (char *)vid_hdr - ubi->vid_hdr_shift; + err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, + ubi->vid_hdr_alsize); + if (err) { + if (err != UBI_IO_BITFLIPS && err != -EBADMSG) + return err; + + /* + * We read all the data, but either a correctable bit-flip + * occurred, or MTD reported about some data integrity error, + * like an ECC error in case of NAND. The former is harmless, + * the later may mean the read data is corrupted. But we have a + * CRC check-sum and we will identify this. If the VID header is + * still OK, we just report this as there was a bit-flip. + */ + read_err = err; + } + + magic = be32_to_cpu(vid_hdr->magic); + if (magic != UBI_VID_HDR_MAGIC) { + /* + * If we have read all 0xFF bytes, the VID header probably does + * not exist and the physical eraseblock is assumed to be free. + * + * But if there was a read error, we do not test the data for + * 0xFFs. Even if it does contain all 0xFFs, this error + * indicates that something is still wrong with this physical + * eraseblock and it cannot be regarded as free. + */ + if (read_err != -EBADMSG && + check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { + /* The physical eraseblock is supposedly free */ + + /* + * The below is just a paranoid check, it has to be + * compiled out if paranoid checks are disabled. + */ + err = paranoid_check_all_ff(ubi, pnum, ubi->leb_start, + ubi->leb_size); + if (err) + return err > 0 ? UBI_IO_BAD_VID_HDR : err; + + if (verbose) + ubi_warn("no VID header found at PEB %d, " + "only 0xFF bytes", pnum); + return UBI_IO_PEB_FREE; + } + + /* + * This is not a valid VID header, and these are not 0xFF + * bytes. Report that the header is corrupted. + */ + if (verbose) { + ubi_warn("bad magic number at PEB %d: %08x instead of " + "%08x", pnum, magic, UBI_VID_HDR_MAGIC); + ubi_dbg_dump_vid_hdr(vid_hdr); + } + return UBI_IO_BAD_VID_HDR; + } + + crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); + hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); + + if (hdr_crc != crc) { + if (verbose) { + ubi_warn("bad CRC at PEB %d, calculated %#08x, " + "read %#08x", pnum, crc, hdr_crc); + ubi_dbg_dump_vid_hdr(vid_hdr); + } + return UBI_IO_BAD_VID_HDR; + } + + /* Validate the VID header that we have just read */ + err = validate_vid_hdr(ubi, vid_hdr); + if (err) { + ubi_err("validation failed for PEB %d", pnum); + return -EINVAL; + } + + return read_err ? UBI_IO_BITFLIPS : 0; +} + +/** + * ubi_io_write_vid_hdr - write a volume identifier header. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to write to + * @vid_hdr: the volume identifier header to write + * + * This function writes the volume identifier header described by @vid_hdr to + * physical eraseblock @pnum. This function automatically fills the + * @vid_hdr->magic and the @vid_hdr->version fields, as well as calculates + * header CRC checksum and stores it at vid_hdr->hdr_crc. + * + * This function returns zero in case of success and a negative error code in + * case of failure. If %-EIO is returned, the physical eraseblock probably went + * bad. + */ +int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, + struct ubi_vid_hdr *vid_hdr) +{ + int err; + uint32_t crc; + void *p; + + dbg_io("write VID header to PEB %d", pnum); + ubi_assert(pnum >= 0 && pnum < ubi->peb_count); + + err = paranoid_check_peb_ec_hdr(ubi, pnum); + if (err) + return err > 0 ? -EINVAL: err; + + vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); + vid_hdr->version = UBI_VERSION; + crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); + vid_hdr->hdr_crc = cpu_to_be32(crc); + + err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); + if (err) + return -EINVAL; + + p = (char *)vid_hdr - ubi->vid_hdr_shift; + err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, + ubi->vid_hdr_alsize); + return err; +} + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID + +/** + * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. + * @ubi: UBI device description object + * @pnum: physical eraseblock number to check + * + * This function returns zero if the physical eraseblock is good, a positive + * number if it is bad and a negative error code if an error occurred. + */ +static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) +{ + int err; + + err = ubi_io_is_bad(ubi, pnum); + if (!err) + return err; + + ubi_err("paranoid check failed for PEB %d", pnum); + ubi_dbg_dump_stack(); + return err; +} + +/** + * paranoid_check_ec_hdr - check if an erase counter header is all right. + * @ubi: UBI device description object + * @pnum: physical eraseblock number the erase counter header belongs to + * @ec_hdr: the erase counter header to check + * + * This function returns zero if the erase counter header contains valid + * values, and %1 if not. + */ +static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_ec_hdr *ec_hdr) +{ + int err; + uint32_t magic; + + magic = be32_to_cpu(ec_hdr->magic); + if (magic != UBI_EC_HDR_MAGIC) { + ubi_err("bad magic %#08x, must be %#08x", + magic, UBI_EC_HDR_MAGIC); + goto fail; + } + + err = validate_ec_hdr(ubi, ec_hdr); + if (err) { + ubi_err("paranoid check failed for PEB %d", pnum); + goto fail; + } + + return 0; + +fail: + ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dbg_dump_stack(); + return 1; +} + +/** + * paranoid_check_peb_ec_hdr - check that the erase counter header of a + * physical eraseblock is in-place and is all right. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to check + * + * This function returns zero if the erase counter header is all right, %1 if + * not, and a negative error code if an error occurred. + */ +static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) +{ + int err; + uint32_t crc, hdr_crc; + struct ubi_ec_hdr *ec_hdr; + + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); + if (!ec_hdr) + return -ENOMEM; + + err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE); + if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) + goto exit; + + crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); + hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); + if (hdr_crc != crc) { + ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); + ubi_err("paranoid check failed for PEB %d", pnum); + ubi_dbg_dump_ec_hdr(ec_hdr); + ubi_dbg_dump_stack(); + err = 1; + goto exit; + } + + err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); + +exit: + kfree(ec_hdr); + return err; +} + +/** + * paranoid_check_vid_hdr - check that a volume identifier header is all right. + * @ubi: UBI device description object + * @pnum: physical eraseblock number the volume identifier header belongs to + * @vid_hdr: the volume identifier header to check + * + * This function returns zero if the volume identifier header is all right, and + * %1 if not. + */ +static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, + const struct ubi_vid_hdr *vid_hdr) +{ + int err; + uint32_t magic; + + magic = be32_to_cpu(vid_hdr->magic); + if (magic != UBI_VID_HDR_MAGIC) { + ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", + magic, pnum, UBI_VID_HDR_MAGIC); + goto fail; + } + + err = validate_vid_hdr(ubi, vid_hdr); + if (err) { + ubi_err("paranoid check failed for PEB %d", pnum); + goto fail; + } + + return err; + +fail: + ubi_err("paranoid check failed for PEB %d", pnum); + ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dbg_dump_stack(); + return 1; + +} + +/** + * paranoid_check_peb_vid_hdr - check that the volume identifier header of a + * physical eraseblock is in-place and is all right. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to check + * + * This function returns zero if the volume identifier header is all right, + * %1 if not, and a negative error code if an error occurred. + */ +static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) +{ + int err; + uint32_t crc, hdr_crc; + struct ubi_vid_hdr *vid_hdr; + void *p; + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) + return -ENOMEM; + + p = (char *)vid_hdr - ubi->vid_hdr_shift; + err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, + ubi->vid_hdr_alsize); + if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG) + goto exit; + + crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); + hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); + if (hdr_crc != crc) { + ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " + "read %#08x", pnum, crc, hdr_crc); + ubi_err("paranoid check failed for PEB %d", pnum); + ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dbg_dump_stack(); + err = 1; + goto exit; + } + + err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); + +exit: + ubi_free_vid_hdr(ubi, vid_hdr); + return err; +} + +/** + * paranoid_check_all_ff - check that a region of flash is empty. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to check + * @offset: the starting offset within the physical eraseblock to check + * @len: the length of the region to check + * + * This function returns zero if only 0xFF bytes are present at offset + * @offset of the physical eraseblock @pnum, %1 if not, and a negative error + * code if an error occurred. + */ +static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, + int len) +{ + size_t read; + int err; + loff_t addr = (loff_t)pnum * ubi->peb_size + offset; + + mutex_lock(&ubi->dbg_buf_mutex); + err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); + if (err && err != -EUCLEAN) { + ubi_err("error %d while reading %d bytes from PEB %d:%d, " + "read %zd bytes", err, len, pnum, offset, read); + goto error; + } + + err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); + if (err == 0) { + ubi_err("flash region at PEB %d:%d, length %d does not " + "contain all 0xFF bytes", pnum, offset, len); + goto fail; + } + mutex_unlock(&ubi->dbg_buf_mutex); + + return 0; + +fail: + ubi_err("paranoid check failed for PEB %d", pnum); + dbg_msg("hex dump of the %d-%d region", offset, offset + len); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, + ubi->dbg_peb_buf, len, 1); + err = 1; +error: + ubi_dbg_dump_stack(); + mutex_unlock(&ubi->dbg_buf_mutex); + return err; +} + +#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c new file mode 100644 index 0000000..423d479 --- /dev/null +++ b/drivers/mtd/ubi/kapi.c @@ -0,0 +1,638 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* This file mostly implements UBI kernel API functions */ + +#ifdef UBI_LINUX +#include +#include +#include +#endif + +#include +#include "ubi.h" + +/** + * ubi_get_device_info - get information about UBI device. + * @ubi_num: UBI device number + * @di: the information is stored here + * + * This function returns %0 in case of success, %-EINVAL if the UBI device + * number is invalid, and %-ENODEV if there is no such UBI device. + */ +int ubi_get_device_info(int ubi_num, struct ubi_device_info *di) +{ + struct ubi_device *ubi; + + if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) + return -EINVAL; + + ubi = ubi_get_device(ubi_num); + if (!ubi) + return -ENODEV; + + di->ubi_num = ubi->ubi_num; + di->leb_size = ubi->leb_size; + di->min_io_size = ubi->min_io_size; + di->ro_mode = ubi->ro_mode; + di->cdev = ubi->cdev.dev; + + ubi_put_device(ubi); + return 0; +} +EXPORT_SYMBOL_GPL(ubi_get_device_info); + +/** + * ubi_get_volume_info - get information about UBI volume. + * @desc: volume descriptor + * @vi: the information is stored here + */ +void ubi_get_volume_info(struct ubi_volume_desc *desc, + struct ubi_volume_info *vi) +{ + const struct ubi_volume *vol = desc->vol; + const struct ubi_device *ubi = vol->ubi; + + vi->vol_id = vol->vol_id; + vi->ubi_num = ubi->ubi_num; + vi->size = vol->reserved_pebs; + vi->used_bytes = vol->used_bytes; + vi->vol_type = vol->vol_type; + vi->corrupted = vol->corrupted; + vi->upd_marker = vol->upd_marker; + vi->alignment = vol->alignment; + vi->usable_leb_size = vol->usable_leb_size; + vi->name_len = vol->name_len; + vi->name = vol->name; + vi->cdev = vol->cdev.dev; +} +EXPORT_SYMBOL_GPL(ubi_get_volume_info); + +/** + * ubi_open_volume - open UBI volume. + * @ubi_num: UBI device number + * @vol_id: volume ID + * @mode: open mode + * + * The @mode parameter specifies if the volume should be opened in read-only + * mode, read-write mode, or exclusive mode. The exclusive mode guarantees that + * nobody else will be able to open this volume. UBI allows to have many volume + * readers and one writer at a time. + * + * If a static volume is being opened for the first time since boot, it will be + * checked by this function, which means it will be fully read and the CRC + * checksum of each logical eraseblock will be checked. + * + * This function returns volume descriptor in case of success and a negative + * error code in case of failure. + */ +struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) +{ + int err; + struct ubi_volume_desc *desc; + struct ubi_device *ubi; + struct ubi_volume *vol; + + dbg_msg("open device %d volume %d, mode %d", ubi_num, vol_id, mode); + + if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) + return ERR_PTR(-EINVAL); + + if (mode != UBI_READONLY && mode != UBI_READWRITE && + mode != UBI_EXCLUSIVE) + return ERR_PTR(-EINVAL); + + /* + * First of all, we have to get the UBI device to prevent its removal. + */ + ubi = ubi_get_device(ubi_num); + if (!ubi) + return ERR_PTR(-ENODEV); + + if (vol_id < 0 || vol_id >= ubi->vtbl_slots) { + err = -EINVAL; + goto out_put_ubi; + } + + desc = kmalloc(sizeof(struct ubi_volume_desc), GFP_KERNEL); + if (!desc) { + err = -ENOMEM; + goto out_put_ubi; + } + + err = -ENODEV; + if (!try_module_get(THIS_MODULE)) + goto out_free; + + spin_lock(&ubi->volumes_lock); + vol = ubi->volumes[vol_id]; + if (!vol) + goto out_unlock; + + err = -EBUSY; + switch (mode) { + case UBI_READONLY: + if (vol->exclusive) + goto out_unlock; + vol->readers += 1; + break; + + case UBI_READWRITE: + if (vol->exclusive || vol->writers > 0) + goto out_unlock; + vol->writers += 1; + break; + + case UBI_EXCLUSIVE: + if (vol->exclusive || vol->writers || vol->readers) + goto out_unlock; + vol->exclusive = 1; + break; + } + get_device(&vol->dev); + vol->ref_count += 1; + spin_unlock(&ubi->volumes_lock); + + desc->vol = vol; + desc->mode = mode; + + mutex_lock(&ubi->ckvol_mutex); + if (!vol->checked) { + /* This is the first open - check the volume */ + err = ubi_check_volume(ubi, vol_id); + if (err < 0) { + mutex_unlock(&ubi->ckvol_mutex); + ubi_close_volume(desc); + return ERR_PTR(err); + } + if (err == 1) { + ubi_warn("volume %d on UBI device %d is corrupted", + vol_id, ubi->ubi_num); + vol->corrupted = 1; + } + vol->checked = 1; + } + mutex_unlock(&ubi->ckvol_mutex); + + return desc; + +out_unlock: + spin_unlock(&ubi->volumes_lock); + module_put(THIS_MODULE); +out_free: + kfree(desc); +out_put_ubi: + ubi_put_device(ubi); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(ubi_open_volume); + +/** + * ubi_open_volume_nm - open UBI volume by name. + * @ubi_num: UBI device number + * @name: volume name + * @mode: open mode + * + * This function is similar to 'ubi_open_volume()', but opens a volume by name. + */ +struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, + int mode) +{ + int i, vol_id = -1, len; + struct ubi_device *ubi; + struct ubi_volume_desc *ret; + + dbg_msg("open volume %s, mode %d", name, mode); + + if (!name) + return ERR_PTR(-EINVAL); + + len = strnlen(name, UBI_VOL_NAME_MAX + 1); + if (len > UBI_VOL_NAME_MAX) + return ERR_PTR(-EINVAL); + + if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) + return ERR_PTR(-EINVAL); + + ubi = ubi_get_device(ubi_num); + if (!ubi) + return ERR_PTR(-ENODEV); + + spin_lock(&ubi->volumes_lock); + /* Walk all volumes of this UBI device */ + for (i = 0; i < ubi->vtbl_slots; i++) { + struct ubi_volume *vol = ubi->volumes[i]; + + if (vol && len == vol->name_len && !strcmp(name, vol->name)) { + vol_id = i; + break; + } + } + spin_unlock(&ubi->volumes_lock); + + if (vol_id >= 0) + ret = ubi_open_volume(ubi_num, vol_id, mode); + else + ret = ERR_PTR(-ENODEV); + + /* + * We should put the UBI device even in case of success, because + * 'ubi_open_volume()' took a reference as well. + */ + ubi_put_device(ubi); + return ret; +} +EXPORT_SYMBOL_GPL(ubi_open_volume_nm); + +/** + * ubi_close_volume - close UBI volume. + * @desc: volume descriptor + */ +void ubi_close_volume(struct ubi_volume_desc *desc) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + + dbg_msg("close volume %d, mode %d", vol->vol_id, desc->mode); + + spin_lock(&ubi->volumes_lock); + switch (desc->mode) { + case UBI_READONLY: + vol->readers -= 1; + break; + case UBI_READWRITE: + vol->writers -= 1; + break; + case UBI_EXCLUSIVE: + vol->exclusive = 0; + } + vol->ref_count -= 1; + spin_unlock(&ubi->volumes_lock); + + kfree(desc); + put_device(&vol->dev); + ubi_put_device(ubi); + module_put(THIS_MODULE); +} +EXPORT_SYMBOL_GPL(ubi_close_volume); + +/** + * ubi_leb_read - read data. + * @desc: volume descriptor + * @lnum: logical eraseblock number to read from + * @buf: buffer where to store the read data + * @offset: offset within the logical eraseblock to read from + * @len: how many bytes to read + * @check: whether UBI has to check the read data's CRC or not. + * + * This function reads data from offset @offset of logical eraseblock @lnum and + * stores the data at @buf. When reading from static volumes, @check specifies + * whether the data has to be checked or not. If yes, the whole logical + * eraseblock will be read and its CRC checksum will be checked (i.e., the CRC + * checksum is per-eraseblock). So checking may substantially slow down the + * read speed. The @check argument is ignored for dynamic volumes. + * + * In case of success, this function returns zero. In case of failure, this + * function returns a negative error code. + * + * %-EBADMSG error code is returned: + * o for both static and dynamic volumes if MTD driver has detected a data + * integrity problem (unrecoverable ECC checksum mismatch in case of NAND); + * o for static volumes in case of data CRC mismatch. + * + * If the volume is damaged because of an interrupted update this function just + * returns immediately with %-EBADF error code. + */ +int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, + int len, int check) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int err, vol_id = vol->vol_id; + + dbg_msg("read %d bytes from LEB %d:%d:%d", len, vol_id, lnum, offset); + + if (vol_id < 0 || vol_id >= ubi->vtbl_slots || lnum < 0 || + lnum >= vol->used_ebs || offset < 0 || len < 0 || + offset + len > vol->usable_leb_size) + return -EINVAL; + + if (vol->vol_type == UBI_STATIC_VOLUME) { + if (vol->used_ebs == 0) + /* Empty static UBI volume */ + return 0; + if (lnum == vol->used_ebs - 1 && + offset + len > vol->last_eb_bytes) + return -EINVAL; + } + + if (vol->upd_marker) + return -EBADF; + if (len == 0) + return 0; + + err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check); + if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) { + ubi_warn("mark volume %d as corrupted", vol_id); + vol->corrupted = 1; + } + + return err; +} +EXPORT_SYMBOL_GPL(ubi_leb_read); + +/** + * ubi_leb_write - write data. + * @desc: volume descriptor + * @lnum: logical eraseblock number to write to + * @buf: data to write + * @offset: offset within the logical eraseblock where to write + * @len: how many bytes to write + * @dtype: expected data type + * + * This function writes @len bytes of data from @buf to offset @offset of + * logical eraseblock @lnum. The @dtype argument describes expected lifetime of + * the data. + * + * This function takes care of physical eraseblock write failures. If write to + * the physical eraseblock write operation fails, the logical eraseblock is + * re-mapped to another physical eraseblock, the data is recovered, and the + * write finishes. UBI has a pool of reserved physical eraseblocks for this. + * + * If all the data were successfully written, zero is returned. If an error + * occurred and UBI has not been able to recover from it, this function returns + * a negative error code. Note, in case of an error, it is possible that + * something was still written to the flash media, but that may be some + * garbage. + * + * If the volume is damaged because of an interrupted update this function just + * returns immediately with %-EBADF code. + */ +int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, + int offset, int len, int dtype) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int vol_id = vol->vol_id; + + dbg_msg("write %d bytes to LEB %d:%d:%d", len, vol_id, lnum, offset); + + if (vol_id < 0 || vol_id >= ubi->vtbl_slots) + return -EINVAL; + + if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) + return -EROFS; + + if (lnum < 0 || lnum >= vol->reserved_pebs || offset < 0 || len < 0 || + offset + len > vol->usable_leb_size || + offset & (ubi->min_io_size - 1) || len & (ubi->min_io_size - 1)) + return -EINVAL; + + if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && + dtype != UBI_UNKNOWN) + return -EINVAL; + + if (vol->upd_marker) + return -EBADF; + + if (len == 0) + return 0; + + return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len, dtype); +} +EXPORT_SYMBOL_GPL(ubi_leb_write); + +/* + * ubi_leb_change - change logical eraseblock atomically. + * @desc: volume descriptor + * @lnum: logical eraseblock number to change + * @buf: data to write + * @len: how many bytes to write + * @dtype: expected data type + * + * This function changes the contents of a logical eraseblock atomically. @buf + * has to contain new logical eraseblock data, and @len - the length of the + * data, which has to be aligned. The length may be shorter then the logical + * eraseblock size, ant the logical eraseblock may be appended to more times + * later on. This function guarantees that in case of an unclean reboot the old + * contents is preserved. Returns zero in case of success and a negative error + * code in case of failure. + */ +int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, + int len, int dtype) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int vol_id = vol->vol_id; + + dbg_msg("atomically write %d bytes to LEB %d:%d", len, vol_id, lnum); + + if (vol_id < 0 || vol_id >= ubi->vtbl_slots) + return -EINVAL; + + if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) + return -EROFS; + + if (lnum < 0 || lnum >= vol->reserved_pebs || len < 0 || + len > vol->usable_leb_size || len & (ubi->min_io_size - 1)) + return -EINVAL; + + if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && + dtype != UBI_UNKNOWN) + return -EINVAL; + + if (vol->upd_marker) + return -EBADF; + + if (len == 0) + return 0; + + return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len, dtype); +} +EXPORT_SYMBOL_GPL(ubi_leb_change); + +/** + * ubi_leb_erase - erase logical eraseblock. + * @desc: volume descriptor + * @lnum: logical eraseblock number + * + * This function un-maps logical eraseblock @lnum and synchronously erases the + * correspondent physical eraseblock. Returns zero in case of success and a + * negative error code in case of failure. + * + * If the volume is damaged because of an interrupted update this function just + * returns immediately with %-EBADF code. + */ +int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int err; + + dbg_msg("erase LEB %d:%d", vol->vol_id, lnum); + + if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) + return -EROFS; + + if (lnum < 0 || lnum >= vol->reserved_pebs) + return -EINVAL; + + if (vol->upd_marker) + return -EBADF; + + err = ubi_eba_unmap_leb(ubi, vol, lnum); + if (err) + return err; + + return ubi_wl_flush(ubi); +} +EXPORT_SYMBOL_GPL(ubi_leb_erase); + +/** + * ubi_leb_unmap - un-map logical eraseblock. + * @desc: volume descriptor + * @lnum: logical eraseblock number + * + * This function un-maps logical eraseblock @lnum and schedules the + * corresponding physical eraseblock for erasure, so that it will eventually be + * physically erased in background. This operation is much faster then the + * erase operation. + * + * Unlike erase, the un-map operation does not guarantee that the logical + * eraseblock will contain all 0xFF bytes when UBI is initialized again. For + * example, if several logical eraseblocks are un-mapped, and an unclean reboot + * happens after this, the logical eraseblocks will not necessarily be + * un-mapped again when this MTD device is attached. They may actually be + * mapped to the same physical eraseblocks again. So, this function has to be + * used with care. + * + * In other words, when un-mapping a logical eraseblock, UBI does not store + * any information about this on the flash media, it just marks the logical + * eraseblock as "un-mapped" in RAM. If UBI is detached before the physical + * eraseblock is physically erased, it will be mapped again to the same logical + * eraseblock when the MTD device is attached again. + * + * The main and obvious use-case of this function is when the contents of a + * logical eraseblock has to be re-written. Then it is much more efficient to + * first un-map it, then write new data, rather then first erase it, then write + * new data. Note, once new data has been written to the logical eraseblock, + * UBI guarantees that the old contents has gone forever. In other words, if an + * unclean reboot happens after the logical eraseblock has been un-mapped and + * then written to, it will contain the last written data. + * + * This function returns zero in case of success and a negative error code in + * case of failure. If the volume is damaged because of an interrupted update + * this function just returns immediately with %-EBADF code. + */ +int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + + dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); + + if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) + return -EROFS; + + if (lnum < 0 || lnum >= vol->reserved_pebs) + return -EINVAL; + + if (vol->upd_marker) + return -EBADF; + + return ubi_eba_unmap_leb(ubi, vol, lnum); +} +EXPORT_SYMBOL_GPL(ubi_leb_unmap); + +/** + * ubi_leb_map - map logical erasblock to a physical eraseblock. + * @desc: volume descriptor + * @lnum: logical eraseblock number + * @dtype: expected data type + * + * This function maps an un-mapped logical eraseblock @lnum to a physical + * eraseblock. This means, that after a successfull invocation of this + * function the logical eraseblock @lnum will be empty (contain only %0xFF + * bytes) and be mapped to a physical eraseblock, even if an unclean reboot + * happens. + * + * This function returns zero in case of success, %-EBADF if the volume is + * damaged because of an interrupted update, %-EBADMSG if the logical + * eraseblock is already mapped, and other negative error codes in case of + * other failures. + */ +int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + + dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); + + if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) + return -EROFS; + + if (lnum < 0 || lnum >= vol->reserved_pebs) + return -EINVAL; + + if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && + dtype != UBI_UNKNOWN) + return -EINVAL; + + if (vol->upd_marker) + return -EBADF; + + if (vol->eba_tbl[lnum] >= 0) + return -EBADMSG; + + return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); +} +EXPORT_SYMBOL_GPL(ubi_leb_map); + +/** + * ubi_is_mapped - check if logical eraseblock is mapped. + * @desc: volume descriptor + * @lnum: logical eraseblock number + * + * This function checks if logical eraseblock @lnum is mapped to a physical + * eraseblock. If a logical eraseblock is un-mapped, this does not necessarily + * mean it will still be un-mapped after the UBI device is re-attached. The + * logical eraseblock may become mapped to the physical eraseblock it was last + * mapped to. + * + * This function returns %1 if the LEB is mapped, %0 if not, and a negative + * error code in case of failure. If the volume is damaged because of an + * interrupted update this function just returns immediately with %-EBADF error + * code. + */ +int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum) +{ + struct ubi_volume *vol = desc->vol; + + dbg_msg("test LEB %d:%d", vol->vol_id, lnum); + + if (lnum < 0 || lnum >= vol->reserved_pebs) + return -EINVAL; + + if (vol->upd_marker) + return -EBADF; + + return vol->eba_tbl[lnum] >= 0; +} +EXPORT_SYMBOL_GPL(ubi_is_mapped); diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c new file mode 100644 index 0000000..a6410bf --- /dev/null +++ b/drivers/mtd/ubi/misc.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* Here we keep miscellaneous functions which are used all over the UBI code */ + +#include +#include "ubi.h" + +/** + * calc_data_len - calculate how much real data is stored in a buffer. + * @ubi: UBI device description object + * @buf: a buffer with the contents of the physical eraseblock + * @length: the buffer length + * + * This function calculates how much "real data" is stored in @buf and returnes + * the length. Continuous 0xFF bytes at the end of the buffer are not + * considered as "real data". + */ +int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, + int length) +{ + int i; + + ubi_assert(!(length & (ubi->min_io_size - 1))); + + for (i = length - 1; i >= 0; i--) + if (((const uint8_t *)buf)[i] != 0xFF) + break; + + /* The resulting length must be aligned to the minimum flash I/O size */ + length = ALIGN(i + 1, ubi->min_io_size); + return length; +} + +/** + * ubi_check_volume - check the contents of a static volume. + * @ubi: UBI device description object + * @vol_id: ID of the volume to check + * + * This function checks if static volume @vol_id is corrupted by fully reading + * it and checking data CRC. This function returns %0 if the volume is not + * corrupted, %1 if it is corrupted and a negative error code in case of + * failure. Dynamic volumes are not checked and zero is returned immediately. + */ +int ubi_check_volume(struct ubi_device *ubi, int vol_id) +{ + void *buf; + int err = 0, i; + struct ubi_volume *vol = ubi->volumes[vol_id]; + + if (vol->vol_type != UBI_STATIC_VOLUME) + return 0; + + buf = vmalloc(vol->usable_leb_size); + if (!buf) + return -ENOMEM; + + for (i = 0; i < vol->used_ebs; i++) { + int size; + + if (i == vol->used_ebs - 1) + size = vol->last_eb_bytes; + else + size = vol->usable_leb_size; + + err = ubi_eba_read_leb(ubi, vol, i, buf, 0, size, 1); + if (err) { + if (err == -EBADMSG) + err = 1; + break; + } + } + + vfree(buf); + return err; +} + +/** + * ubi_calculate_rsvd_pool - calculate how many PEBs must be reserved for bad + * eraseblock handling. + * @ubi: UBI device description object + */ +void ubi_calculate_reserved(struct ubi_device *ubi) +{ + ubi->beb_rsvd_level = ubi->good_peb_count/100; + ubi->beb_rsvd_level *= CONFIG_MTD_UBI_BEB_RESERVE; + if (ubi->beb_rsvd_level < MIN_RESEVED_PEBS) + ubi->beb_rsvd_level = MIN_RESEVED_PEBS; +} -- cgit v1.1 From f412fefa079c6aa9a9763f6869bf787ea6bf6e1b Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:27:23 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 4/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- drivers/mtd/ubi/scan.c | 1360 +++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/ubi/scan.h | 165 ++++++ drivers/mtd/ubi/ubi-media.h | 372 ++++++++++++ drivers/mtd/ubi/ubi.h | 641 ++++++++++++++++++++ 4 files changed, 2538 insertions(+) create mode 100644 drivers/mtd/ubi/scan.c create mode 100644 drivers/mtd/ubi/scan.h create mode 100644 drivers/mtd/ubi/ubi-media.h create mode 100644 drivers/mtd/ubi/ubi.h diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c new file mode 100644 index 0000000..d5c1d27 --- /dev/null +++ b/drivers/mtd/ubi/scan.c @@ -0,0 +1,1360 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * UBI scanning unit. + * + * This unit is responsible for scanning the flash media, checking UBI + * headers and providing complete information about the UBI flash image. + * + * The scanning information is represented by a &struct ubi_scan_info' object. + * Information about found volumes is represented by &struct ubi_scan_volume + * objects which are kept in volume RB-tree with root at the @volumes field. + * The RB-tree is indexed by the volume ID. + * + * Found logical eraseblocks are represented by &struct ubi_scan_leb objects. + * These objects are kept in per-volume RB-trees with the root at the + * corresponding &struct ubi_scan_volume object. To put it differently, we keep + * an RB-tree of per-volume objects and each of these objects is the root of + * RB-tree of per-eraseblock objects. + * + * Corrupted physical eraseblocks are put to the @corr list, free physical + * eraseblocks are put to the @free list and the physical eraseblock to be + * erased are put to the @erase list. + */ + +#ifdef UBI_LINUX +#include +#include +#include +#endif + +#include +#include "ubi.h" + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si); +#else +#define paranoid_check_si(ubi, si) 0 +#endif + +/* Temporary variables used during scanning */ +static struct ubi_ec_hdr *ech; +static struct ubi_vid_hdr *vidh; + +/** + * add_to_list - add physical eraseblock to a list. + * @si: scanning information + * @pnum: physical eraseblock number to add + * @ec: erase counter of the physical eraseblock + * @list: the list to add to + * + * This function adds physical eraseblock @pnum to free, erase, corrupted or + * alien lists. Returns zero in case of success and a negative error code in + * case of failure. + */ +static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, + struct list_head *list) +{ + struct ubi_scan_leb *seb; + + if (list == &si->free) + dbg_bld("add to free: PEB %d, EC %d", pnum, ec); + else if (list == &si->erase) + dbg_bld("add to erase: PEB %d, EC %d", pnum, ec); + else if (list == &si->corr) + dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec); + else if (list == &si->alien) + dbg_bld("add to alien: PEB %d, EC %d", pnum, ec); + else + BUG(); + + seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); + if (!seb) + return -ENOMEM; + + seb->pnum = pnum; + seb->ec = ec; + list_add_tail(&seb->u.list, list); + return 0; +} + +/** + * validate_vid_hdr - check that volume identifier header is correct and + * consistent. + * @vid_hdr: the volume identifier header to check + * @sv: information about the volume this logical eraseblock belongs to + * @pnum: physical eraseblock number the VID header came from + * + * This function checks that data stored in @vid_hdr is consistent. Returns + * non-zero if an inconsistency was found and zero if not. + * + * Note, UBI does sanity check of everything it reads from the flash media. + * Most of the checks are done in the I/O unit. Here we check that the + * information in the VID header is consistent to the information in other VID + * headers of the same volume. + */ +static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, + const struct ubi_scan_volume *sv, int pnum) +{ + int vol_type = vid_hdr->vol_type; + int vol_id = be32_to_cpu(vid_hdr->vol_id); + int used_ebs = be32_to_cpu(vid_hdr->used_ebs); + int data_pad = be32_to_cpu(vid_hdr->data_pad); + + if (sv->leb_count != 0) { + int sv_vol_type; + + /* + * This is not the first logical eraseblock belonging to this + * volume. Ensure that the data in its VID header is consistent + * to the data in previous logical eraseblock headers. + */ + + if (vol_id != sv->vol_id) { + dbg_err("inconsistent vol_id"); + goto bad; + } + + if (sv->vol_type == UBI_STATIC_VOLUME) + sv_vol_type = UBI_VID_STATIC; + else + sv_vol_type = UBI_VID_DYNAMIC; + + if (vol_type != sv_vol_type) { + dbg_err("inconsistent vol_type"); + goto bad; + } + + if (used_ebs != sv->used_ebs) { + dbg_err("inconsistent used_ebs"); + goto bad; + } + + if (data_pad != sv->data_pad) { + dbg_err("inconsistent data_pad"); + goto bad; + } + } + + return 0; + +bad: + ubi_err("inconsistent VID header at PEB %d", pnum); + ubi_dbg_dump_vid_hdr(vid_hdr); + ubi_dbg_dump_sv(sv); + return -EINVAL; +} + +/** + * add_volume - add volume to the scanning information. + * @si: scanning information + * @vol_id: ID of the volume to add + * @pnum: physical eraseblock number + * @vid_hdr: volume identifier header + * + * If the volume corresponding to the @vid_hdr logical eraseblock is already + * present in the scanning information, this function does nothing. Otherwise + * it adds corresponding volume to the scanning information. Returns a pointer + * to the scanning volume object in case of success and a negative error code + * in case of failure. + */ +static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, + int pnum, + const struct ubi_vid_hdr *vid_hdr) +{ + struct ubi_scan_volume *sv; + struct rb_node **p = &si->volumes.rb_node, *parent = NULL; + + ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); + + /* Walk the volume RB-tree to look if this volume is already present */ + while (*p) { + parent = *p; + sv = rb_entry(parent, struct ubi_scan_volume, rb); + + if (vol_id == sv->vol_id) + return sv; + + if (vol_id > sv->vol_id) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + /* The volume is absent - add it */ + sv = kmalloc(sizeof(struct ubi_scan_volume), GFP_KERNEL); + if (!sv) + return ERR_PTR(-ENOMEM); + + sv->highest_lnum = sv->leb_count = 0; + sv->vol_id = vol_id; + sv->root = RB_ROOT; + sv->used_ebs = be32_to_cpu(vid_hdr->used_ebs); + sv->data_pad = be32_to_cpu(vid_hdr->data_pad); + sv->compat = vid_hdr->compat; + sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME + : UBI_STATIC_VOLUME; + if (vol_id > si->highest_vol_id) + si->highest_vol_id = vol_id; + + rb_link_node(&sv->rb, parent, p); + rb_insert_color(&sv->rb, &si->volumes); + si->vols_found += 1; + dbg_bld("added volume %d", vol_id); + return sv; +} + +/** + * compare_lebs - find out which logical eraseblock is newer. + * @ubi: UBI device description object + * @seb: first logical eraseblock to compare + * @pnum: physical eraseblock number of the second logical eraseblock to + * compare + * @vid_hdr: volume identifier header of the second logical eraseblock + * + * This function compares 2 copies of a LEB and informs which one is newer. In + * case of success this function returns a positive value, in case of failure, a + * negative error code is returned. The success return codes use the following + * bits: + * o bit 0 is cleared: the first PEB (described by @seb) is newer then the + * second PEB (described by @pnum and @vid_hdr); + * o bit 0 is set: the second PEB is newer; + * o bit 1 is cleared: no bit-flips were detected in the newer LEB; + * o bit 1 is set: bit-flips were detected in the newer LEB; + * o bit 2 is cleared: the older LEB is not corrupted; + * o bit 2 is set: the older LEB is corrupted. + */ +static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb, + int pnum, const struct ubi_vid_hdr *vid_hdr) +{ + void *buf; + int len, err, second_is_newer, bitflips = 0, corrupted = 0; + uint32_t data_crc, crc; + struct ubi_vid_hdr *vh = NULL; + unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); + + if (seb->sqnum == 0 && sqnum2 == 0) { + long long abs, v1 = seb->leb_ver, v2 = be32_to_cpu(vid_hdr->leb_ver); + + /* + * UBI constantly increases the logical eraseblock version + * number and it can overflow. Thus, we have to bear in mind + * that versions that are close to %0xFFFFFFFF are less then + * versions that are close to %0. + * + * The UBI WL unit guarantees that the number of pending tasks + * is not greater then %0x7FFFFFFF. So, if the difference + * between any two versions is greater or equivalent to + * %0x7FFFFFFF, there was an overflow and the logical + * eraseblock with lower version is actually newer then the one + * with higher version. + * + * FIXME: but this is anyway obsolete and will be removed at + * some point. + */ + dbg_bld("using old crappy leb_ver stuff"); + + if (v1 == v2) { + ubi_err("PEB %d and PEB %d have the same version %lld", + seb->pnum, pnum, v1); + return -EINVAL; + } + + abs = v1 - v2; + if (abs < 0) + abs = -abs; + + if (abs < 0x7FFFFFFF) + /* Non-overflow situation */ + second_is_newer = (v2 > v1); + else + second_is_newer = (v2 < v1); + } else + /* Obviously the LEB with lower sequence counter is older */ + second_is_newer = sqnum2 > seb->sqnum; + + /* + * Now we know which copy is newer. If the copy flag of the PEB with + * newer version is not set, then we just return, otherwise we have to + * check data CRC. For the second PEB we already have the VID header, + * for the first one - we'll need to re-read it from flash. + * + * FIXME: this may be optimized so that we wouldn't read twice. + */ + + if (second_is_newer) { + if (!vid_hdr->copy_flag) { + /* It is not a copy, so it is newer */ + dbg_bld("second PEB %d is newer, copy_flag is unset", + pnum); + return 1; + } + } else { + pnum = seb->pnum; + + vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vh) + return -ENOMEM; + + err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); + if (err) { + if (err == UBI_IO_BITFLIPS) + bitflips = 1; + else { + dbg_err("VID of PEB %d header is bad, but it " + "was OK earlier", pnum); + if (err > 0) + err = -EIO; + + goto out_free_vidh; + } + } + + if (!vh->copy_flag) { + /* It is not a copy, so it is newer */ + dbg_bld("first PEB %d is newer, copy_flag is unset", + pnum); + err = bitflips << 1; + goto out_free_vidh; + } + + vid_hdr = vh; + } + + /* Read the data of the copy and check the CRC */ + + len = be32_to_cpu(vid_hdr->data_size); + buf = vmalloc(len); + if (!buf) { + err = -ENOMEM; + goto out_free_vidh; + } + + err = ubi_io_read_data(ubi, buf, pnum, 0, len); + if (err && err != UBI_IO_BITFLIPS) + goto out_free_buf; + + data_crc = be32_to_cpu(vid_hdr->data_crc); + crc = crc32(UBI_CRC32_INIT, buf, len); + if (crc != data_crc) { + dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", + pnum, crc, data_crc); + corrupted = 1; + bitflips = 0; + second_is_newer = !second_is_newer; + } else { + dbg_bld("PEB %d CRC is OK", pnum); + bitflips = !!err; + } + + vfree(buf); + ubi_free_vid_hdr(ubi, vh); + + if (second_is_newer) + dbg_bld("second PEB %d is newer, copy_flag is set", pnum); + else + dbg_bld("first PEB %d is newer, copy_flag is set", pnum); + + return second_is_newer | (bitflips << 1) | (corrupted << 2); + +out_free_buf: + vfree(buf); +out_free_vidh: + ubi_free_vid_hdr(ubi, vh); + return err; +} + +/** + * ubi_scan_add_used - add information about a physical eraseblock to the + * scanning information. + * @ubi: UBI device description object + * @si: scanning information + * @pnum: the physical eraseblock number + * @ec: erase counter + * @vid_hdr: the volume identifier header + * @bitflips: if bit-flips were detected when this physical eraseblock was read + * + * This function adds information about a used physical eraseblock to the + * 'used' tree of the corresponding volume. The function is rather complex + * because it has to handle cases when this is not the first physical + * eraseblock belonging to the same logical eraseblock, and the newer one has + * to be picked, while the older one has to be dropped. This function returns + * zero in case of success and a negative error code in case of failure. + */ +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, + int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, + int bitflips) +{ + int err, vol_id, lnum; + uint32_t leb_ver; + unsigned long long sqnum; + struct ubi_scan_volume *sv; + struct ubi_scan_leb *seb; + struct rb_node **p, *parent = NULL; + + vol_id = be32_to_cpu(vid_hdr->vol_id); + lnum = be32_to_cpu(vid_hdr->lnum); + sqnum = be64_to_cpu(vid_hdr->sqnum); + leb_ver = be32_to_cpu(vid_hdr->leb_ver); + + dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, ver %u, bitflips %d", + pnum, vol_id, lnum, ec, sqnum, leb_ver, bitflips); + + sv = add_volume(si, vol_id, pnum, vid_hdr); + if (IS_ERR(sv) < 0) + return PTR_ERR(sv); + + if (si->max_sqnum < sqnum) + si->max_sqnum = sqnum; + + /* + * Walk the RB-tree of logical eraseblocks of volume @vol_id to look + * if this is the first instance of this logical eraseblock or not. + */ + p = &sv->root.rb_node; + while (*p) { + int cmp_res; + + parent = *p; + seb = rb_entry(parent, struct ubi_scan_leb, u.rb); + if (lnum != seb->lnum) { + if (lnum < seb->lnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + continue; + } + + /* + * There is already a physical eraseblock describing the same + * logical eraseblock present. + */ + + dbg_bld("this LEB already exists: PEB %d, sqnum %llu, " + "LEB ver %u, EC %d", seb->pnum, seb->sqnum, + seb->leb_ver, seb->ec); + + /* + * Make sure that the logical eraseblocks have different + * versions. Otherwise the image is bad. + */ + if (seb->leb_ver == leb_ver && leb_ver != 0) { + ubi_err("two LEBs with same version %u", leb_ver); + ubi_dbg_dump_seb(seb, 0); + ubi_dbg_dump_vid_hdr(vid_hdr); + return -EINVAL; + } + + /* + * Make sure that the logical eraseblocks have different + * sequence numbers. Otherwise the image is bad. + * + * FIXME: remove 'sqnum != 0' check when leb_ver is removed. + */ + if (seb->sqnum == sqnum && sqnum != 0) { + ubi_err("two LEBs with same sequence number %llu", + sqnum); + ubi_dbg_dump_seb(seb, 0); + ubi_dbg_dump_vid_hdr(vid_hdr); + return -EINVAL; + } + + /* + * Now we have to drop the older one and preserve the newer + * one. + */ + cmp_res = compare_lebs(ubi, seb, pnum, vid_hdr); + if (cmp_res < 0) + return cmp_res; + + if (cmp_res & 1) { + /* + * This logical eraseblock is newer then the one + * found earlier. + */ + err = validate_vid_hdr(vid_hdr, sv, pnum); + if (err) + return err; + + if (cmp_res & 4) + err = add_to_list(si, seb->pnum, seb->ec, + &si->corr); + else + err = add_to_list(si, seb->pnum, seb->ec, + &si->erase); + if (err) + return err; + + seb->ec = ec; + seb->pnum = pnum; + seb->scrub = ((cmp_res & 2) || bitflips); + seb->sqnum = sqnum; + seb->leb_ver = leb_ver; + + if (sv->highest_lnum == lnum) + sv->last_data_size = + be32_to_cpu(vid_hdr->data_size); + + return 0; + } else { + /* + * This logical eraseblock is older then the one found + * previously. + */ + if (cmp_res & 4) + return add_to_list(si, pnum, ec, &si->corr); + else + return add_to_list(si, pnum, ec, &si->erase); + } + } + + /* + * We've met this logical eraseblock for the first time, add it to the + * scanning information. + */ + + err = validate_vid_hdr(vid_hdr, sv, pnum); + if (err) + return err; + + seb = kmalloc(sizeof(struct ubi_scan_leb), GFP_KERNEL); + if (!seb) + return -ENOMEM; + + seb->ec = ec; + seb->pnum = pnum; + seb->lnum = lnum; + seb->sqnum = sqnum; + seb->scrub = bitflips; + seb->leb_ver = leb_ver; + + if (sv->highest_lnum <= lnum) { + sv->highest_lnum = lnum; + sv->last_data_size = be32_to_cpu(vid_hdr->data_size); + } + + sv->leb_count += 1; + rb_link_node(&seb->u.rb, parent, p); + rb_insert_color(&seb->u.rb, &sv->root); + return 0; +} + +/** + * ubi_scan_find_sv - find information about a particular volume in the + * scanning information. + * @si: scanning information + * @vol_id: the requested volume ID + * + * This function returns a pointer to the volume description or %NULL if there + * are no data about this volume in the scanning information. + */ +struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, + int vol_id) +{ + struct ubi_scan_volume *sv; + struct rb_node *p = si->volumes.rb_node; + + while (p) { + sv = rb_entry(p, struct ubi_scan_volume, rb); + + if (vol_id == sv->vol_id) + return sv; + + if (vol_id > sv->vol_id) + p = p->rb_left; + else + p = p->rb_right; + } + + return NULL; +} + +/** + * ubi_scan_find_seb - find information about a particular logical + * eraseblock in the volume scanning information. + * @sv: a pointer to the volume scanning information + * @lnum: the requested logical eraseblock + * + * This function returns a pointer to the scanning logical eraseblock or %NULL + * if there are no data about it in the scanning volume information. + */ +struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, + int lnum) +{ + struct ubi_scan_leb *seb; + struct rb_node *p = sv->root.rb_node; + + while (p) { + seb = rb_entry(p, struct ubi_scan_leb, u.rb); + + if (lnum == seb->lnum) + return seb; + + if (lnum > seb->lnum) + p = p->rb_left; + else + p = p->rb_right; + } + + return NULL; +} + +/** + * ubi_scan_rm_volume - delete scanning information about a volume. + * @si: scanning information + * @sv: the volume scanning information to delete + */ +void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv) +{ + struct rb_node *rb; + struct ubi_scan_leb *seb; + + dbg_bld("remove scanning information about volume %d", sv->vol_id); + + while ((rb = rb_first(&sv->root))) { + seb = rb_entry(rb, struct ubi_scan_leb, u.rb); + rb_erase(&seb->u.rb, &sv->root); + list_add_tail(&seb->u.list, &si->erase); + } + + rb_erase(&sv->rb, &si->volumes); + kfree(sv); + si->vols_found -= 1; +} + +/** + * ubi_scan_erase_peb - erase a physical eraseblock. + * @ubi: UBI device description object + * @si: scanning information + * @pnum: physical eraseblock number to erase; + * @ec: erase counter value to write (%UBI_SCAN_UNKNOWN_EC if it is unknown) + * + * This function erases physical eraseblock 'pnum', and writes the erase + * counter header to it. This function should only be used on UBI device + * initialization stages, when the EBA unit had not been yet initialized. This + * function returns zero in case of success and a negative error code in case + * of failure. + */ +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, + int pnum, int ec) +{ + int err; + struct ubi_ec_hdr *ec_hdr; + + if ((long long)ec >= UBI_MAX_ERASECOUNTER) { + /* + * Erase counter overflow. Upgrade UBI and use 64-bit + * erase counters internally. + */ + ubi_err("erase counter overflow at PEB %d, EC %d", pnum, ec); + return -EINVAL; + } + + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ec_hdr) + return -ENOMEM; + + ec_hdr->ec = cpu_to_be64(ec); + + err = ubi_io_sync_erase(ubi, pnum, 0); + if (err < 0) + goto out_free; + + err = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr); + +out_free: + kfree(ec_hdr); + return err; +} + +/** + * ubi_scan_get_free_peb - get a free physical eraseblock. + * @ubi: UBI device description object + * @si: scanning information + * + * This function returns a free physical eraseblock. It is supposed to be + * called on the UBI initialization stages when the wear-leveling unit is not + * initialized yet. This function picks a physical eraseblocks from one of the + * lists, writes the EC header if it is needed, and removes it from the list. + * + * This function returns scanning physical eraseblock information in case of + * success and an error code in case of failure. + */ +struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, + struct ubi_scan_info *si) +{ + int err = 0, i; + struct ubi_scan_leb *seb; + + if (!list_empty(&si->free)) { + seb = list_entry(si->free.next, struct ubi_scan_leb, u.list); + list_del(&seb->u.list); + dbg_bld("return free PEB %d, EC %d", seb->pnum, seb->ec); + return seb; + } + + for (i = 0; i < 2; i++) { + struct list_head *head; + struct ubi_scan_leb *tmp_seb; + + if (i == 0) + head = &si->erase; + else + head = &si->corr; + + /* + * We try to erase the first physical eraseblock from the @head + * list and pick it if we succeed, or try to erase the + * next one if not. And so forth. We don't want to take care + * about bad eraseblocks here - they'll be handled later. + */ + list_for_each_entry_safe(seb, tmp_seb, head, u.list) { + if (seb->ec == UBI_SCAN_UNKNOWN_EC) + seb->ec = si->mean_ec; + + err = ubi_scan_erase_peb(ubi, si, seb->pnum, seb->ec+1); + if (err) + continue; + + seb->ec += 1; + list_del(&seb->u.list); + dbg_bld("return PEB %d, EC %d", seb->pnum, seb->ec); + return seb; + } + } + + ubi_err("no eraseblocks found"); + return ERR_PTR(-ENOSPC); +} + +/** + * process_eb - read UBI headers, check them and add corresponding data + * to the scanning information. + * @ubi: UBI device description object + * @si: scanning information + * @pnum: the physical eraseblock number + * + * This function returns a zero if the physical eraseblock was successfully + * handled and a negative error code in case of failure. + */ +static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) +{ + long long uninitialized_var(ec); + int err, bitflips = 0, vol_id, ec_corr = 0; + + dbg_bld("scan PEB %d", pnum); + + /* Skip bad physical eraseblocks */ + err = ubi_io_is_bad(ubi, pnum); + if (err < 0) + return err; + else if (err) { + /* + * FIXME: this is actually duty of the I/O unit to initialize + * this, but MTD does not provide enough information. + */ + si->bad_peb_count += 1; + return 0; + } + + err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); + if (err < 0) + return err; + else if (err == UBI_IO_BITFLIPS) + bitflips = 1; + else if (err == UBI_IO_PEB_EMPTY) + return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase); + else if (err == UBI_IO_BAD_EC_HDR) { + /* + * We have to also look at the VID header, possibly it is not + * corrupted. Set %bitflips flag in order to make this PEB be + * moved and EC be re-created. + */ + ec_corr = 1; + ec = UBI_SCAN_UNKNOWN_EC; + bitflips = 1; + } + + si->is_empty = 0; + + if (!ec_corr) { + /* Make sure UBI version is OK */ + if (ech->version != UBI_VERSION) { + ubi_err("this UBI version is %d, image version is %d", + UBI_VERSION, (int)ech->version); + return -EINVAL; + } + + ec = be64_to_cpu(ech->ec); + if (ec > UBI_MAX_ERASECOUNTER) { + /* + * Erase counter overflow. The EC headers have 64 bits + * reserved, but we anyway make use of only 31 bit + * values, as this seems to be enough for any existing + * flash. Upgrade UBI and use 64-bit erase counters + * internally. + */ + ubi_err("erase counter overflow, max is %d", + UBI_MAX_ERASECOUNTER); + ubi_dbg_dump_ec_hdr(ech); + return -EINVAL; + } + } + + /* OK, we've done with the EC header, let's look at the VID header */ + + err = ubi_io_read_vid_hdr(ubi, pnum, vidh, 0); + if (err < 0) + return err; + else if (err == UBI_IO_BITFLIPS) + bitflips = 1; + else if (err == UBI_IO_BAD_VID_HDR || + (err == UBI_IO_PEB_FREE && ec_corr)) { + /* VID header is corrupted */ + err = add_to_list(si, pnum, ec, &si->corr); + if (err) + return err; + goto adjust_mean_ec; + } else if (err == UBI_IO_PEB_FREE) { + /* No VID header - the physical eraseblock is free */ + err = add_to_list(si, pnum, ec, &si->free); + if (err) + return err; + goto adjust_mean_ec; + } + + vol_id = be32_to_cpu(vidh->vol_id); + if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) { + int lnum = be32_to_cpu(vidh->lnum); + + /* Unsupported internal volume */ + switch (vidh->compat) { + case UBI_COMPAT_DELETE: + ubi_msg("\"delete\" compatible internal volume %d:%d" + " found, remove it", vol_id, lnum); + err = add_to_list(si, pnum, ec, &si->corr); + if (err) + return err; + break; + + case UBI_COMPAT_RO: + ubi_msg("read-only compatible internal volume %d:%d" + " found, switch to read-only mode", + vol_id, lnum); + ubi->ro_mode = 1; + break; + + case UBI_COMPAT_PRESERVE: + ubi_msg("\"preserve\" compatible internal volume %d:%d" + " found", vol_id, lnum); + err = add_to_list(si, pnum, ec, &si->alien); + if (err) + return err; + si->alien_peb_count += 1; + return 0; + + case UBI_COMPAT_REJECT: + ubi_err("incompatible internal volume %d:%d found", + vol_id, lnum); + return -EINVAL; + } + } + + /* Both UBI headers seem to be fine */ + err = ubi_scan_add_used(ubi, si, pnum, ec, vidh, bitflips); + if (err) + return err; + +adjust_mean_ec: + if (!ec_corr) { + si->ec_sum += ec; + si->ec_count += 1; + if (ec > si->max_ec) + si->max_ec = ec; + if (ec < si->min_ec) + si->min_ec = ec; + } + + return 0; +} + +/** + * ubi_scan - scan an MTD device. + * @ubi: UBI device description object + * + * This function does full scanning of an MTD device and returns complete + * information about it. In case of failure, an error code is returned. + */ +struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) +{ + int err, pnum; + struct rb_node *rb1, *rb2; + struct ubi_scan_volume *sv; + struct ubi_scan_leb *seb; + struct ubi_scan_info *si; + + si = kzalloc(sizeof(struct ubi_scan_info), GFP_KERNEL); + if (!si) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&si->corr); + INIT_LIST_HEAD(&si->free); + INIT_LIST_HEAD(&si->erase); + INIT_LIST_HEAD(&si->alien); + si->volumes = RB_ROOT; + si->is_empty = 1; + + err = -ENOMEM; + ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); + if (!ech) + goto out_si; + + vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vidh) + goto out_ech; + + for (pnum = 0; pnum < ubi->peb_count; pnum++) { + cond_resched(); + + dbg_msg("process PEB %d", pnum); + err = process_eb(ubi, si, pnum); + if (err < 0) + goto out_vidh; + } + + dbg_msg("scanning is finished"); + + /* Calculate mean erase counter */ + if (si->ec_count) { + do_div(si->ec_sum, si->ec_count); + si->mean_ec = si->ec_sum; + } + + if (si->is_empty) + ubi_msg("empty MTD device detected"); + + /* + * In case of unknown erase counter we use the mean erase counter + * value. + */ + ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) + if (seb->ec == UBI_SCAN_UNKNOWN_EC) + seb->ec = si->mean_ec; + } + + list_for_each_entry(seb, &si->free, u.list) { + if (seb->ec == UBI_SCAN_UNKNOWN_EC) + seb->ec = si->mean_ec; + } + + list_for_each_entry(seb, &si->corr, u.list) + if (seb->ec == UBI_SCAN_UNKNOWN_EC) + seb->ec = si->mean_ec; + + list_for_each_entry(seb, &si->erase, u.list) + if (seb->ec == UBI_SCAN_UNKNOWN_EC) + seb->ec = si->mean_ec; + + err = paranoid_check_si(ubi, si); + if (err) { + if (err > 0) + err = -EINVAL; + goto out_vidh; + } + + ubi_free_vid_hdr(ubi, vidh); + kfree(ech); + + return si; + +out_vidh: + ubi_free_vid_hdr(ubi, vidh); +out_ech: + kfree(ech); +out_si: + ubi_scan_destroy_si(si); + return ERR_PTR(err); +} + +/** + * destroy_sv - free the scanning volume information + * @sv: scanning volume information + * + * This function destroys the volume RB-tree (@sv->root) and the scanning + * volume information. + */ +static void destroy_sv(struct ubi_scan_volume *sv) +{ + struct ubi_scan_leb *seb; + struct rb_node *this = sv->root.rb_node; + + while (this) { + if (this->rb_left) + this = this->rb_left; + else if (this->rb_right) + this = this->rb_right; + else { + seb = rb_entry(this, struct ubi_scan_leb, u.rb); + this = rb_parent(this); + if (this) { + if (this->rb_left == &seb->u.rb) + this->rb_left = NULL; + else + this->rb_right = NULL; + } + + kfree(seb); + } + } + kfree(sv); +} + +/** + * ubi_scan_destroy_si - destroy scanning information. + * @si: scanning information + */ +void ubi_scan_destroy_si(struct ubi_scan_info *si) +{ + struct ubi_scan_leb *seb, *seb_tmp; + struct ubi_scan_volume *sv; + struct rb_node *rb; + + list_for_each_entry_safe(seb, seb_tmp, &si->alien, u.list) { + list_del(&seb->u.list); + kfree(seb); + } + list_for_each_entry_safe(seb, seb_tmp, &si->erase, u.list) { + list_del(&seb->u.list); + kfree(seb); + } + list_for_each_entry_safe(seb, seb_tmp, &si->corr, u.list) { + list_del(&seb->u.list); + kfree(seb); + } + list_for_each_entry_safe(seb, seb_tmp, &si->free, u.list) { + list_del(&seb->u.list); + kfree(seb); + } + + /* Destroy the volume RB-tree */ + rb = si->volumes.rb_node; + while (rb) { + if (rb->rb_left) + rb = rb->rb_left; + else if (rb->rb_right) + rb = rb->rb_right; + else { + sv = rb_entry(rb, struct ubi_scan_volume, rb); + + rb = rb_parent(rb); + if (rb) { + if (rb->rb_left == &sv->rb) + rb->rb_left = NULL; + else + rb->rb_right = NULL; + } + + destroy_sv(sv); + } + } + + kfree(si); +} + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID + +/** + * paranoid_check_si - check if the scanning information is correct and + * consistent. + * @ubi: UBI device description object + * @si: scanning information + * + * This function returns zero if the scanning information is all right, %1 if + * not and a negative error code if an error occurred. + */ +static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) +{ + int pnum, err, vols_found = 0; + struct rb_node *rb1, *rb2; + struct ubi_scan_volume *sv; + struct ubi_scan_leb *seb, *last_seb; + uint8_t *buf; + + /* + * At first, check that scanning information is OK. + */ + ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + int leb_count = 0; + + cond_resched(); + + vols_found += 1; + + if (si->is_empty) { + ubi_err("bad is_empty flag"); + goto bad_sv; + } + + if (sv->vol_id < 0 || sv->highest_lnum < 0 || + sv->leb_count < 0 || sv->vol_type < 0 || sv->used_ebs < 0 || + sv->data_pad < 0 || sv->last_data_size < 0) { + ubi_err("negative values"); + goto bad_sv; + } + + if (sv->vol_id >= UBI_MAX_VOLUMES && + sv->vol_id < UBI_INTERNAL_VOL_START) { + ubi_err("bad vol_id"); + goto bad_sv; + } + + if (sv->vol_id > si->highest_vol_id) { + ubi_err("highest_vol_id is %d, but vol_id %d is there", + si->highest_vol_id, sv->vol_id); + goto out; + } + + if (sv->vol_type != UBI_DYNAMIC_VOLUME && + sv->vol_type != UBI_STATIC_VOLUME) { + ubi_err("bad vol_type"); + goto bad_sv; + } + + if (sv->data_pad > ubi->leb_size / 2) { + ubi_err("bad data_pad"); + goto bad_sv; + } + + last_seb = NULL; + ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { + cond_resched(); + + last_seb = seb; + leb_count += 1; + + if (seb->pnum < 0 || seb->ec < 0) { + ubi_err("negative values"); + goto bad_seb; + } + + if (seb->ec < si->min_ec) { + ubi_err("bad si->min_ec (%d), %d found", + si->min_ec, seb->ec); + goto bad_seb; + } + + if (seb->ec > si->max_ec) { + ubi_err("bad si->max_ec (%d), %d found", + si->max_ec, seb->ec); + goto bad_seb; + } + + if (seb->pnum >= ubi->peb_count) { + ubi_err("too high PEB number %d, total PEBs %d", + seb->pnum, ubi->peb_count); + goto bad_seb; + } + + if (sv->vol_type == UBI_STATIC_VOLUME) { + if (seb->lnum >= sv->used_ebs) { + ubi_err("bad lnum or used_ebs"); + goto bad_seb; + } + } else { + if (sv->used_ebs != 0) { + ubi_err("non-zero used_ebs"); + goto bad_seb; + } + } + + if (seb->lnum > sv->highest_lnum) { + ubi_err("incorrect highest_lnum or lnum"); + goto bad_seb; + } + } + + if (sv->leb_count != leb_count) { + ubi_err("bad leb_count, %d objects in the tree", + leb_count); + goto bad_sv; + } + + if (!last_seb) + continue; + + seb = last_seb; + + if (seb->lnum != sv->highest_lnum) { + ubi_err("bad highest_lnum"); + goto bad_seb; + } + } + + if (vols_found != si->vols_found) { + ubi_err("bad si->vols_found %d, should be %d", + si->vols_found, vols_found); + goto out; + } + + /* Check that scanning information is correct */ + ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + last_seb = NULL; + ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { + int vol_type; + + cond_resched(); + + last_seb = seb; + + err = ubi_io_read_vid_hdr(ubi, seb->pnum, vidh, 1); + if (err && err != UBI_IO_BITFLIPS) { + ubi_err("VID header is not OK (%d)", err); + if (err > 0) + err = -EIO; + return err; + } + + vol_type = vidh->vol_type == UBI_VID_DYNAMIC ? + UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; + if (sv->vol_type != vol_type) { + ubi_err("bad vol_type"); + goto bad_vid_hdr; + } + + if (seb->sqnum != be64_to_cpu(vidh->sqnum)) { + ubi_err("bad sqnum %llu", seb->sqnum); + goto bad_vid_hdr; + } + + if (sv->vol_id != be32_to_cpu(vidh->vol_id)) { + ubi_err("bad vol_id %d", sv->vol_id); + goto bad_vid_hdr; + } + + if (sv->compat != vidh->compat) { + ubi_err("bad compat %d", vidh->compat); + goto bad_vid_hdr; + } + + if (seb->lnum != be32_to_cpu(vidh->lnum)) { + ubi_err("bad lnum %d", seb->lnum); + goto bad_vid_hdr; + } + + if (sv->used_ebs != be32_to_cpu(vidh->used_ebs)) { + ubi_err("bad used_ebs %d", sv->used_ebs); + goto bad_vid_hdr; + } + + if (sv->data_pad != be32_to_cpu(vidh->data_pad)) { + ubi_err("bad data_pad %d", sv->data_pad); + goto bad_vid_hdr; + } + + if (seb->leb_ver != be32_to_cpu(vidh->leb_ver)) { + ubi_err("bad leb_ver %u", seb->leb_ver); + goto bad_vid_hdr; + } + } + + if (!last_seb) + continue; + + if (sv->highest_lnum != be32_to_cpu(vidh->lnum)) { + ubi_err("bad highest_lnum %d", sv->highest_lnum); + goto bad_vid_hdr; + } + + if (sv->last_data_size != be32_to_cpu(vidh->data_size)) { + ubi_err("bad last_data_size %d", sv->last_data_size); + goto bad_vid_hdr; + } + } + + /* + * Make sure that all the physical eraseblocks are in one of the lists + * or trees. + */ + buf = kzalloc(ubi->peb_count, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (pnum = 0; pnum < ubi->peb_count; pnum++) { + err = ubi_io_is_bad(ubi, pnum); + if (err < 0) { + kfree(buf); + return err; + } + else if (err) + buf[pnum] = 1; + } + + ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) + ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) + buf[seb->pnum] = 1; + + list_for_each_entry(seb, &si->free, u.list) + buf[seb->pnum] = 1; + + list_for_each_entry(seb, &si->corr, u.list) + buf[seb->pnum] = 1; + + list_for_each_entry(seb, &si->erase, u.list) + buf[seb->pnum] = 1; + + list_for_each_entry(seb, &si->alien, u.list) + buf[seb->pnum] = 1; + + err = 0; + for (pnum = 0; pnum < ubi->peb_count; pnum++) + if (!buf[pnum]) { + ubi_err("PEB %d is not referred", pnum); + err = 1; + } + + kfree(buf); + if (err) + goto out; + return 0; + +bad_seb: + ubi_err("bad scanning information about LEB %d", seb->lnum); + ubi_dbg_dump_seb(seb, 0); + ubi_dbg_dump_sv(sv); + goto out; + +bad_sv: + ubi_err("bad scanning information about volume %d", sv->vol_id); + ubi_dbg_dump_sv(sv); + goto out; + +bad_vid_hdr: + ubi_err("bad scanning information about volume %d", sv->vol_id); + ubi_dbg_dump_sv(sv); + ubi_dbg_dump_vid_hdr(vidh); + +out: + ubi_dbg_dump_stack(); + return 1; +} + +#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h new file mode 100644 index 0000000..966b9b6 --- /dev/null +++ b/drivers/mtd/ubi/scan.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __UBI_SCAN_H__ +#define __UBI_SCAN_H__ + +/* The erase counter value for this physical eraseblock is unknown */ +#define UBI_SCAN_UNKNOWN_EC (-1) + +/** + * struct ubi_scan_leb - scanning information about a physical eraseblock. + * @ec: erase counter (%UBI_SCAN_UNKNOWN_EC if it is unknown) + * @pnum: physical eraseblock number + * @lnum: logical eraseblock number + * @scrub: if this physical eraseblock needs scrubbing + * @sqnum: sequence number + * @u: unions RB-tree or @list links + * @u.rb: link in the per-volume RB-tree of &struct ubi_scan_leb objects + * @u.list: link in one of the eraseblock lists + * @leb_ver: logical eraseblock version (obsolete) + * + * One object of this type is allocated for each physical eraseblock during + * scanning. + */ +struct ubi_scan_leb { + int ec; + int pnum; + int lnum; + int scrub; + unsigned long long sqnum; + union { + struct rb_node rb; + struct list_head list; + } u; + uint32_t leb_ver; +}; + +/** + * struct ubi_scan_volume - scanning information about a volume. + * @vol_id: volume ID + * @highest_lnum: highest logical eraseblock number in this volume + * @leb_count: number of logical eraseblocks in this volume + * @vol_type: volume type + * @used_ebs: number of used logical eraseblocks in this volume (only for + * static volumes) + * @last_data_size: amount of data in the last logical eraseblock of this + * volume (always equivalent to the usable logical eraseblock size in case of + * dynamic volumes) + * @data_pad: how many bytes at the end of logical eraseblocks of this volume + * are not used (due to volume alignment) + * @compat: compatibility flags of this volume + * @rb: link in the volume RB-tree + * @root: root of the RB-tree containing all the eraseblock belonging to this + * volume (&struct ubi_scan_leb objects) + * + * One object of this type is allocated for each volume during scanning. + */ +struct ubi_scan_volume { + int vol_id; + int highest_lnum; + int leb_count; + int vol_type; + int used_ebs; + int last_data_size; + int data_pad; + int compat; + struct rb_node rb; + struct rb_root root; +}; + +/** + * struct ubi_scan_info - UBI scanning information. + * @volumes: root of the volume RB-tree + * @corr: list of corrupted physical eraseblocks + * @free: list of free physical eraseblocks + * @erase: list of physical eraseblocks which have to be erased + * @alien: list of physical eraseblocks which should not be used by UBI (e.g., + * @bad_peb_count: count of bad physical eraseblocks + * those belonging to "preserve"-compatible internal volumes) + * @vols_found: number of volumes found during scanning + * @highest_vol_id: highest volume ID + * @alien_peb_count: count of physical eraseblocks in the @alien list + * @is_empty: flag indicating whether the MTD device is empty or not + * @min_ec: lowest erase counter value + * @max_ec: highest erase counter value + * @max_sqnum: highest sequence number value + * @mean_ec: mean erase counter value + * @ec_sum: a temporary variable used when calculating @mean_ec + * @ec_count: a temporary variable used when calculating @mean_ec + * + * This data structure contains the result of scanning and may be used by other + * UBI units to build final UBI data structures, further error-recovery and so + * on. + */ +struct ubi_scan_info { + struct rb_root volumes; + struct list_head corr; + struct list_head free; + struct list_head erase; + struct list_head alien; + int bad_peb_count; + int vols_found; + int highest_vol_id; + int alien_peb_count; + int is_empty; + int min_ec; + int max_ec; + unsigned long long max_sqnum; + int mean_ec; + uint64_t ec_sum; + int ec_count; +}; + +struct ubi_device; +struct ubi_vid_hdr; + +/* + * ubi_scan_move_to_list - move a physical eraseblock from the volume tree to a + * list. + * + * @sv: volume scanning information + * @seb: scanning eraseblock infprmation + * @list: the list to move to + */ +static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, + struct ubi_scan_leb *seb, + struct list_head *list) +{ + rb_erase(&seb->u.rb, &sv->root); + list_add_tail(&seb->u.list, list); +} + +int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, + int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, + int bitflips); +struct ubi_scan_volume *ubi_scan_find_sv(const struct ubi_scan_info *si, + int vol_id); +struct ubi_scan_leb *ubi_scan_find_seb(const struct ubi_scan_volume *sv, + int lnum); +void ubi_scan_rm_volume(struct ubi_scan_info *si, struct ubi_scan_volume *sv); +struct ubi_scan_leb *ubi_scan_get_free_peb(struct ubi_device *ubi, + struct ubi_scan_info *si); +int ubi_scan_erase_peb(struct ubi_device *ubi, const struct ubi_scan_info *si, + int pnum, int ec); +struct ubi_scan_info *ubi_scan(struct ubi_device *ubi); +void ubi_scan_destroy_si(struct ubi_scan_info *si); + +#endif /* !__UBI_SCAN_H__ */ diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h new file mode 100644 index 0000000..c3185d9 --- /dev/null +++ b/drivers/mtd/ubi/ubi-media.h @@ -0,0 +1,372 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём) + * Thomas Gleixner + * Frank Haverkamp + * Oliver Lohmann + * Andreas Arnez + */ + +/* + * This file defines the layout of UBI headers and all the other UBI on-flash + * data structures. + */ + +#ifndef __UBI_MEDIA_H__ +#define __UBI_MEDIA_H__ + +#include + +/* The version of UBI images supported by this implementation */ +#define UBI_VERSION 1 + +/* The highest erase counter value supported by this implementation */ +#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF + +/* The initial CRC32 value used when calculating CRC checksums */ +#define UBI_CRC32_INIT 0xFFFFFFFFU + +/* Erase counter header magic number (ASCII "UBI#") */ +#define UBI_EC_HDR_MAGIC 0x55424923 +/* Volume identifier header magic number (ASCII "UBI!") */ +#define UBI_VID_HDR_MAGIC 0x55424921 + +/* + * Volume type constants used in the volume identifier header. + * + * @UBI_VID_DYNAMIC: dynamic volume + * @UBI_VID_STATIC: static volume + */ +enum { + UBI_VID_DYNAMIC = 1, + UBI_VID_STATIC = 2 +}; + +/* + * Volume flags used in the volume table record. + * + * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume + * + * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume + * table. UBI automatically re-sizes the volume which has this flag and makes + * the volume to be of largest possible size. This means that if after the + * initialization UBI finds out that there are available physical eraseblocks + * present on the device, it automatically appends all of them to the volume + * (the physical eraseblocks reserved for bad eraseblocks handling and other + * reserved physical eraseblocks are not taken). So, if there is a volume with + * the %UBI_VTBL_AUTORESIZE_FLG flag set, the amount of available logical + * eraseblocks will be zero after UBI is loaded, because all of them will be + * reserved for this volume. Note, the %UBI_VTBL_AUTORESIZE_FLG bit is cleared + * after the volume had been initialized. + * + * The auto-resize feature is useful for device production purposes. For + * example, different NAND flash chips may have different amount of initial bad + * eraseblocks, depending of particular chip instance. Manufacturers of NAND + * chips usually guarantee that the amount of initial bad eraseblocks does not + * exceed certain percent, e.g. 2%. When one creates an UBI image which will be + * flashed to the end devices in production, he does not know the exact amount + * of good physical eraseblocks the NAND chip on the device will have, but this + * number is required to calculate the volume sized and put them to the volume + * table of the UBI image. In this case, one of the volumes (e.g., the one + * which will store the root file system) is marked as "auto-resizable", and + * UBI will adjust its size on the first boot if needed. + * + * Note, first UBI reserves some amount of physical eraseblocks for bad + * eraseblock handling, and then re-sizes the volume, not vice-versa. This + * means that the pool of reserved physical eraseblocks will always be present. + */ +enum { + UBI_VTBL_AUTORESIZE_FLG = 0x01, +}; + +/* + * Compatibility constants used by internal volumes. + * + * @UBI_COMPAT_DELETE: delete this internal volume before anything is written + * to the flash + * @UBI_COMPAT_RO: attach this device in read-only mode + * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its + * physical eraseblocks, don't allow the wear-leveling unit to move them + * @UBI_COMPAT_REJECT: reject this UBI image + */ +enum { + UBI_COMPAT_DELETE = 1, + UBI_COMPAT_RO = 2, + UBI_COMPAT_PRESERVE = 4, + UBI_COMPAT_REJECT = 5 +}; + +/* Sizes of UBI headers */ +#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr) +#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) + +/* Sizes of UBI headers without the ending CRC */ +#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(__be32)) +#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(__be32)) + +/** + * struct ubi_ec_hdr - UBI erase counter header. + * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) + * @version: version of UBI implementation which is supposed to accept this + * UBI image + * @padding1: reserved for future, zeroes + * @ec: the erase counter + * @vid_hdr_offset: where the VID header starts + * @data_offset: where the user data start + * @padding2: reserved for future, zeroes + * @hdr_crc: erase counter header CRC checksum + * + * The erase counter header takes 64 bytes and has a plenty of unused space for + * future usage. The unused fields are zeroed. The @version field is used to + * indicate the version of UBI implementation which is supposed to be able to + * work with this UBI image. If @version is greater then the current UBI + * version, the image is rejected. This may be useful in future if something + * is changed radically. This field is duplicated in the volume identifier + * header. + * + * The @vid_hdr_offset and @data_offset fields contain the offset of the the + * volume identifier header and user data, relative to the beginning of the + * physical eraseblock. These values have to be the same for all physical + * eraseblocks. + */ +struct ubi_ec_hdr { + __be32 magic; + __u8 version; + __u8 padding1[3]; + __be64 ec; /* Warning: the current limit is 31-bit anyway! */ + __be32 vid_hdr_offset; + __be32 data_offset; + __u8 padding2[36]; + __be32 hdr_crc; +} __attribute__ ((packed)); + +/** + * struct ubi_vid_hdr - on-flash UBI volume identifier header. + * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) + * @version: UBI implementation version which is supposed to accept this UBI + * image (%UBI_VERSION) + * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) + * @copy_flag: if this logical eraseblock was copied from another physical + * eraseblock (for wear-leveling reasons) + * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, + * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) + * @vol_id: ID of this volume + * @lnum: logical eraseblock number + * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be + * removed, kept only for not breaking older UBI users) + * @data_size: how many bytes of data this logical eraseblock contains + * @used_ebs: total number of used logical eraseblocks in this volume + * @data_pad: how many bytes at the end of this physical eraseblock are not + * used + * @data_crc: CRC checksum of the data stored in this logical eraseblock + * @padding1: reserved for future, zeroes + * @sqnum: sequence number + * @padding2: reserved for future, zeroes + * @hdr_crc: volume identifier header CRC checksum + * + * The @sqnum is the value of the global sequence counter at the time when this + * VID header was created. The global sequence counter is incremented each time + * UBI writes a new VID header to the flash, i.e. when it maps a logical + * eraseblock to a new physical eraseblock. The global sequence counter is an + * unsigned 64-bit integer and we assume it never overflows. The @sqnum + * (sequence number) is used to distinguish between older and newer versions of + * logical eraseblocks. + * + * There are 2 situations when there may be more then one physical eraseblock + * corresponding to the same logical eraseblock, i.e., having the same @vol_id + * and @lnum values in the volume identifier header. Suppose we have a logical + * eraseblock L and it is mapped to the physical eraseblock P. + * + * 1. Because UBI may erase physical eraseblocks asynchronously, the following + * situation is possible: L is asynchronously erased, so P is scheduled for + * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, + * so P1 is written to, then an unclean reboot happens. Result - there are 2 + * physical eraseblocks P and P1 corresponding to the same logical eraseblock + * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the + * flash. + * + * 2. From time to time UBI moves logical eraseblocks to other physical + * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P + * to P1, and an unclean reboot happens before P is physically erased, there + * are two physical eraseblocks P and P1 corresponding to L and UBI has to + * select one of them when the flash is attached. The @sqnum field says which + * PEB is the original (obviously P will have lower @sqnum) and the copy. But + * it is not enough to select the physical eraseblock with the higher sequence + * number, because the unclean reboot could have happen in the middle of the + * copying process, so the data in P is corrupted. It is also not enough to + * just select the physical eraseblock with lower sequence number, because the + * data there may be old (consider a case if more data was added to P1 after + * the copying). Moreover, the unclean reboot may happen when the erasure of P + * was just started, so it result in unstable P, which is "mostly" OK, but + * still has unstable bits. + * + * UBI uses the @copy_flag field to indicate that this logical eraseblock is a + * copy. UBI also calculates data CRC when the data is moved and stores it at + * the @data_crc field of the copy (P1). So when UBI needs to pick one physical + * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is + * examined. If it is cleared, the situation* is simple and the newer one is + * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC + * checksum is correct, this physical eraseblock is selected (P1). Otherwise + * the older one (P) is selected. + * + * Note, there is an obsolete @leb_ver field which was used instead of @sqnum + * in the past. But it is not used anymore and we keep it in order to be able + * to deal with old UBI images. It will be removed at some point. + * + * There are 2 sorts of volumes in UBI: user volumes and internal volumes. + * Internal volumes are not seen from outside and are used for various internal + * UBI purposes. In this implementation there is only one internal volume - the + * layout volume. Internal volumes are the main mechanism of UBI extensions. + * For example, in future one may introduce a journal internal volume. Internal + * volumes have their own reserved range of IDs. + * + * The @compat field is only used for internal volumes and contains the "degree + * of their compatibility". It is always zero for user volumes. This field + * provides a mechanism to introduce UBI extensions and to be still compatible + * with older UBI binaries. For example, if someone introduced a journal in + * future, he would probably use %UBI_COMPAT_DELETE compatibility for the + * journal volume. And in this case, older UBI binaries, which know nothing + * about the journal volume, would just delete this volume and work perfectly + * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image + * - it just ignores the Ext3fs journal. + * + * The @data_crc field contains the CRC checksum of the contents of the logical + * eraseblock if this is a static volume. In case of dynamic volumes, it does + * not contain the CRC checksum as a rule. The only exception is when the + * data of the physical eraseblock was moved by the wear-leveling unit, then + * the wear-leveling unit calculates the data CRC and stores it in the + * @data_crc field. And of course, the @copy_flag is %in this case. + * + * The @data_size field is used only for static volumes because UBI has to know + * how many bytes of data are stored in this eraseblock. For dynamic volumes, + * this field usually contains zero. The only exception is when the data of the + * physical eraseblock was moved to another physical eraseblock for + * wear-leveling reasons. In this case, UBI calculates CRC checksum of the + * contents and uses both @data_crc and @data_size fields. In this case, the + * @data_size field contains data size. + * + * The @used_ebs field is used only for static volumes and indicates how many + * eraseblocks the data of the volume takes. For dynamic volumes this field is + * not used and always contains zero. + * + * The @data_pad is calculated when volumes are created using the alignment + * parameter. So, effectively, the @data_pad field reduces the size of logical + * eraseblocks of this volume. This is very handy when one uses block-oriented + * software (say, cramfs) on top of the UBI volume. + */ +struct ubi_vid_hdr { + __be32 magic; + __u8 version; + __u8 vol_type; + __u8 copy_flag; + __u8 compat; + __be32 vol_id; + __be32 lnum; + __be32 leb_ver; /* obsolete, to be removed, don't use */ + __be32 data_size; + __be32 used_ebs; + __be32 data_pad; + __be32 data_crc; + __u8 padding1[4]; + __be64 sqnum; + __u8 padding2[12]; + __be32 hdr_crc; +} __attribute__ ((packed)); + +/* Internal UBI volumes count */ +#define UBI_INT_VOL_COUNT 1 + +/* + * Starting ID of internal volumes. There is reserved room for 4096 internal + * volumes. + */ +#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) + +/* The layout volume contains the volume table */ + +#define UBI_LAYOUT_VOLUME_ID UBI_INTERNAL_VOL_START +#define UBI_LAYOUT_VOLUME_TYPE UBI_VID_DYNAMIC +#define UBI_LAYOUT_VOLUME_ALIGN 1 +#define UBI_LAYOUT_VOLUME_EBS 2 +#define UBI_LAYOUT_VOLUME_NAME "layout volume" +#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT + +/* The maximum number of volumes per one UBI device */ +#define UBI_MAX_VOLUMES 128 + +/* The maximum volume name length */ +#define UBI_VOL_NAME_MAX 127 + +/* Size of the volume table record */ +#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) + +/* Size of the volume table record without the ending CRC */ +#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(__be32)) + +/** + * struct ubi_vtbl_record - a record in the volume table. + * @reserved_pebs: how many physical eraseblocks are reserved for this volume + * @alignment: volume alignment + * @data_pad: how many bytes are unused at the end of the each physical + * eraseblock to satisfy the requested alignment + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @upd_marker: if volume update was started but not finished + * @name_len: volume name length + * @name: the volume name + * @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG) + * @padding: reserved, zeroes + * @crc: a CRC32 checksum of the record + * + * The volume table records are stored in the volume table, which is stored in + * the layout volume. The layout volume consists of 2 logical eraseblock, each + * of which contains a copy of the volume table (i.e., the volume table is + * duplicated). The volume table is an array of &struct ubi_vtbl_record + * objects indexed by the volume ID. + * + * If the size of the logical eraseblock is large enough to fit + * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES + * records. Otherwise, it contains as many records as it can fit (i.e., size of + * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). + * + * The @upd_marker flag is used to implement volume update. It is set to %1 + * before update and set to %0 after the update. So if the update operation was + * interrupted, UBI knows that the volume is corrupted. + * + * The @alignment field is specified when the volume is created and cannot be + * later changed. It may be useful, for example, when a block-oriented file + * system works on top of UBI. The @data_pad field is calculated using the + * logical eraseblock size and @alignment. The alignment must be multiple to the + * minimal flash I/O unit. If @alignment is 1, all the available space of + * the physical eraseblocks is used. + * + * Empty records contain all zeroes and the CRC checksum of those zeroes. + */ +struct ubi_vtbl_record { + __be32 reserved_pebs; + __be32 alignment; + __be32 data_pad; + __u8 vol_type; + __u8 upd_marker; + __be16 name_len; + __u8 name[UBI_VOL_NAME_MAX+1]; + __u8 flags; + __u8 padding[23]; + __be32 crc; +} __attribute__ ((packed)); + +#endif /* !__UBI_MEDIA_H__ */ diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h new file mode 100644 index 0000000..bf77a15 --- /dev/null +++ b/drivers/mtd/ubi/ubi.h @@ -0,0 +1,641 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (c) Nokia Corporation, 2006, 2007 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __UBI_UBI_H__ +#define __UBI_UBI_H__ + +#ifdef UBI_LINUX +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "ubi-media.h" +#include "scan.h" +#include "debug.h" + +/* Maximum number of supported UBI devices */ +#define UBI_MAX_DEVICES 32 + +/* UBI name used for character devices, sysfs, etc */ +#define UBI_NAME_STR "ubi" + +/* Normal UBI messages */ +#define ubi_msg(fmt, ...) printk(KERN_NOTICE "UBI: " fmt "\n", ##__VA_ARGS__) +/* UBI warning messages */ +#define ubi_warn(fmt, ...) printk(KERN_WARNING "UBI warning: %s: " fmt "\n", \ + __func__, ##__VA_ARGS__) +/* UBI error messages */ +#define ubi_err(fmt, ...) printk(KERN_ERR "UBI error: %s: " fmt "\n", \ + __func__, ##__VA_ARGS__) + +/* Lowest number PEBs reserved for bad PEB handling */ +#define MIN_RESEVED_PEBS 2 + +/* Background thread name pattern */ +#define UBI_BGT_NAME_PATTERN "ubi_bgt%dd" + +/* This marker in the EBA table means that the LEB is um-mapped */ +#define UBI_LEB_UNMAPPED -1 + +/* + * In case of errors, UBI tries to repeat the operation several times before + * returning error. The below constant defines how many times UBI re-tries. + */ +#define UBI_IO_RETRIES 3 + +/* + * Error codes returned by the I/O unit. + * + * UBI_IO_PEB_EMPTY: the physical eraseblock is empty, i.e. it contains only + * 0xFF bytes + * UBI_IO_PEB_FREE: the physical eraseblock is free, i.e. it contains only a + * valid erase counter header, and the rest are %0xFF bytes + * UBI_IO_BAD_EC_HDR: the erase counter header is corrupted (bad magic or CRC) + * UBI_IO_BAD_VID_HDR: the volume identifier header is corrupted (bad magic or + * CRC) + * UBI_IO_BITFLIPS: bit-flips were detected and corrected + */ +enum { + UBI_IO_PEB_EMPTY = 1, + UBI_IO_PEB_FREE, + UBI_IO_BAD_EC_HDR, + UBI_IO_BAD_VID_HDR, + UBI_IO_BITFLIPS +}; + +/** + * struct ubi_wl_entry - wear-leveling entry. + * @rb: link in the corresponding RB-tree + * @ec: erase counter + * @pnum: physical eraseblock number + * + * This data structure is used in the WL unit. Each physical eraseblock has a + * corresponding &struct wl_entry object which may be kept in different + * RB-trees. See WL unit for details. + */ +struct ubi_wl_entry { + struct rb_node rb; + int ec; + int pnum; +}; + +/** + * struct ubi_ltree_entry - an entry in the lock tree. + * @rb: links RB-tree nodes + * @vol_id: volume ID of the locked logical eraseblock + * @lnum: locked logical eraseblock number + * @users: how many tasks are using this logical eraseblock or wait for it + * @mutex: read/write mutex to implement read/write access serialization to + * the (@vol_id, @lnum) logical eraseblock + * + * This data structure is used in the EBA unit to implement per-LEB locking. + * When a logical eraseblock is being locked - corresponding + * &struct ubi_ltree_entry object is inserted to the lock tree (@ubi->ltree). + * See EBA unit for details. + */ +struct ubi_ltree_entry { + struct rb_node rb; + int vol_id; + int lnum; + int users; + struct rw_semaphore mutex; +}; + +struct ubi_volume_desc; + +/** + * struct ubi_volume - UBI volume description data structure. + * @dev: device object to make use of the the Linux device model + * @cdev: character device object to create character device + * @ubi: reference to the UBI device description object + * @vol_id: volume ID + * @ref_count: volume reference count + * @readers: number of users holding this volume in read-only mode + * @writers: number of users holding this volume in read-write mode + * @exclusive: whether somebody holds this volume in exclusive mode + * + * @reserved_pebs: how many physical eraseblocks are reserved for this volume + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @usable_leb_size: logical eraseblock size without padding + * @used_ebs: how many logical eraseblocks in this volume contain data + * @last_eb_bytes: how many bytes are stored in the last logical eraseblock + * @used_bytes: how many bytes of data this volume contains + * @alignment: volume alignment + * @data_pad: how many bytes are not used at the end of physical eraseblocks to + * satisfy the requested alignment + * @name_len: volume name length + * @name: volume name + * + * @upd_ebs: how many eraseblocks are expected to be updated + * @ch_lnum: LEB number which is being changing by the atomic LEB change + * operation + * @ch_dtype: data persistency type which is being changing by the atomic LEB + * change operation + * @upd_bytes: how many bytes are expected to be received for volume update or + * atomic LEB change + * @upd_received: how many bytes were already received for volume update or + * atomic LEB change + * @upd_buf: update buffer which is used to collect update data or data for + * atomic LEB change + * + * @eba_tbl: EBA table of this volume (LEB->PEB mapping) + * @checked: %1 if this static volume was checked + * @corrupted: %1 if the volume is corrupted (static volumes only) + * @upd_marker: %1 if the update marker is set for this volume + * @updating: %1 if the volume is being updated + * @changing_leb: %1 if the atomic LEB change ioctl command is in progress + * + * @gluebi_desc: gluebi UBI volume descriptor + * @gluebi_refcount: reference count of the gluebi MTD device + * @gluebi_mtd: MTD device description object of the gluebi MTD device + * + * The @corrupted field indicates that the volume's contents is corrupted. + * Since UBI protects only static volumes, this field is not relevant to + * dynamic volumes - it is user's responsibility to assure their data + * integrity. + * + * The @upd_marker flag indicates that this volume is either being updated at + * the moment or is damaged because of an unclean reboot. + */ +struct ubi_volume { + struct device dev; + struct cdev cdev; + struct ubi_device *ubi; + int vol_id; + int ref_count; + int readers; + int writers; + int exclusive; + + int reserved_pebs; + int vol_type; + int usable_leb_size; + int used_ebs; + int last_eb_bytes; + long long used_bytes; + int alignment; + int data_pad; + int name_len; + char name[UBI_VOL_NAME_MAX+1]; + + int upd_ebs; + int ch_lnum; + int ch_dtype; + long long upd_bytes; + long long upd_received; + void *upd_buf; + + int *eba_tbl; + unsigned int checked:1; + unsigned int corrupted:1; + unsigned int upd_marker:1; + unsigned int updating:1; + unsigned int changing_leb:1; + +#ifdef CONFIG_MTD_UBI_GLUEBI + /* + * Gluebi-related stuff may be compiled out. + * TODO: this should not be built into UBI but should be a separate + * ubimtd driver which works on top of UBI and emulates MTD devices. + */ + struct ubi_volume_desc *gluebi_desc; + int gluebi_refcount; + struct mtd_info gluebi_mtd; +#endif +}; + +/** + * struct ubi_volume_desc - descriptor of the UBI volume returned when it is + * opened. + * @vol: reference to the corresponding volume description object + * @mode: open mode (%UBI_READONLY, %UBI_READWRITE, or %UBI_EXCLUSIVE) + */ +struct ubi_volume_desc { + struct ubi_volume *vol; + int mode; +}; + +struct ubi_wl_entry; + +/** + * struct ubi_device - UBI device description structure + * @dev: UBI device object to use the the Linux device model + * @cdev: character device object to create character device + * @ubi_num: UBI device number + * @ubi_name: UBI device name + * @vol_count: number of volumes in this UBI device + * @volumes: volumes of this UBI device + * @volumes_lock: protects @volumes, @rsvd_pebs, @avail_pebs, beb_rsvd_pebs, + * @beb_rsvd_level, @bad_peb_count, @good_peb_count, @vol_count, + * @vol->readers, @vol->writers, @vol->exclusive, + * @vol->ref_count, @vol->mapping and @vol->eba_tbl. + * @ref_count: count of references on the UBI device + * + * @rsvd_pebs: count of reserved physical eraseblocks + * @avail_pebs: count of available physical eraseblocks + * @beb_rsvd_pebs: how many physical eraseblocks are reserved for bad PEB + * handling + * @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling + * + * @autoresize_vol_id: ID of the volume which has to be auto-resized at the end + * of UBI ititializetion + * @vtbl_slots: how many slots are available in the volume table + * @vtbl_size: size of the volume table in bytes + * @vtbl: in-RAM volume table copy + * @volumes_mutex: protects on-flash volume table and serializes volume + * changes, like creation, deletion, update, resize + * + * @max_ec: current highest erase counter value + * @mean_ec: current mean erase counter value + * + * @global_sqnum: global sequence number + * @ltree_lock: protects the lock tree and @global_sqnum + * @ltree: the lock tree + * @alc_mutex: serializes "atomic LEB change" operations + * + * @used: RB-tree of used physical eraseblocks + * @free: RB-tree of free physical eraseblocks + * @scrub: RB-tree of physical eraseblocks which need scrubbing + * @prot: protection trees + * @prot.pnum: protection tree indexed by physical eraseblock numbers + * @prot.aec: protection tree indexed by absolute erase counter value + * @wl_lock: protects the @used, @free, @prot, @lookuptbl, @abs_ec, @move_from, + * @move_to, @move_to_put @erase_pending, @wl_scheduled, and @works + * fields + * @move_mutex: serializes eraseblock moves + * @wl_scheduled: non-zero if the wear-leveling was scheduled + * @lookuptbl: a table to quickly find a &struct ubi_wl_entry object for any + * physical eraseblock + * @abs_ec: absolute erase counter + * @move_from: physical eraseblock from where the data is being moved + * @move_to: physical eraseblock where the data is being moved to + * @move_to_put: if the "to" PEB was put + * @works: list of pending works + * @works_count: count of pending works + * @bgt_thread: background thread description object + * @thread_enabled: if the background thread is enabled + * @bgt_name: background thread name + * + * @flash_size: underlying MTD device size (in bytes) + * @peb_count: count of physical eraseblocks on the MTD device + * @peb_size: physical eraseblock size + * @bad_peb_count: count of bad physical eraseblocks + * @good_peb_count: count of good physical eraseblocks + * @min_io_size: minimal input/output unit size of the underlying MTD device + * @hdrs_min_io_size: minimal I/O unit size used for VID and EC headers + * @ro_mode: if the UBI device is in read-only mode + * @leb_size: logical eraseblock size + * @leb_start: starting offset of logical eraseblocks within physical + * eraseblocks + * @ec_hdr_alsize: size of the EC header aligned to @hdrs_min_io_size + * @vid_hdr_alsize: size of the VID header aligned to @hdrs_min_io_size + * @vid_hdr_offset: starting offset of the volume identifier header (might be + * unaligned) + * @vid_hdr_aloffset: starting offset of the VID header aligned to + * @hdrs_min_io_size + * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset + * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or + * not + * @mtd: MTD device descriptor + * + * @peb_buf1: a buffer of PEB size used for different purposes + * @peb_buf2: another buffer of PEB size used for different purposes + * @buf_mutex: proptects @peb_buf1 and @peb_buf2 + * @dbg_peb_buf: buffer of PEB size used for debugging + * @dbg_buf_mutex: proptects @dbg_peb_buf + */ +struct ubi_device { + struct cdev cdev; + struct device dev; + int ubi_num; + char ubi_name[sizeof(UBI_NAME_STR)+5]; + int vol_count; + struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; + spinlock_t volumes_lock; + int ref_count; + + int rsvd_pebs; + int avail_pebs; + int beb_rsvd_pebs; + int beb_rsvd_level; + + int autoresize_vol_id; + int vtbl_slots; + int vtbl_size; + struct ubi_vtbl_record *vtbl; + struct mutex volumes_mutex; + + int max_ec; + /* TODO: mean_ec is not updated run-time, fix */ + int mean_ec; + + /* EBA unit's stuff */ + unsigned long long global_sqnum; + spinlock_t ltree_lock; + struct rb_root ltree; + struct mutex alc_mutex; + + /* Wear-leveling unit's stuff */ + struct rb_root used; + struct rb_root free; + struct rb_root scrub; + struct { + struct rb_root pnum; + struct rb_root aec; + } prot; + spinlock_t wl_lock; + struct mutex move_mutex; + struct rw_semaphore work_sem; + int wl_scheduled; + struct ubi_wl_entry **lookuptbl; + unsigned long long abs_ec; + struct ubi_wl_entry *move_from; + struct ubi_wl_entry *move_to; + int move_to_put; + struct list_head works; + int works_count; + struct task_struct *bgt_thread; + int thread_enabled; + char bgt_name[sizeof(UBI_BGT_NAME_PATTERN)+2]; + + /* I/O unit's stuff */ + long long flash_size; + int peb_count; + int peb_size; + int bad_peb_count; + int good_peb_count; + int min_io_size; + int hdrs_min_io_size; + int ro_mode; + int leb_size; + int leb_start; + int ec_hdr_alsize; + int vid_hdr_alsize; + int vid_hdr_offset; + int vid_hdr_aloffset; + int vid_hdr_shift; + int bad_allowed; + struct mtd_info *mtd; + + void *peb_buf1; + void *peb_buf2; + struct mutex buf_mutex; + struct mutex ckvol_mutex; +#ifdef CONFIG_MTD_UBI_DEBUG + void *dbg_peb_buf; + struct mutex dbg_buf_mutex; +#endif +}; + +extern struct kmem_cache *ubi_wl_entry_slab; +extern struct file_operations ubi_ctrl_cdev_operations; +extern struct file_operations ubi_cdev_operations; +extern struct file_operations ubi_vol_cdev_operations; +extern struct class *ubi_class; +extern struct mutex ubi_devices_mutex; + +/* vtbl.c */ +int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, + struct ubi_vtbl_record *vtbl_rec); +int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si); + +/* vmt.c */ +int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req); +int ubi_remove_volume(struct ubi_volume_desc *desc); +int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs); +int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol); +void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol); + +/* upd.c */ +int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, + long long bytes); +int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, + const void __user *buf, int count); +int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, + const struct ubi_leb_change_req *req); +int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, + const void __user *buf, int count); + +/* misc.c */ +int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, int length); +int ubi_check_volume(struct ubi_device *ubi, int vol_id); +void ubi_calculate_reserved(struct ubi_device *ubi); + +/* gluebi.c */ +#ifdef CONFIG_MTD_UBI_GLUEBI +int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol); +int ubi_destroy_gluebi(struct ubi_volume *vol); +void ubi_gluebi_updated(struct ubi_volume *vol); +#else +#define ubi_create_gluebi(ubi, vol) 0 +#define ubi_destroy_gluebi(vol) 0 +#define ubi_gluebi_updated(vol) +#endif + +/* eba.c */ +int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol, + int lnum); +int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + void *buf, int offset, int len, int check); +int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + const void *buf, int offset, int len, int dtype); +int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, + int lnum, const void *buf, int len, int dtype, + int used_ebs); +int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, + int lnum, const void *buf, int len, int dtype); +int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, + struct ubi_vid_hdr *vid_hdr); +int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); +void ubi_eba_close(const struct ubi_device *ubi); + +/* wl.c */ +int ubi_wl_get_peb(struct ubi_device *ubi, int dtype); +int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture); +int ubi_wl_flush(struct ubi_device *ubi); +int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); +int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); +void ubi_wl_close(struct ubi_device *ubi); +int ubi_thread(void *u); + +/* io.c */ +int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, + int len); +int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, + int len); +int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture); +int ubi_io_is_bad(const struct ubi_device *ubi, int pnum); +int ubi_io_mark_bad(const struct ubi_device *ubi, int pnum); +int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, + struct ubi_ec_hdr *ec_hdr, int verbose); +int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, + struct ubi_ec_hdr *ec_hdr); +int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, + struct ubi_vid_hdr *vid_hdr, int verbose); +int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, + struct ubi_vid_hdr *vid_hdr); + +/* build.c */ +int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset); +int ubi_detach_mtd_dev(int ubi_num, int anyway); +struct ubi_device *ubi_get_device(int ubi_num); +void ubi_put_device(struct ubi_device *ubi); +struct ubi_device *ubi_get_by_major(int major); +int ubi_major2num(int major); + +/* + * ubi_rb_for_each_entry - walk an RB-tree. + * @rb: a pointer to type 'struct rb_node' to to use as a loop counter + * @pos: a pointer to RB-tree entry type to use as a loop counter + * @root: RB-tree's root + * @member: the name of the 'struct rb_node' within the RB-tree entry + */ +#define ubi_rb_for_each_entry(rb, pos, root, member) \ + for (rb = rb_first(root), \ + pos = (rb ? container_of(rb, typeof(*pos), member) : NULL); \ + rb; \ + rb = rb_next(rb), pos = container_of(rb, typeof(*pos), member)) + +/** + * ubi_zalloc_vid_hdr - allocate a volume identifier header object. + * @ubi: UBI device description object + * @gfp_flags: GFP flags to allocate with + * + * This function returns a pointer to the newly allocated and zero-filled + * volume identifier header object in case of success and %NULL in case of + * failure. + */ +static inline struct ubi_vid_hdr * +ubi_zalloc_vid_hdr(const struct ubi_device *ubi, gfp_t gfp_flags) +{ + void *vid_hdr; + + vid_hdr = kzalloc(ubi->vid_hdr_alsize, gfp_flags); + if (!vid_hdr) + return NULL; + + /* + * VID headers may be stored at un-aligned flash offsets, so we shift + * the pointer. + */ + return vid_hdr + ubi->vid_hdr_shift; +} + +/** + * ubi_free_vid_hdr - free a volume identifier header object. + * @ubi: UBI device description object + * @vid_hdr: the object to free + */ +static inline void ubi_free_vid_hdr(const struct ubi_device *ubi, + struct ubi_vid_hdr *vid_hdr) +{ + void *p = vid_hdr; + + if (!p) + return; + + kfree(p - ubi->vid_hdr_shift); +} + +/* + * This function is equivalent to 'ubi_io_read()', but @offset is relative to + * the beginning of the logical eraseblock, not to the beginning of the + * physical eraseblock. + */ +static inline int ubi_io_read_data(const struct ubi_device *ubi, void *buf, + int pnum, int offset, int len) +{ + ubi_assert(offset >= 0); + return ubi_io_read(ubi, buf, pnum, offset + ubi->leb_start, len); +} + +/* + * This function is equivalent to 'ubi_io_write()', but @offset is relative to + * the beginning of the logical eraseblock, not to the beginning of the + * physical eraseblock. + */ +static inline int ubi_io_write_data(struct ubi_device *ubi, const void *buf, + int pnum, int offset, int len) +{ + ubi_assert(offset >= 0); + return ubi_io_write(ubi, buf, pnum, offset + ubi->leb_start, len); +} + +/** + * ubi_ro_mode - switch to read-only mode. + * @ubi: UBI device description object + */ +static inline void ubi_ro_mode(struct ubi_device *ubi) +{ + if (!ubi->ro_mode) { + ubi->ro_mode = 1; + ubi_warn("switch to read-only mode"); + } +} + +/** + * vol_id2idx - get table index by volume ID. + * @ubi: UBI device description object + * @vol_id: volume ID + */ +static inline int vol_id2idx(const struct ubi_device *ubi, int vol_id) +{ + if (vol_id >= UBI_INTERNAL_VOL_START) + return vol_id - UBI_INTERNAL_VOL_START + ubi->vtbl_slots; + else + return vol_id; +} + +/** + * idx2vol_id - get volume ID by table index. + * @ubi: UBI device description object + * @idx: table index + */ +static inline int idx2vol_id(const struct ubi_device *ubi, int idx) +{ + if (idx >= ubi->vtbl_slots) + return idx - ubi->vtbl_slots + UBI_INTERNAL_VOL_START; + else + return idx; +} + +#endif /* !__UBI_UBI_H__ */ -- cgit v1.1 From c91a719daa331b5856109313371e4ece5ec06d96 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:28:06 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 5/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- drivers/mtd/ubi/upd.c | 441 +++++++++++++ drivers/mtd/ubi/vmt.c | 862 +++++++++++++++++++++++++ drivers/mtd/ubi/vtbl.c | 837 ++++++++++++++++++++++++ drivers/mtd/ubi/wl.c | 1670 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 3810 insertions(+) create mode 100644 drivers/mtd/ubi/upd.c create mode 100644 drivers/mtd/ubi/vmt.c create mode 100644 drivers/mtd/ubi/vtbl.c create mode 100644 drivers/mtd/ubi/wl.c diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c new file mode 100644 index 0000000..5f7ed7b --- /dev/null +++ b/drivers/mtd/ubi/upd.c @@ -0,0 +1,441 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (c) Nokia Corporation, 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + * + * Jan 2007: Alexander Schmidt, hacked per-volume update. + */ + +/* + * This file contains implementation of the volume update and atomic LEB change + * functionality. + * + * The update operation is based on the per-volume update marker which is + * stored in the volume table. The update marker is set before the update + * starts, and removed after the update has been finished. So if the update was + * interrupted by an unclean re-boot or due to some other reasons, the update + * marker stays on the flash media and UBI finds it when it attaches the MTD + * device next time. If the update marker is set for a volume, the volume is + * treated as damaged and most I/O operations are prohibited. Only a new update + * operation is allowed. + * + * Note, in general it is possible to implement the update operation as a + * transaction with a roll-back capability. + */ + +#ifdef UBI_LINUX +#include +#include +#include +#endif + +#include +#include "ubi.h" + +/** + * set_update_marker - set update marker. + * @ubi: UBI device description object + * @vol: volume description object + * + * This function sets the update marker flag for volume @vol. Returns zero + * in case of success and a negative error code in case of failure. + */ +static int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol) +{ + int err; + struct ubi_vtbl_record vtbl_rec; + + dbg_msg("set update marker for volume %d", vol->vol_id); + + if (vol->upd_marker) { + ubi_assert(ubi->vtbl[vol->vol_id].upd_marker); + dbg_msg("already set"); + return 0; + } + + memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], + sizeof(struct ubi_vtbl_record)); + vtbl_rec.upd_marker = 1; + + mutex_lock(&ubi->volumes_mutex); + err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec); + mutex_unlock(&ubi->volumes_mutex); + vol->upd_marker = 1; + return err; +} + +/** + * clear_update_marker - clear update marker. + * @ubi: UBI device description object + * @vol: volume description object + * @bytes: new data size in bytes + * + * This function clears the update marker for volume @vol, sets new volume + * data size and clears the "corrupted" flag (static volumes only). Returns + * zero in case of success and a negative error code in case of failure. + */ +static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, + long long bytes) +{ + int err; + uint64_t tmp; + struct ubi_vtbl_record vtbl_rec; + + dbg_msg("clear update marker for volume %d", vol->vol_id); + + memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], + sizeof(struct ubi_vtbl_record)); + ubi_assert(vol->upd_marker && vtbl_rec.upd_marker); + vtbl_rec.upd_marker = 0; + + if (vol->vol_type == UBI_STATIC_VOLUME) { + vol->corrupted = 0; + vol->used_bytes = tmp = bytes; + vol->last_eb_bytes = do_div(tmp, vol->usable_leb_size); + vol->used_ebs = tmp; + if (vol->last_eb_bytes) + vol->used_ebs += 1; + else + vol->last_eb_bytes = vol->usable_leb_size; + } + + mutex_lock(&ubi->volumes_mutex); + err = ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec); + mutex_unlock(&ubi->volumes_mutex); + vol->upd_marker = 0; + return err; +} + +/** + * ubi_start_update - start volume update. + * @ubi: UBI device description object + * @vol: volume description object + * @bytes: update bytes + * + * This function starts volume update operation. If @bytes is zero, the volume + * is just wiped out. Returns zero in case of success and a negative error code + * in case of failure. + */ +int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, + long long bytes) +{ + int i, err; + uint64_t tmp; + + dbg_msg("start update of volume %d, %llu bytes", vol->vol_id, bytes); + ubi_assert(!vol->updating && !vol->changing_leb); + vol->updating = 1; + + err = set_update_marker(ubi, vol); + if (err) + return err; + + /* Before updating - wipe out the volume */ + for (i = 0; i < vol->reserved_pebs; i++) { + err = ubi_eba_unmap_leb(ubi, vol, i); + if (err) + return err; + } + + if (bytes == 0) { + err = clear_update_marker(ubi, vol, 0); + if (err) + return err; + err = ubi_wl_flush(ubi); + if (!err) + vol->updating = 0; + } + + vol->upd_buf = vmalloc(ubi->leb_size); + if (!vol->upd_buf) + return -ENOMEM; + + tmp = bytes; + vol->upd_ebs = !!do_div(tmp, vol->usable_leb_size); + vol->upd_ebs += tmp; + vol->upd_bytes = bytes; + vol->upd_received = 0; + return 0; +} + +/** + * ubi_start_leb_change - start atomic LEB change. + * @ubi: UBI device description object + * @vol: volume description object + * @req: operation request + * + * This function starts atomic LEB change operation. Returns zero in case of + * success and a negative error code in case of failure. + */ +int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol, + const struct ubi_leb_change_req *req) +{ + ubi_assert(!vol->updating && !vol->changing_leb); + + dbg_msg("start changing LEB %d:%d, %u bytes", + vol->vol_id, req->lnum, req->bytes); + if (req->bytes == 0) + return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0, + req->dtype); + + vol->upd_bytes = req->bytes; + vol->upd_received = 0; + vol->changing_leb = 1; + vol->ch_lnum = req->lnum; + vol->ch_dtype = req->dtype; + + vol->upd_buf = vmalloc(req->bytes); + if (!vol->upd_buf) + return -ENOMEM; + + return 0; +} + +/** + * write_leb - write update data. + * @ubi: UBI device description object + * @vol: volume description object + * @lnum: logical eraseblock number + * @buf: data to write + * @len: data size + * @used_ebs: how many logical eraseblocks will this volume contain (static + * volumes only) + * + * This function writes update data to corresponding logical eraseblock. In + * case of dynamic volume, this function checks if the data contains 0xFF bytes + * at the end. If yes, the 0xFF bytes are cut and not written. So if the whole + * buffer contains only 0xFF bytes, the LEB is left unmapped. + * + * The reason why we skip the trailing 0xFF bytes in case of dynamic volume is + * that we want to make sure that more data may be appended to the logical + * eraseblock in future. Indeed, writing 0xFF bytes may have side effects and + * this PEB won't be writable anymore. So if one writes the file-system image + * to the UBI volume where 0xFFs mean free space - UBI makes sure this free + * space is writable after the update. + * + * We do not do this for static volumes because they are read-only. But this + * also cannot be done because we have to store per-LEB CRC and the correct + * data length. + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + void *buf, int len, int used_ebs) +{ + int err; + + if (vol->vol_type == UBI_DYNAMIC_VOLUME) { + int l = ALIGN(len, ubi->min_io_size); + + memset(buf + len, 0xFF, l - len); + len = ubi_calc_data_len(ubi, buf, l); + if (len == 0) { + dbg_msg("all %d bytes contain 0xFF - skip", len); + return 0; + } + + err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len, UBI_UNKNOWN); + } else { + /* + * When writing static volume, and this is the last logical + * eraseblock, the length (@len) does not have to be aligned to + * the minimal flash I/O unit. The 'ubi_eba_write_leb_st()' + * function accepts exact (unaligned) length and stores it in + * the VID header. And it takes care of proper alignment by + * padding the buffer. Here we just make sure the padding will + * contain zeros, not random trash. + */ + memset(buf + len, 0, vol->usable_leb_size - len); + err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, + UBI_UNKNOWN, used_ebs); + } + + return err; +} + +/** + * ubi_more_update_data - write more update data. + * @vol: volume description object + * @buf: write data (user-space memory buffer) + * @count: how much bytes to write + * + * This function writes more data to the volume which is being updated. It may + * be called arbitrary number of times until all the update data arriveis. This + * function returns %0 in case of success, number of bytes written during the + * last call if the whole volume update has been successfully finished, and a + * negative error code in case of failure. + */ +int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, + const void __user *buf, int count) +{ + uint64_t tmp; + int lnum, offs, err = 0, len, to_write = count; + + dbg_msg("write %d of %lld bytes, %lld already passed", + count, vol->upd_bytes, vol->upd_received); + + if (ubi->ro_mode) + return -EROFS; + + tmp = vol->upd_received; + offs = do_div(tmp, vol->usable_leb_size); + lnum = tmp; + + if (vol->upd_received + count > vol->upd_bytes) + to_write = count = vol->upd_bytes - vol->upd_received; + + /* + * When updating volumes, we accumulate whole logical eraseblock of + * data and write it at once. + */ + if (offs != 0) { + /* + * This is a write to the middle of the logical eraseblock. We + * copy the data to our update buffer and wait for more data or + * flush it if the whole eraseblock is written or the update + * is finished. + */ + + len = vol->usable_leb_size - offs; + if (len > count) + len = count; + + err = copy_from_user(vol->upd_buf + offs, buf, len); + if (err) + return -EFAULT; + + if (offs + len == vol->usable_leb_size || + vol->upd_received + len == vol->upd_bytes) { + int flush_len = offs + len; + + /* + * OK, we gathered either the whole eraseblock or this + * is the last chunk, it's time to flush the buffer. + */ + ubi_assert(flush_len <= vol->usable_leb_size); + err = write_leb(ubi, vol, lnum, vol->upd_buf, flush_len, + vol->upd_ebs); + if (err) + return err; + } + + vol->upd_received += len; + count -= len; + buf += len; + lnum += 1; + } + + /* + * If we've got more to write, let's continue. At this point we know we + * are starting from the beginning of an eraseblock. + */ + while (count) { + if (count > vol->usable_leb_size) + len = vol->usable_leb_size; + else + len = count; + + err = copy_from_user(vol->upd_buf, buf, len); + if (err) + return -EFAULT; + + if (len == vol->usable_leb_size || + vol->upd_received + len == vol->upd_bytes) { + err = write_leb(ubi, vol, lnum, vol->upd_buf, + len, vol->upd_ebs); + if (err) + break; + } + + vol->upd_received += len; + count -= len; + lnum += 1; + buf += len; + } + + ubi_assert(vol->upd_received <= vol->upd_bytes); + if (vol->upd_received == vol->upd_bytes) { + /* The update is finished, clear the update marker */ + err = clear_update_marker(ubi, vol, vol->upd_bytes); + if (err) + return err; + err = ubi_wl_flush(ubi); + if (err == 0) { + vol->updating = 0; + err = to_write; + vfree(vol->upd_buf); + } + } + + return err; +} + +/** + * ubi_more_leb_change_data - accept more data for atomic LEB change. + * @vol: volume description object + * @buf: write data (user-space memory buffer) + * @count: how much bytes to write + * + * This function accepts more data to the volume which is being under the + * "atomic LEB change" operation. It may be called arbitrary number of times + * until all data arrives. This function returns %0 in case of success, number + * of bytes written during the last call if the whole "atomic LEB change" + * operation has been successfully finished, and a negative error code in case + * of failure. + */ +int ubi_more_leb_change_data(struct ubi_device *ubi, struct ubi_volume *vol, + const void __user *buf, int count) +{ + int err; + + dbg_msg("write %d of %lld bytes, %lld already passed", + count, vol->upd_bytes, vol->upd_received); + + if (ubi->ro_mode) + return -EROFS; + + if (vol->upd_received + count > vol->upd_bytes) + count = vol->upd_bytes - vol->upd_received; + + err = copy_from_user(vol->upd_buf + vol->upd_received, buf, count); + if (err) + return -EFAULT; + + vol->upd_received += count; + + if (vol->upd_received == vol->upd_bytes) { + int len = ALIGN((int)vol->upd_bytes, ubi->min_io_size); + + memset(vol->upd_buf + vol->upd_bytes, 0xFF, len - vol->upd_bytes); + len = ubi_calc_data_len(ubi, vol->upd_buf, len); + err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum, + vol->upd_buf, len, UBI_UNKNOWN); + if (err) + return err; + } + + ubi_assert(vol->upd_received <= vol->upd_bytes); + if (vol->upd_received == vol->upd_bytes) { + vol->changing_leb = 0; + err = count; + vfree(vol->upd_buf); + } + + return err; +} diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c new file mode 100644 index 0000000..a87a2f3 --- /dev/null +++ b/drivers/mtd/ubi/vmt.c @@ -0,0 +1,862 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file contains implementation of volume creation, deletion, updating and + * resizing. + */ + +#ifdef UBI_LINUX +#include +#include +#endif + +#include +#include "ubi.h" + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +static void paranoid_check_volumes(struct ubi_device *ubi); +#else +#define paranoid_check_volumes(ubi) +#endif + +#ifdef UBI_LINUX +static ssize_t vol_attribute_show(struct device *dev, + struct device_attribute *attr, char *buf); + +/* Device attributes corresponding to files in '//class/ubi/ubiX_Y' */ +static struct device_attribute attr_vol_reserved_ebs = + __ATTR(reserved_ebs, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_type = + __ATTR(type, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_name = + __ATTR(name, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_corrupted = + __ATTR(corrupted, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_alignment = + __ATTR(alignment, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_usable_eb_size = + __ATTR(usable_eb_size, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_data_bytes = + __ATTR(data_bytes, S_IRUGO, vol_attribute_show, NULL); +static struct device_attribute attr_vol_upd_marker = + __ATTR(upd_marker, S_IRUGO, vol_attribute_show, NULL); + +/* + * "Show" method for files in '//class/ubi/ubiX_Y/'. + * + * Consider a situation: + * A. process 1 opens a sysfs file related to volume Y, say + * //class/ubi/ubiX_Y/reserved_ebs; + * B. process 2 removes volume Y; + * C. process 1 starts reading the //class/ubi/ubiX_Y/reserved_ebs file; + * + * In this situation, this function will return %-ENODEV because it will find + * out that the volume was removed from the @ubi->volumes array. + */ +static ssize_t vol_attribute_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); + struct ubi_device *ubi; + + ubi = ubi_get_device(vol->ubi->ubi_num); + if (!ubi) + return -ENODEV; + + spin_lock(&ubi->volumes_lock); + if (!ubi->volumes[vol->vol_id]) { + spin_unlock(&ubi->volumes_lock); + ubi_put_device(ubi); + return -ENODEV; + } + /* Take a reference to prevent volume removal */ + vol->ref_count += 1; + spin_unlock(&ubi->volumes_lock); + + if (attr == &attr_vol_reserved_ebs) + ret = sprintf(buf, "%d\n", vol->reserved_pebs); + else if (attr == &attr_vol_type) { + const char *tp; + + if (vol->vol_type == UBI_DYNAMIC_VOLUME) + tp = "dynamic"; + else + tp = "static"; + ret = sprintf(buf, "%s\n", tp); + } else if (attr == &attr_vol_name) + ret = sprintf(buf, "%s\n", vol->name); + else if (attr == &attr_vol_corrupted) + ret = sprintf(buf, "%d\n", vol->corrupted); + else if (attr == &attr_vol_alignment) + ret = sprintf(buf, "%d\n", vol->alignment); + else if (attr == &attr_vol_usable_eb_size) + ret = sprintf(buf, "%d\n", vol->usable_leb_size); + else if (attr == &attr_vol_data_bytes) + ret = sprintf(buf, "%lld\n", vol->used_bytes); + else if (attr == &attr_vol_upd_marker) + ret = sprintf(buf, "%d\n", vol->upd_marker); + else + /* This must be a bug */ + ret = -EINVAL; + + /* We've done the operation, drop volume and UBI device references */ + spin_lock(&ubi->volumes_lock); + vol->ref_count -= 1; + ubi_assert(vol->ref_count >= 0); + spin_unlock(&ubi->volumes_lock); + ubi_put_device(ubi); + return ret; +} +#endif + +/* Release method for volume devices */ +static void vol_release(struct device *dev) +{ + struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); + + kfree(vol); +} + +#ifdef UBI_LINUX +/** + * volume_sysfs_init - initialize sysfs for new volume. + * @ubi: UBI device description object + * @vol: volume description object + * + * This function returns zero in case of success and a negative error code in + * case of failure. + * + * Note, this function does not free allocated resources in case of failure - + * the caller does it. This is because this would cause release() here and the + * caller would oops. + */ +static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol) +{ + int err; + + err = device_create_file(&vol->dev, &attr_vol_reserved_ebs); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_type); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_name); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_corrupted); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_alignment); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_usable_eb_size); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_data_bytes); + if (err) + return err; + err = device_create_file(&vol->dev, &attr_vol_upd_marker); + return err; +} + +/** + * volume_sysfs_close - close sysfs for a volume. + * @vol: volume description object + */ +static void volume_sysfs_close(struct ubi_volume *vol) +{ + device_remove_file(&vol->dev, &attr_vol_upd_marker); + device_remove_file(&vol->dev, &attr_vol_data_bytes); + device_remove_file(&vol->dev, &attr_vol_usable_eb_size); + device_remove_file(&vol->dev, &attr_vol_alignment); + device_remove_file(&vol->dev, &attr_vol_corrupted); + device_remove_file(&vol->dev, &attr_vol_name); + device_remove_file(&vol->dev, &attr_vol_type); + device_remove_file(&vol->dev, &attr_vol_reserved_ebs); + device_unregister(&vol->dev); +} +#endif + +/** + * ubi_create_volume - create volume. + * @ubi: UBI device description object + * @req: volume creation request + * + * This function creates volume described by @req. If @req->vol_id id + * %UBI_VOL_NUM_AUTO, this function automatically assign ID to the new volume + * and saves it in @req->vol_id. Returns zero in case of success and a negative + * error code in case of failure. Note, the caller has to have the + * @ubi->volumes_mutex locked. + */ +int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) +{ + int i, err, vol_id = req->vol_id, dont_free = 0; + struct ubi_volume *vol; + struct ubi_vtbl_record vtbl_rec; + uint64_t bytes; + dev_t dev; + + if (ubi->ro_mode) + return -EROFS; + + vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); + if (!vol) + return -ENOMEM; + + spin_lock(&ubi->volumes_lock); + if (vol_id == UBI_VOL_NUM_AUTO) { + /* Find unused volume ID */ + dbg_msg("search for vacant volume ID"); + for (i = 0; i < ubi->vtbl_slots; i++) + if (!ubi->volumes[i]) { + vol_id = i; + break; + } + + if (vol_id == UBI_VOL_NUM_AUTO) { + dbg_err("out of volume IDs"); + err = -ENFILE; + goto out_unlock; + } + req->vol_id = vol_id; + } + + dbg_msg("volume ID %d, %llu bytes, type %d, name %s", + vol_id, (unsigned long long)req->bytes, + (int)req->vol_type, req->name); + + /* Ensure that this volume does not exist */ + err = -EEXIST; + if (ubi->volumes[vol_id]) { + dbg_err("volume %d already exists", vol_id); + goto out_unlock; + } + + /* Ensure that the name is unique */ + for (i = 0; i < ubi->vtbl_slots; i++) + if (ubi->volumes[i] && + ubi->volumes[i]->name_len == req->name_len && + !strcmp(ubi->volumes[i]->name, req->name)) { + dbg_err("volume \"%s\" exists (ID %d)", req->name, i); + goto out_unlock; + } + + /* Calculate how many eraseblocks are requested */ + vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; + bytes = req->bytes; + if (do_div(bytes, vol->usable_leb_size)) + vol->reserved_pebs = 1; + vol->reserved_pebs += bytes; + + /* Reserve physical eraseblocks */ + if (vol->reserved_pebs > ubi->avail_pebs) { + dbg_err("not enough PEBs, only %d available", ubi->avail_pebs); + err = -ENOSPC; + goto out_unlock; + } + ubi->avail_pebs -= vol->reserved_pebs; + ubi->rsvd_pebs += vol->reserved_pebs; + spin_unlock(&ubi->volumes_lock); + + vol->vol_id = vol_id; + vol->alignment = req->alignment; + vol->data_pad = ubi->leb_size % vol->alignment; + vol->vol_type = req->vol_type; + vol->name_len = req->name_len; + memcpy(vol->name, req->name, vol->name_len + 1); + vol->ubi = ubi; + + /* + * Finish all pending erases because there may be some LEBs belonging + * to the same volume ID. + */ + err = ubi_wl_flush(ubi); + if (err) + goto out_acc; + + vol->eba_tbl = kmalloc(vol->reserved_pebs * sizeof(int), GFP_KERNEL); + if (!vol->eba_tbl) { + err = -ENOMEM; + goto out_acc; + } + + for (i = 0; i < vol->reserved_pebs; i++) + vol->eba_tbl[i] = UBI_LEB_UNMAPPED; + + if (vol->vol_type == UBI_DYNAMIC_VOLUME) { + vol->used_ebs = vol->reserved_pebs; + vol->last_eb_bytes = vol->usable_leb_size; + vol->used_bytes = + (long long)vol->used_ebs * vol->usable_leb_size; + } else { + bytes = vol->used_bytes; + vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); + vol->used_ebs = bytes; + if (vol->last_eb_bytes) + vol->used_ebs += 1; + else + vol->last_eb_bytes = vol->usable_leb_size; + } + + /* Register character device for the volume */ + cdev_init(&vol->cdev, &ubi_vol_cdev_operations); + vol->cdev.owner = THIS_MODULE; + dev = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1); + err = cdev_add(&vol->cdev, dev, 1); + if (err) { + ubi_err("cannot add character device"); + goto out_mapping; + } + + err = ubi_create_gluebi(ubi, vol); + if (err) + goto out_cdev; + + vol->dev.release = vol_release; + vol->dev.parent = &ubi->dev; + vol->dev.devt = dev; + vol->dev.class = ubi_class; + + sprintf(&vol->dev.bus_id[0], "%s_%d", ubi->ubi_name, vol->vol_id); + err = device_register(&vol->dev); + if (err) { + ubi_err("cannot register device"); + goto out_gluebi; + } + + err = volume_sysfs_init(ubi, vol); + if (err) + goto out_sysfs; + + /* Fill volume table record */ + memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record)); + vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs); + vtbl_rec.alignment = cpu_to_be32(vol->alignment); + vtbl_rec.data_pad = cpu_to_be32(vol->data_pad); + vtbl_rec.name_len = cpu_to_be16(vol->name_len); + if (vol->vol_type == UBI_DYNAMIC_VOLUME) + vtbl_rec.vol_type = UBI_VID_DYNAMIC; + else + vtbl_rec.vol_type = UBI_VID_STATIC; + memcpy(vtbl_rec.name, vol->name, vol->name_len + 1); + + err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); + if (err) + goto out_sysfs; + + spin_lock(&ubi->volumes_lock); + ubi->volumes[vol_id] = vol; + ubi->vol_count += 1; + spin_unlock(&ubi->volumes_lock); + + paranoid_check_volumes(ubi); + return 0; + +out_sysfs: + /* + * We have registered our device, we should not free the volume* + * description object in this function in case of an error - it is + * freed by the release function. + * + * Get device reference to prevent the release function from being + * called just after sysfs has been closed. + */ + dont_free = 1; + get_device(&vol->dev); + volume_sysfs_close(vol); +out_gluebi: + if (ubi_destroy_gluebi(vol)) + dbg_err("cannot destroy gluebi for volume %d:%d", + ubi->ubi_num, vol_id); +out_cdev: + cdev_del(&vol->cdev); +out_mapping: + kfree(vol->eba_tbl); +out_acc: + spin_lock(&ubi->volumes_lock); + ubi->rsvd_pebs -= vol->reserved_pebs; + ubi->avail_pebs += vol->reserved_pebs; +out_unlock: + spin_unlock(&ubi->volumes_lock); + if (dont_free) + put_device(&vol->dev); + else + kfree(vol); + ubi_err("cannot create volume %d, error %d", vol_id, err); + return err; +} + +/** + * ubi_remove_volume - remove volume. + * @desc: volume descriptor + * + * This function removes volume described by @desc. The volume has to be opened + * in "exclusive" mode. Returns zero in case of success and a negative error + * code in case of failure. The caller has to have the @ubi->volumes_mutex + * locked. + */ +int ubi_remove_volume(struct ubi_volume_desc *desc) +{ + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + int i, err, vol_id = vol->vol_id, reserved_pebs = vol->reserved_pebs; + + dbg_msg("remove UBI volume %d", vol_id); + ubi_assert(desc->mode == UBI_EXCLUSIVE); + ubi_assert(vol == ubi->volumes[vol_id]); + + if (ubi->ro_mode) + return -EROFS; + + spin_lock(&ubi->volumes_lock); + if (vol->ref_count > 1) { + /* + * The volume is busy, probably someone is reading one of its + * sysfs files. + */ + err = -EBUSY; + goto out_unlock; + } + ubi->volumes[vol_id] = NULL; + spin_unlock(&ubi->volumes_lock); + + err = ubi_destroy_gluebi(vol); + if (err) + goto out_err; + + err = ubi_change_vtbl_record(ubi, vol_id, NULL); + if (err) + goto out_err; + + for (i = 0; i < vol->reserved_pebs; i++) { + err = ubi_eba_unmap_leb(ubi, vol, i); + if (err) + goto out_err; + } + + kfree(vol->eba_tbl); + vol->eba_tbl = NULL; + cdev_del(&vol->cdev); + volume_sysfs_close(vol); + + spin_lock(&ubi->volumes_lock); + ubi->rsvd_pebs -= reserved_pebs; + ubi->avail_pebs += reserved_pebs; + i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; + if (i > 0) { + i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; + ubi->avail_pebs -= i; + ubi->rsvd_pebs += i; + ubi->beb_rsvd_pebs += i; + if (i > 0) + ubi_msg("reserve more %d PEBs", i); + } + ubi->vol_count -= 1; + spin_unlock(&ubi->volumes_lock); + + paranoid_check_volumes(ubi); + return 0; + +out_err: + ubi_err("cannot remove volume %d, error %d", vol_id, err); + spin_lock(&ubi->volumes_lock); + ubi->volumes[vol_id] = vol; +out_unlock: + spin_unlock(&ubi->volumes_lock); + return err; +} + +/** + * ubi_resize_volume - re-size volume. + * @desc: volume descriptor + * @reserved_pebs: new size in physical eraseblocks + * + * This function re-sizes the volume and returns zero in case of success, and a + * negative error code in case of failure. The caller has to have the + * @ubi->volumes_mutex locked. + */ +int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) +{ + int i, err, pebs, *new_mapping; + struct ubi_volume *vol = desc->vol; + struct ubi_device *ubi = vol->ubi; + struct ubi_vtbl_record vtbl_rec; + int vol_id = vol->vol_id; + + if (ubi->ro_mode) + return -EROFS; + + dbg_msg("re-size volume %d to from %d to %d PEBs", + vol_id, vol->reserved_pebs, reserved_pebs); + + if (vol->vol_type == UBI_STATIC_VOLUME && + reserved_pebs < vol->used_ebs) { + dbg_err("too small size %d, %d LEBs contain data", + reserved_pebs, vol->used_ebs); + return -EINVAL; + } + + /* If the size is the same, we have nothing to do */ + if (reserved_pebs == vol->reserved_pebs) + return 0; + + new_mapping = kmalloc(reserved_pebs * sizeof(int), GFP_KERNEL); + if (!new_mapping) + return -ENOMEM; + + for (i = 0; i < reserved_pebs; i++) + new_mapping[i] = UBI_LEB_UNMAPPED; + + spin_lock(&ubi->volumes_lock); + if (vol->ref_count > 1) { + spin_unlock(&ubi->volumes_lock); + err = -EBUSY; + goto out_free; + } + spin_unlock(&ubi->volumes_lock); + + /* Reserve physical eraseblocks */ + pebs = reserved_pebs - vol->reserved_pebs; + if (pebs > 0) { + spin_lock(&ubi->volumes_lock); + if (pebs > ubi->avail_pebs) { + dbg_err("not enough PEBs: requested %d, available %d", + pebs, ubi->avail_pebs); + spin_unlock(&ubi->volumes_lock); + err = -ENOSPC; + goto out_free; + } + ubi->avail_pebs -= pebs; + ubi->rsvd_pebs += pebs; + for (i = 0; i < vol->reserved_pebs; i++) + new_mapping[i] = vol->eba_tbl[i]; + kfree(vol->eba_tbl); + vol->eba_tbl = new_mapping; + spin_unlock(&ubi->volumes_lock); + } + + /* Change volume table record */ + memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); + vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs); + err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); + if (err) + goto out_acc; + + if (pebs < 0) { + for (i = 0; i < -pebs; i++) { + err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i); + if (err) + goto out_acc; + } + spin_lock(&ubi->volumes_lock); + ubi->rsvd_pebs += pebs; + ubi->avail_pebs -= pebs; + pebs = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; + if (pebs > 0) { + pebs = ubi->avail_pebs >= pebs ? pebs : ubi->avail_pebs; + ubi->avail_pebs -= pebs; + ubi->rsvd_pebs += pebs; + ubi->beb_rsvd_pebs += pebs; + if (pebs > 0) + ubi_msg("reserve more %d PEBs", pebs); + } + for (i = 0; i < reserved_pebs; i++) + new_mapping[i] = vol->eba_tbl[i]; + kfree(vol->eba_tbl); + vol->eba_tbl = new_mapping; + spin_unlock(&ubi->volumes_lock); + } + + vol->reserved_pebs = reserved_pebs; + if (vol->vol_type == UBI_DYNAMIC_VOLUME) { + vol->used_ebs = reserved_pebs; + vol->last_eb_bytes = vol->usable_leb_size; + vol->used_bytes = + (long long)vol->used_ebs * vol->usable_leb_size; + } + + paranoid_check_volumes(ubi); + return 0; + +out_acc: + if (pebs > 0) { + spin_lock(&ubi->volumes_lock); + ubi->rsvd_pebs -= pebs; + ubi->avail_pebs += pebs; + spin_unlock(&ubi->volumes_lock); + } +out_free: + kfree(new_mapping); + return err; +} + +/** + * ubi_add_volume - add volume. + * @ubi: UBI device description object + * @vol: volume description object + * + * This function adds an existing volume and initializes all its data + * structures. Returns zero in case of success and a negative error code in + * case of failure. + */ +int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol) +{ + int err, vol_id = vol->vol_id; + dev_t dev; + + dbg_msg("add volume %d", vol_id); + ubi_dbg_dump_vol_info(vol); + + /* Register character device for the volume */ + cdev_init(&vol->cdev, &ubi_vol_cdev_operations); + vol->cdev.owner = THIS_MODULE; + dev = MKDEV(MAJOR(ubi->cdev.dev), vol->vol_id + 1); + err = cdev_add(&vol->cdev, dev, 1); + if (err) { + ubi_err("cannot add character device for volume %d, error %d", + vol_id, err); + return err; + } + + err = ubi_create_gluebi(ubi, vol); + if (err) + goto out_cdev; + + vol->dev.release = vol_release; + vol->dev.parent = &ubi->dev; + vol->dev.devt = dev; + vol->dev.class = ubi_class; + sprintf(&vol->dev.bus_id[0], "%s_%d", ubi->ubi_name, vol->vol_id); + err = device_register(&vol->dev); + if (err) + goto out_gluebi; + + err = volume_sysfs_init(ubi, vol); + if (err) { + cdev_del(&vol->cdev); + err = ubi_destroy_gluebi(vol); + volume_sysfs_close(vol); + return err; + } + + paranoid_check_volumes(ubi); + return 0; + +out_gluebi: + err = ubi_destroy_gluebi(vol); +out_cdev: + cdev_del(&vol->cdev); + return err; +} + +/** + * ubi_free_volume - free volume. + * @ubi: UBI device description object + * @vol: volume description object + * + * This function frees all resources for volume @vol but does not remove it. + * Used only when the UBI device is detached. + */ +void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol) +{ + int err; + + dbg_msg("free volume %d", vol->vol_id); + + ubi->volumes[vol->vol_id] = NULL; + err = ubi_destroy_gluebi(vol); + cdev_del(&vol->cdev); + volume_sysfs_close(vol); +} + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID + +/** + * paranoid_check_volume - check volume information. + * @ubi: UBI device description object + * @vol_id: volume ID + */ +static void paranoid_check_volume(struct ubi_device *ubi, int vol_id) +{ + int idx = vol_id2idx(ubi, vol_id); + int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker; + const struct ubi_volume *vol; + long long n; + const char *name; + + spin_lock(&ubi->volumes_lock); + reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs); + vol = ubi->volumes[idx]; + + if (!vol) { + if (reserved_pebs) { + ubi_err("no volume info, but volume exists"); + goto fail; + } + spin_unlock(&ubi->volumes_lock); + return; + } + + if (vol->exclusive) { + /* + * The volume may be being created at the moment, do not check + * it (e.g., it may be in the middle of ubi_create_volume(). + */ + spin_unlock(&ubi->volumes_lock); + return; + } + + if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 || + vol->name_len < 0) { + ubi_err("negative values"); + goto fail; + } + if (vol->alignment > ubi->leb_size || vol->alignment == 0) { + ubi_err("bad alignment"); + goto fail; + } + + n = vol->alignment & (ubi->min_io_size - 1); + if (vol->alignment != 1 && n) { + ubi_err("alignment is not multiple of min I/O unit"); + goto fail; + } + + n = ubi->leb_size % vol->alignment; + if (vol->data_pad != n) { + ubi_err("bad data_pad, has to be %lld", n); + goto fail; + } + + if (vol->vol_type != UBI_DYNAMIC_VOLUME && + vol->vol_type != UBI_STATIC_VOLUME) { + ubi_err("bad vol_type"); + goto fail; + } + + if (vol->upd_marker && vol->corrupted) { + dbg_err("update marker and corrupted simultaneously"); + goto fail; + } + + if (vol->reserved_pebs > ubi->good_peb_count) { + ubi_err("too large reserved_pebs"); + goto fail; + } + + n = ubi->leb_size - vol->data_pad; + if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) { + ubi_err("bad usable_leb_size, has to be %lld", n); + goto fail; + } + + if (vol->name_len > UBI_VOL_NAME_MAX) { + ubi_err("too long volume name, max is %d", UBI_VOL_NAME_MAX); + goto fail; + } + + if (!vol->name) { + ubi_err("NULL volume name"); + goto fail; + } + + n = strnlen(vol->name, vol->name_len + 1); + if (n != vol->name_len) { + ubi_err("bad name_len %lld", n); + goto fail; + } + + n = (long long)vol->used_ebs * vol->usable_leb_size; + if (vol->vol_type == UBI_DYNAMIC_VOLUME) { + if (vol->corrupted) { + ubi_err("corrupted dynamic volume"); + goto fail; + } + if (vol->used_ebs != vol->reserved_pebs) { + ubi_err("bad used_ebs"); + goto fail; + } + if (vol->last_eb_bytes != vol->usable_leb_size) { + ubi_err("bad last_eb_bytes"); + goto fail; + } + if (vol->used_bytes != n) { + ubi_err("bad used_bytes"); + goto fail; + } + } else { + if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) { + ubi_err("bad used_ebs"); + goto fail; + } + if (vol->last_eb_bytes < 0 || + vol->last_eb_bytes > vol->usable_leb_size) { + ubi_err("bad last_eb_bytes"); + goto fail; + } + if (vol->used_bytes < 0 || vol->used_bytes > n || + vol->used_bytes < n - vol->usable_leb_size) { + ubi_err("bad used_bytes"); + goto fail; + } + } + + alignment = be32_to_cpu(ubi->vtbl[vol_id].alignment); + data_pad = be32_to_cpu(ubi->vtbl[vol_id].data_pad); + name_len = be16_to_cpu(ubi->vtbl[vol_id].name_len); + upd_marker = ubi->vtbl[vol_id].upd_marker; + name = &ubi->vtbl[vol_id].name[0]; + if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC) + vol_type = UBI_DYNAMIC_VOLUME; + else + vol_type = UBI_STATIC_VOLUME; + + if (alignment != vol->alignment || data_pad != vol->data_pad || + upd_marker != vol->upd_marker || vol_type != vol->vol_type || + name_len!= vol->name_len || strncmp(name, vol->name, name_len)) { + ubi_err("volume info is different"); + goto fail; + } + + spin_unlock(&ubi->volumes_lock); + return; + +fail: + ubi_err("paranoid check failed for volume %d", vol_id); + ubi_dbg_dump_vol_info(vol); + ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); + spin_unlock(&ubi->volumes_lock); + BUG(); +} + +/** + * paranoid_check_volumes - check information about all volumes. + * @ubi: UBI device description object + */ +static void paranoid_check_volumes(struct ubi_device *ubi) +{ + int i; + + for (i = 0; i < ubi->vtbl_slots; i++) + paranoid_check_volume(ubi, i); +} +#endif diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c new file mode 100644 index 0000000..9264ac6 --- /dev/null +++ b/drivers/mtd/ubi/vtbl.c @@ -0,0 +1,837 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * Copyright (c) Nokia Corporation, 2006, 2007 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +/* + * This file includes volume table manipulation code. The volume table is an + * on-flash table containing volume meta-data like name, number of reserved + * physical eraseblocks, type, etc. The volume table is stored in the so-called + * "layout volume". + * + * The layout volume is an internal volume which is organized as follows. It + * consists of two logical eraseblocks - LEB 0 and LEB 1. Each logical + * eraseblock stores one volume table copy, i.e. LEB 0 and LEB 1 duplicate each + * other. This redundancy guarantees robustness to unclean reboots. The volume + * table is basically an array of volume table records. Each record contains + * full information about the volume and protected by a CRC checksum. + * + * The volume table is changed, it is first changed in RAM. Then LEB 0 is + * erased, and the updated volume table is written back to LEB 0. Then same for + * LEB 1. This scheme guarantees recoverability from unclean reboots. + * + * In this UBI implementation the on-flash volume table does not contain any + * information about how many data static volumes contain. This information may + * be found from the scanning data. + * + * But it would still be beneficial to store this information in the volume + * table. For example, suppose we have a static volume X, and all its physical + * eraseblocks became bad for some reasons. Suppose we are attaching the + * corresponding MTD device, the scanning has found no logical eraseblocks + * corresponding to the volume X. According to the volume table volume X does + * exist. So we don't know whether it is just empty or all its physical + * eraseblocks went bad. So we cannot alarm the user about this corruption. + * + * The volume table also stores so-called "update marker", which is used for + * volume updates. Before updating the volume, the update marker is set, and + * after the update operation is finished, the update marker is cleared. So if + * the update operation was interrupted (e.g. by an unclean reboot) - the + * update marker is still there and we know that the volume's contents is + * damaged. + */ + +#ifdef UBI_LINUX +#include +#include +#include +#endif + +#include +#include "ubi.h" + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +static void paranoid_vtbl_check(const struct ubi_device *ubi); +#else +#define paranoid_vtbl_check(ubi) +#endif + +/* Empty volume table record */ +static struct ubi_vtbl_record empty_vtbl_record; + +/** + * ubi_change_vtbl_record - change volume table record. + * @ubi: UBI device description object + * @idx: table index to change + * @vtbl_rec: new volume table record + * + * This function changes volume table record @idx. If @vtbl_rec is %NULL, empty + * volume table record is written. The caller does not have to calculate CRC of + * the record as it is done by this function. Returns zero in case of success + * and a negative error code in case of failure. + */ +int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, + struct ubi_vtbl_record *vtbl_rec) +{ + int i, err; + uint32_t crc; + struct ubi_volume *layout_vol; + + ubi_assert(idx >= 0 && idx < ubi->vtbl_slots); + layout_vol = ubi->volumes[vol_id2idx(ubi, UBI_LAYOUT_VOLUME_ID)]; + + if (!vtbl_rec) + vtbl_rec = &empty_vtbl_record; + else { + crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); + vtbl_rec->crc = cpu_to_be32(crc); + } + + memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); + for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { + err = ubi_eba_unmap_leb(ubi, layout_vol, i); + if (err) + return err; + + err = ubi_eba_write_leb(ubi, layout_vol, i, ubi->vtbl, 0, + ubi->vtbl_size, UBI_LONGTERM); + if (err) + return err; + } + + paranoid_vtbl_check(ubi); + return 0; +} + +/** + * vtbl_check - check if volume table is not corrupted and contains sensible + * data. + * @ubi: UBI device description object + * @vtbl: volume table + * + * This function returns zero if @vtbl is all right, %1 if CRC is incorrect, + * and %-EINVAL if it contains inconsistent data. + */ +static int vtbl_check(const struct ubi_device *ubi, + const struct ubi_vtbl_record *vtbl) +{ + int i, n, reserved_pebs, alignment, data_pad, vol_type, name_len; + int upd_marker, err; + uint32_t crc; + const char *name; + + for (i = 0; i < ubi->vtbl_slots; i++) { + cond_resched(); + + reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); + alignment = be32_to_cpu(vtbl[i].alignment); + data_pad = be32_to_cpu(vtbl[i].data_pad); + upd_marker = vtbl[i].upd_marker; + vol_type = vtbl[i].vol_type; + name_len = be16_to_cpu(vtbl[i].name_len); + name = (const char *) &vtbl[i].name[0]; + + crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); + if (be32_to_cpu(vtbl[i].crc) != crc) { + ubi_err("bad CRC at record %u: %#08x, not %#08x", + i, crc, be32_to_cpu(vtbl[i].crc)); + ubi_dbg_dump_vtbl_record(&vtbl[i], i); + return 1; + } + + if (reserved_pebs == 0) { + if (memcmp(&vtbl[i], &empty_vtbl_record, + UBI_VTBL_RECORD_SIZE)) { + err = 2; + goto bad; + } + continue; + } + + if (reserved_pebs < 0 || alignment < 0 || data_pad < 0 || + name_len < 0) { + err = 3; + goto bad; + } + + if (alignment > ubi->leb_size || alignment == 0) { + err = 4; + goto bad; + } + + n = alignment & (ubi->min_io_size - 1); + if (alignment != 1 && n) { + err = 5; + goto bad; + } + + n = ubi->leb_size % alignment; + if (data_pad != n) { + dbg_err("bad data_pad, has to be %d", n); + err = 6; + goto bad; + } + + if (vol_type != UBI_VID_DYNAMIC && vol_type != UBI_VID_STATIC) { + err = 7; + goto bad; + } + + if (upd_marker != 0 && upd_marker != 1) { + err = 8; + goto bad; + } + + if (reserved_pebs > ubi->good_peb_count) { + dbg_err("too large reserved_pebs, good PEBs %d", + ubi->good_peb_count); + err = 9; + goto bad; + } + + if (name_len > UBI_VOL_NAME_MAX) { + err = 10; + goto bad; + } + + if (name[0] == '\0') { + err = 11; + goto bad; + } + + if (name_len != strnlen(name, name_len + 1)) { + err = 12; + goto bad; + } + } + + /* Checks that all names are unique */ + for (i = 0; i < ubi->vtbl_slots - 1; i++) { + for (n = i + 1; n < ubi->vtbl_slots; n++) { + int len1 = be16_to_cpu(vtbl[i].name_len); + int len2 = be16_to_cpu(vtbl[n].name_len); + + if (len1 > 0 && len1 == len2 && + !strncmp((char *)vtbl[i].name, (char *)vtbl[n].name, len1)) { + ubi_err("volumes %d and %d have the same name" + " \"%s\"", i, n, vtbl[i].name); + ubi_dbg_dump_vtbl_record(&vtbl[i], i); + ubi_dbg_dump_vtbl_record(&vtbl[n], n); + return -EINVAL; + } + } + } + + return 0; + +bad: + ubi_err("volume table check failed: record %d, error %d", i, err); + ubi_dbg_dump_vtbl_record(&vtbl[i], i); + return -EINVAL; +} + +/** + * create_vtbl - create a copy of volume table. + * @ubi: UBI device description object + * @si: scanning information + * @copy: number of the volume table copy + * @vtbl: contents of the volume table + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, + int copy, void *vtbl) +{ + int err, tries = 0; + static struct ubi_vid_hdr *vid_hdr; + struct ubi_scan_volume *sv; + struct ubi_scan_leb *new_seb, *old_seb = NULL; + + ubi_msg("create volume table (copy #%d)", copy + 1); + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL); + if (!vid_hdr) + return -ENOMEM; + + /* + * Check if there is a logical eraseblock which would have to contain + * this volume table copy was found during scanning. It has to be wiped + * out. + */ + sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID); + if (sv) + old_seb = ubi_scan_find_seb(sv, copy); + +retry: + new_seb = ubi_scan_get_free_peb(ubi, si); + if (IS_ERR(new_seb)) { + err = PTR_ERR(new_seb); + goto out_free; + } + + vid_hdr->vol_type = UBI_VID_DYNAMIC; + vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOLUME_ID); + vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; + vid_hdr->data_size = vid_hdr->used_ebs = + vid_hdr->data_pad = cpu_to_be32(0); + vid_hdr->lnum = cpu_to_be32(copy); + vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum); + vid_hdr->leb_ver = cpu_to_be32(old_seb ? old_seb->leb_ver + 1: 0); + + /* The EC header is already there, write the VID header */ + err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr); + if (err) + goto write_error; + + /* Write the layout volume contents */ + err = ubi_io_write_data(ubi, vtbl, new_seb->pnum, 0, ubi->vtbl_size); + if (err) + goto write_error; + + /* + * And add it to the scanning information. Don't delete the old + * @old_seb as it will be deleted and freed in 'ubi_scan_add_used()'. + */ + err = ubi_scan_add_used(ubi, si, new_seb->pnum, new_seb->ec, + vid_hdr, 0); + kfree(new_seb); + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + +write_error: + if (err == -EIO && ++tries <= 5) { + /* + * Probably this physical eraseblock went bad, try to pick + * another one. + */ + list_add_tail(&new_seb->u.list, &si->corr); + goto retry; + } + kfree(new_seb); +out_free: + ubi_free_vid_hdr(ubi, vid_hdr); + return err; + +} + +/** + * process_lvol - process the layout volume. + * @ubi: UBI device description object + * @si: scanning information + * @sv: layout volume scanning information + * + * This function is responsible for reading the layout volume, ensuring it is + * not corrupted, and recovering from corruptions if needed. Returns volume + * table in case of success and a negative error code in case of failure. + */ +static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, + struct ubi_scan_info *si, + struct ubi_scan_volume *sv) +{ + int err; + struct rb_node *rb; + struct ubi_scan_leb *seb; + struct ubi_vtbl_record *leb[UBI_LAYOUT_VOLUME_EBS] = { NULL, NULL }; + int leb_corrupted[UBI_LAYOUT_VOLUME_EBS] = {1, 1}; + + /* + * UBI goes through the following steps when it changes the layout + * volume: + * a. erase LEB 0; + * b. write new data to LEB 0; + * c. erase LEB 1; + * d. write new data to LEB 1. + * + * Before the change, both LEBs contain the same data. + * + * Due to unclean reboots, the contents of LEB 0 may be lost, but there + * should LEB 1. So it is OK if LEB 0 is corrupted while LEB 1 is not. + * Similarly, LEB 1 may be lost, but there should be LEB 0. And + * finally, unclean reboots may result in a situation when neither LEB + * 0 nor LEB 1 are corrupted, but they are different. In this case, LEB + * 0 contains more recent information. + * + * So the plan is to first check LEB 0. Then + * a. if LEB 0 is OK, it must be containing the most resent data; then + * we compare it with LEB 1, and if they are different, we copy LEB + * 0 to LEB 1; + * b. if LEB 0 is corrupted, but LEB 1 has to be OK, and we copy LEB 1 + * to LEB 0. + */ + + dbg_msg("check layout volume"); + + /* Read both LEB 0 and LEB 1 into memory */ + ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { + leb[seb->lnum] = vmalloc(ubi->vtbl_size); + if (!leb[seb->lnum]) { + err = -ENOMEM; + goto out_free; + } + memset(leb[seb->lnum], 0, ubi->vtbl_size); + + err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, + ubi->vtbl_size); + if (err == UBI_IO_BITFLIPS || err == -EBADMSG) + /* + * Scrub the PEB later. Note, -EBADMSG indicates an + * uncorrectable ECC error, but we have our own CRC and + * the data will be checked later. If the data is OK, + * the PEB will be scrubbed (because we set + * seb->scrub). If the data is not OK, the contents of + * the PEB will be recovered from the second copy, and + * seb->scrub will be cleared in + * 'ubi_scan_add_used()'. + */ + seb->scrub = 1; + else if (err) + goto out_free; + } + + err = -EINVAL; + if (leb[0]) { + leb_corrupted[0] = vtbl_check(ubi, leb[0]); + if (leb_corrupted[0] < 0) + goto out_free; + } + + if (!leb_corrupted[0]) { + /* LEB 0 is OK */ + if (leb[1]) + leb_corrupted[1] = memcmp(leb[0], leb[1], ubi->vtbl_size); + if (leb_corrupted[1]) { + ubi_warn("volume table copy #2 is corrupted"); + err = create_vtbl(ubi, si, 1, leb[0]); + if (err) + goto out_free; + ubi_msg("volume table was restored"); + } + + /* Both LEB 1 and LEB 2 are OK and consistent */ + vfree(leb[1]); + return leb[0]; + } else { + /* LEB 0 is corrupted or does not exist */ + if (leb[1]) { + leb_corrupted[1] = vtbl_check(ubi, leb[1]); + if (leb_corrupted[1] < 0) + goto out_free; + } + if (leb_corrupted[1]) { + /* Both LEB 0 and LEB 1 are corrupted */ + ubi_err("both volume tables are corrupted"); + goto out_free; + } + + ubi_warn("volume table copy #1 is corrupted"); + err = create_vtbl(ubi, si, 0, leb[1]); + if (err) + goto out_free; + ubi_msg("volume table was restored"); + + vfree(leb[0]); + return leb[1]; + } + +out_free: + vfree(leb[0]); + vfree(leb[1]); + return ERR_PTR(err); +} + +/** + * create_empty_lvol - create empty layout volume. + * @ubi: UBI device description object + * @si: scanning information + * + * This function returns volume table contents in case of success and a + * negative error code in case of failure. + */ +static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, + struct ubi_scan_info *si) +{ + int i; + struct ubi_vtbl_record *vtbl; + + vtbl = vmalloc(ubi->vtbl_size); + if (!vtbl) + return ERR_PTR(-ENOMEM); + memset(vtbl, 0, ubi->vtbl_size); + + for (i = 0; i < ubi->vtbl_slots; i++) + memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); + + for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { + int err; + + err = create_vtbl(ubi, si, i, vtbl); + if (err) { + vfree(vtbl); + return ERR_PTR(err); + } + } + + return vtbl; +} + +/** + * init_volumes - initialize volume information for existing volumes. + * @ubi: UBI device description object + * @si: scanning information + * @vtbl: volume table + * + * This function allocates volume description objects for existing volumes. + * Returns zero in case of success and a negative error code in case of + * failure. + */ +static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, + const struct ubi_vtbl_record *vtbl) +{ + int i, reserved_pebs = 0; + struct ubi_scan_volume *sv; + struct ubi_volume *vol; + + for (i = 0; i < ubi->vtbl_slots; i++) { + cond_resched(); + + if (be32_to_cpu(vtbl[i].reserved_pebs) == 0) + continue; /* Empty record */ + + vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); + if (!vol) + return -ENOMEM; + + vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); + vol->alignment = be32_to_cpu(vtbl[i].alignment); + vol->data_pad = be32_to_cpu(vtbl[i].data_pad); + vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ? + UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; + vol->name_len = be16_to_cpu(vtbl[i].name_len); + vol->usable_leb_size = ubi->leb_size - vol->data_pad; + memcpy(vol->name, vtbl[i].name, vol->name_len); + vol->name[vol->name_len] = '\0'; + vol->vol_id = i; + + if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) { + /* Auto re-size flag may be set only for one volume */ + if (ubi->autoresize_vol_id != -1) { + ubi_err("more then one auto-resize volume (%d " + "and %d)", ubi->autoresize_vol_id, i); + kfree(vol); + return -EINVAL; + } + + ubi->autoresize_vol_id = i; + } + + ubi_assert(!ubi->volumes[i]); + ubi->volumes[i] = vol; + ubi->vol_count += 1; + vol->ubi = ubi; + reserved_pebs += vol->reserved_pebs; + + /* + * In case of dynamic volume UBI knows nothing about how many + * data is stored there. So assume the whole volume is used. + */ + if (vol->vol_type == UBI_DYNAMIC_VOLUME) { + vol->used_ebs = vol->reserved_pebs; + vol->last_eb_bytes = vol->usable_leb_size; + vol->used_bytes = + (long long)vol->used_ebs * vol->usable_leb_size; + continue; + } + + /* Static volumes only */ + sv = ubi_scan_find_sv(si, i); + if (!sv) { + /* + * No eraseblocks belonging to this volume found. We + * don't actually know whether this static volume is + * completely corrupted or just contains no data. And + * we cannot know this as long as data size is not + * stored on flash. So we just assume the volume is + * empty. FIXME: this should be handled. + */ + continue; + } + + if (sv->leb_count != sv->used_ebs) { + /* + * We found a static volume which misses several + * eraseblocks. Treat it as corrupted. + */ + ubi_warn("static volume %d misses %d LEBs - corrupted", + sv->vol_id, sv->used_ebs - sv->leb_count); + vol->corrupted = 1; + continue; + } + + vol->used_ebs = sv->used_ebs; + vol->used_bytes = + (long long)(vol->used_ebs - 1) * vol->usable_leb_size; + vol->used_bytes += sv->last_data_size; + vol->last_eb_bytes = sv->last_data_size; + } + + /* And add the layout volume */ + vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); + if (!vol) + return -ENOMEM; + + vol->reserved_pebs = UBI_LAYOUT_VOLUME_EBS; + vol->alignment = 1; + vol->vol_type = UBI_DYNAMIC_VOLUME; + vol->name_len = sizeof(UBI_LAYOUT_VOLUME_NAME) - 1; + memcpy(vol->name, UBI_LAYOUT_VOLUME_NAME, vol->name_len + 1); + vol->usable_leb_size = ubi->leb_size; + vol->used_ebs = vol->reserved_pebs; + vol->last_eb_bytes = vol->reserved_pebs; + vol->used_bytes = + (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad); + vol->vol_id = UBI_LAYOUT_VOLUME_ID; + vol->ref_count = 1; + + ubi_assert(!ubi->volumes[i]); + ubi->volumes[vol_id2idx(ubi, vol->vol_id)] = vol; + reserved_pebs += vol->reserved_pebs; + ubi->vol_count += 1; + vol->ubi = ubi; + + if (reserved_pebs > ubi->avail_pebs) + ubi_err("not enough PEBs, required %d, available %d", + reserved_pebs, ubi->avail_pebs); + ubi->rsvd_pebs += reserved_pebs; + ubi->avail_pebs -= reserved_pebs; + + return 0; +} + +/** + * check_sv - check volume scanning information. + * @vol: UBI volume description object + * @sv: volume scanning information + * + * This function returns zero if the volume scanning information is consistent + * to the data read from the volume tabla, and %-EINVAL if not. + */ +static int check_sv(const struct ubi_volume *vol, + const struct ubi_scan_volume *sv) +{ + int err; + + if (sv->highest_lnum >= vol->reserved_pebs) { + err = 1; + goto bad; + } + if (sv->leb_count > vol->reserved_pebs) { + err = 2; + goto bad; + } + if (sv->vol_type != vol->vol_type) { + err = 3; + goto bad; + } + if (sv->used_ebs > vol->reserved_pebs) { + err = 4; + goto bad; + } + if (sv->data_pad != vol->data_pad) { + err = 5; + goto bad; + } + return 0; + +bad: + ubi_err("bad scanning information, error %d", err); + ubi_dbg_dump_sv(sv); + ubi_dbg_dump_vol_info(vol); + return -EINVAL; +} + +/** + * check_scanning_info - check that scanning information. + * @ubi: UBI device description object + * @si: scanning information + * + * Even though we protect on-flash data by CRC checksums, we still don't trust + * the media. This function ensures that scanning information is consistent to + * the information read from the volume table. Returns zero if the scanning + * information is OK and %-EINVAL if it is not. + */ +static int check_scanning_info(const struct ubi_device *ubi, + struct ubi_scan_info *si) +{ + int err, i; + struct ubi_scan_volume *sv; + struct ubi_volume *vol; + + if (si->vols_found > UBI_INT_VOL_COUNT + ubi->vtbl_slots) { + ubi_err("scanning found %d volumes, maximum is %d + %d", + si->vols_found, UBI_INT_VOL_COUNT, ubi->vtbl_slots); + return -EINVAL; + } + + if (si->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT && + si->highest_vol_id < UBI_INTERNAL_VOL_START) { + ubi_err("too large volume ID %d found by scanning", + si->highest_vol_id); + return -EINVAL; + } + + for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { + cond_resched(); + + sv = ubi_scan_find_sv(si, i); + vol = ubi->volumes[i]; + if (!vol) { + if (sv) + ubi_scan_rm_volume(si, sv); + continue; + } + + if (vol->reserved_pebs == 0) { + ubi_assert(i < ubi->vtbl_slots); + + if (!sv) + continue; + + /* + * During scanning we found a volume which does not + * exist according to the information in the volume + * table. This must have happened due to an unclean + * reboot while the volume was being removed. Discard + * these eraseblocks. + */ + ubi_msg("finish volume %d removal", sv->vol_id); + ubi_scan_rm_volume(si, sv); + } else if (sv) { + err = check_sv(vol, sv); + if (err) + return err; + } + } + + return 0; +} + +/** + * ubi_read_volume_table - read volume table. + * information. + * @ubi: UBI device description object + * @si: scanning information + * + * This function reads volume table, checks it, recover from errors if needed, + * or creates it if needed. Returns zero in case of success and a negative + * error code in case of failure. + */ +int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) +{ + int i, err; + struct ubi_scan_volume *sv; + + empty_vtbl_record.crc = cpu_to_be32(0xf116c36b); + + /* + * The number of supported volumes is limited by the eraseblock size + * and by the UBI_MAX_VOLUMES constant. + */ + ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE; + if (ubi->vtbl_slots > UBI_MAX_VOLUMES) + ubi->vtbl_slots = UBI_MAX_VOLUMES; + + ubi->vtbl_size = ubi->vtbl_slots * UBI_VTBL_RECORD_SIZE; + ubi->vtbl_size = ALIGN(ubi->vtbl_size, ubi->min_io_size); + + sv = ubi_scan_find_sv(si, UBI_LAYOUT_VOLUME_ID); + if (!sv) { + /* + * No logical eraseblocks belonging to the layout volume were + * found. This could mean that the flash is just empty. In + * this case we create empty layout volume. + * + * But if flash is not empty this must be a corruption or the + * MTD device just contains garbage. + */ + if (si->is_empty) { + ubi->vtbl = create_empty_lvol(ubi, si); + if (IS_ERR(ubi->vtbl)) + return PTR_ERR(ubi->vtbl); + } else { + ubi_err("the layout volume was not found"); + return -EINVAL; + } + } else { + if (sv->leb_count > UBI_LAYOUT_VOLUME_EBS) { + /* This must not happen with proper UBI images */ + dbg_err("too many LEBs (%d) in layout volume", + sv->leb_count); + return -EINVAL; + } + + ubi->vtbl = process_lvol(ubi, si, sv); + if (IS_ERR(ubi->vtbl)) + return PTR_ERR(ubi->vtbl); + } + + ubi->avail_pebs = ubi->good_peb_count; + + /* + * The layout volume is OK, initialize the corresponding in-RAM data + * structures. + */ + err = init_volumes(ubi, si, ubi->vtbl); + if (err) + goto out_free; + + /* + * Get sure that the scanning information is consistent to the + * information stored in the volume table. + */ + err = check_scanning_info(ubi, si); + if (err) + goto out_free; + + return 0; + +out_free: + vfree(ubi->vtbl); + for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) + if (ubi->volumes[i]) { + kfree(ubi->volumes[i]); + ubi->volumes[i] = NULL; + } + return err; +} + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID + +/** + * paranoid_vtbl_check - check volume table. + * @ubi: UBI device description object + */ +static void paranoid_vtbl_check(const struct ubi_device *ubi) +{ + if (vtbl_check(ubi, ubi->vtbl)) { + ubi_err("paranoid check failed"); + BUG(); + } +} + +#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c new file mode 100644 index 0000000..2f9a5e3 --- /dev/null +++ b/drivers/mtd/ubi/wl.c @@ -0,0 +1,1670 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Artem Bityutskiy (Битюцкий Артём), Thomas Gleixner + */ + +/* + * UBI wear-leveling unit. + * + * This unit is responsible for wear-leveling. It works in terms of physical + * eraseblocks and erase counters and knows nothing about logical eraseblocks, + * volumes, etc. From this unit's perspective all physical eraseblocks are of + * two types - used and free. Used physical eraseblocks are those that were + * "get" by the 'ubi_wl_get_peb()' function, and free physical eraseblocks are + * those that were put by the 'ubi_wl_put_peb()' function. + * + * Physical eraseblocks returned by 'ubi_wl_get_peb()' have only erase counter + * header. The rest of the physical eraseblock contains only 0xFF bytes. + * + * When physical eraseblocks are returned to the WL unit by means of the + * 'ubi_wl_put_peb()' function, they are scheduled for erasure. The erasure is + * done asynchronously in context of the per-UBI device background thread, + * which is also managed by the WL unit. + * + * The wear-leveling is ensured by means of moving the contents of used + * physical eraseblocks with low erase counter to free physical eraseblocks + * with high erase counter. + * + * The 'ubi_wl_get_peb()' function accepts data type hints which help to pick + * an "optimal" physical eraseblock. For example, when it is known that the + * physical eraseblock will be "put" soon because it contains short-term data, + * the WL unit may pick a free physical eraseblock with low erase counter, and + * so forth. + * + * If the WL unit fails to erase a physical eraseblock, it marks it as bad. + * + * This unit is also responsible for scrubbing. If a bit-flip is detected in a + * physical eraseblock, it has to be moved. Technically this is the same as + * moving it for wear-leveling reasons. + * + * As it was said, for the UBI unit all physical eraseblocks are either "free" + * or "used". Free eraseblock are kept in the @wl->free RB-tree, while used + * eraseblocks are kept in a set of different RB-trees: @wl->used, + * @wl->prot.pnum, @wl->prot.aec, and @wl->scrub. + * + * Note, in this implementation, we keep a small in-RAM object for each physical + * eraseblock. This is surely not a scalable solution. But it appears to be good + * enough for moderately large flashes and it is simple. In future, one may + * re-work this unit and make it more scalable. + * + * At the moment this unit does not utilize the sequence number, which was + * introduced relatively recently. But it would be wise to do this because the + * sequence number of a logical eraseblock characterizes how old is it. For + * example, when we move a PEB with low erase counter, and we need to pick the + * target PEB, we pick a PEB with the highest EC if our PEB is "old" and we + * pick target PEB with an average EC if our PEB is not very "old". This is a + * room for future re-works of the WL unit. + * + * FIXME: looks too complex, should be simplified (later). + */ + +#ifdef UBI_LINUX +#include +#include +#include +#include +#endif + +#include +#include "ubi.h" + +/* Number of physical eraseblocks reserved for wear-leveling purposes */ +#define WL_RESERVED_PEBS 1 + +/* + * How many erase cycles are short term, unknown, and long term physical + * eraseblocks protected. + */ +#define ST_PROTECTION 16 +#define U_PROTECTION 10 +#define LT_PROTECTION 4 + +/* + * Maximum difference between two erase counters. If this threshold is + * exceeded, the WL unit starts moving data from used physical eraseblocks with + * low erase counter to free physical eraseblocks with high erase counter. + */ +#define UBI_WL_THRESHOLD CONFIG_MTD_UBI_WL_THRESHOLD + +/* + * When a physical eraseblock is moved, the WL unit has to pick the target + * physical eraseblock to move to. The simplest way would be just to pick the + * one with the highest erase counter. But in certain workloads this could lead + * to an unlimited wear of one or few physical eraseblock. Indeed, imagine a + * situation when the picked physical eraseblock is constantly erased after the + * data is written to it. So, we have a constant which limits the highest erase + * counter of the free physical eraseblock to pick. Namely, the WL unit does + * not pick eraseblocks with erase counter greater then the lowest erase + * counter plus %WL_FREE_MAX_DIFF. + */ +#define WL_FREE_MAX_DIFF (2*UBI_WL_THRESHOLD) + +/* + * Maximum number of consecutive background thread failures which is enough to + * switch to read-only mode. + */ +#define WL_MAX_FAILURES 32 + +/** + * struct ubi_wl_prot_entry - PEB protection entry. + * @rb_pnum: link in the @wl->prot.pnum RB-tree + * @rb_aec: link in the @wl->prot.aec RB-tree + * @abs_ec: the absolute erase counter value when the protection ends + * @e: the wear-leveling entry of the physical eraseblock under protection + * + * When the WL unit returns a physical eraseblock, the physical eraseblock is + * protected from being moved for some "time". For this reason, the physical + * eraseblock is not directly moved from the @wl->free tree to the @wl->used + * tree. There is one more tree in between where this physical eraseblock is + * temporarily stored (@wl->prot). + * + * All this protection stuff is needed because: + * o we don't want to move physical eraseblocks just after we have given them + * to the user; instead, we first want to let users fill them up with data; + * + * o there is a chance that the user will put the physical eraseblock very + * soon, so it makes sense not to move it for some time, but wait; this is + * especially important in case of "short term" physical eraseblocks. + * + * Physical eraseblocks stay protected only for limited time. But the "time" is + * measured in erase cycles in this case. This is implemented with help of the + * absolute erase counter (@wl->abs_ec). When it reaches certain value, the + * physical eraseblocks are moved from the protection trees (@wl->prot.*) to + * the @wl->used tree. + * + * Protected physical eraseblocks are searched by physical eraseblock number + * (when they are put) and by the absolute erase counter (to check if it is + * time to move them to the @wl->used tree). So there are actually 2 RB-trees + * storing the protected physical eraseblocks: @wl->prot.pnum and + * @wl->prot.aec. They are referred to as the "protection" trees. The + * first one is indexed by the physical eraseblock number. The second one is + * indexed by the absolute erase counter. Both trees store + * &struct ubi_wl_prot_entry objects. + * + * Each physical eraseblock has 2 main states: free and used. The former state + * corresponds to the @wl->free tree. The latter state is split up on several + * sub-states: + * o the WL movement is allowed (@wl->used tree); + * o the WL movement is temporarily prohibited (@wl->prot.pnum and + * @wl->prot.aec trees); + * o scrubbing is needed (@wl->scrub tree). + * + * Depending on the sub-state, wear-leveling entries of the used physical + * eraseblocks may be kept in one of those trees. + */ +struct ubi_wl_prot_entry { + struct rb_node rb_pnum; + struct rb_node rb_aec; + unsigned long long abs_ec; + struct ubi_wl_entry *e; +}; + +/** + * struct ubi_work - UBI work description data structure. + * @list: a link in the list of pending works + * @func: worker function + * @priv: private data of the worker function + * + * @e: physical eraseblock to erase + * @torture: if the physical eraseblock has to be tortured + * + * The @func pointer points to the worker function. If the @cancel argument is + * not zero, the worker has to free the resources and exit immediately. The + * worker has to return zero in case of success and a negative error code in + * case of failure. + */ +struct ubi_work { + struct list_head list; + int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel); + /* The below fields are only relevant to erasure works */ + struct ubi_wl_entry *e; + int torture; +}; + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID +static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec); +static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, + struct rb_root *root); +#else +#define paranoid_check_ec(ubi, pnum, ec) 0 +#define paranoid_check_in_wl_tree(e, root) +#endif + +/** + * wl_tree_add - add a wear-leveling entry to a WL RB-tree. + * @e: the wear-leveling entry to add + * @root: the root of the tree + * + * Note, we use (erase counter, physical eraseblock number) pairs as keys in + * the @ubi->used and @ubi->free RB-trees. + */ +static void wl_tree_add(struct ubi_wl_entry *e, struct rb_root *root) +{ + struct rb_node **p, *parent = NULL; + + p = &root->rb_node; + while (*p) { + struct ubi_wl_entry *e1; + + parent = *p; + e1 = rb_entry(parent, struct ubi_wl_entry, rb); + + if (e->ec < e1->ec) + p = &(*p)->rb_left; + else if (e->ec > e1->ec) + p = &(*p)->rb_right; + else { + ubi_assert(e->pnum != e1->pnum); + if (e->pnum < e1->pnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + } + + rb_link_node(&e->rb, parent, p); + rb_insert_color(&e->rb, root); +} + +/** + * do_work - do one pending work. + * @ubi: UBI device description object + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int do_work(struct ubi_device *ubi) +{ + int err; + struct ubi_work *wrk; + + cond_resched(); + + /* + * @ubi->work_sem is used to synchronize with the workers. Workers take + * it in read mode, so many of them may be doing works at a time. But + * the queue flush code has to be sure the whole queue of works is + * done, and it takes the mutex in write mode. + */ + down_read(&ubi->work_sem); + spin_lock(&ubi->wl_lock); + if (list_empty(&ubi->works)) { + spin_unlock(&ubi->wl_lock); + up_read(&ubi->work_sem); + return 0; + } + + wrk = list_entry(ubi->works.next, struct ubi_work, list); + list_del(&wrk->list); + ubi->works_count -= 1; + ubi_assert(ubi->works_count >= 0); + spin_unlock(&ubi->wl_lock); + + /* + * Call the worker function. Do not touch the work structure + * after this call as it will have been freed or reused by that + * time by the worker function. + */ + err = wrk->func(ubi, wrk, 0); + if (err) + ubi_err("work failed with error code %d", err); + up_read(&ubi->work_sem); + + return err; +} + +/** + * produce_free_peb - produce a free physical eraseblock. + * @ubi: UBI device description object + * + * This function tries to make a free PEB by means of synchronous execution of + * pending works. This may be needed if, for example the background thread is + * disabled. Returns zero in case of success and a negative error code in case + * of failure. + */ +static int produce_free_peb(struct ubi_device *ubi) +{ + int err; + + spin_lock(&ubi->wl_lock); + while (!ubi->free.rb_node) { + spin_unlock(&ubi->wl_lock); + + dbg_wl("do one work synchronously"); + err = do_work(ubi); + if (err) + return err; + + spin_lock(&ubi->wl_lock); + } + spin_unlock(&ubi->wl_lock); + + return 0; +} + +/** + * in_wl_tree - check if wear-leveling entry is present in a WL RB-tree. + * @e: the wear-leveling entry to check + * @root: the root of the tree + * + * This function returns non-zero if @e is in the @root RB-tree and zero if it + * is not. + */ +static int in_wl_tree(struct ubi_wl_entry *e, struct rb_root *root) +{ + struct rb_node *p; + + p = root->rb_node; + while (p) { + struct ubi_wl_entry *e1; + + e1 = rb_entry(p, struct ubi_wl_entry, rb); + + if (e->pnum == e1->pnum) { + ubi_assert(e == e1); + return 1; + } + + if (e->ec < e1->ec) + p = p->rb_left; + else if (e->ec > e1->ec) + p = p->rb_right; + else { + ubi_assert(e->pnum != e1->pnum); + if (e->pnum < e1->pnum) + p = p->rb_left; + else + p = p->rb_right; + } + } + + return 0; +} + +/** + * prot_tree_add - add physical eraseblock to protection trees. + * @ubi: UBI device description object + * @e: the physical eraseblock to add + * @pe: protection entry object to use + * @abs_ec: absolute erase counter value when this physical eraseblock has + * to be removed from the protection trees. + * + * @wl->lock has to be locked. + */ +static void prot_tree_add(struct ubi_device *ubi, struct ubi_wl_entry *e, + struct ubi_wl_prot_entry *pe, int abs_ec) +{ + struct rb_node **p, *parent = NULL; + struct ubi_wl_prot_entry *pe1; + + pe->e = e; + pe->abs_ec = ubi->abs_ec + abs_ec; + + p = &ubi->prot.pnum.rb_node; + while (*p) { + parent = *p; + pe1 = rb_entry(parent, struct ubi_wl_prot_entry, rb_pnum); + + if (e->pnum < pe1->e->pnum) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + rb_link_node(&pe->rb_pnum, parent, p); + rb_insert_color(&pe->rb_pnum, &ubi->prot.pnum); + + p = &ubi->prot.aec.rb_node; + parent = NULL; + while (*p) { + parent = *p; + pe1 = rb_entry(parent, struct ubi_wl_prot_entry, rb_aec); + + if (pe->abs_ec < pe1->abs_ec) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + rb_link_node(&pe->rb_aec, parent, p); + rb_insert_color(&pe->rb_aec, &ubi->prot.aec); +} + +/** + * find_wl_entry - find wear-leveling entry closest to certain erase counter. + * @root: the RB-tree where to look for + * @max: highest possible erase counter + * + * This function looks for a wear leveling entry with erase counter closest to + * @max and less then @max. + */ +static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int max) +{ + struct rb_node *p; + struct ubi_wl_entry *e; + + e = rb_entry(rb_first(root), struct ubi_wl_entry, rb); + max += e->ec; + + p = root->rb_node; + while (p) { + struct ubi_wl_entry *e1; + + e1 = rb_entry(p, struct ubi_wl_entry, rb); + if (e1->ec >= max) + p = p->rb_left; + else { + p = p->rb_right; + e = e1; + } + } + + return e; +} + +/** + * ubi_wl_get_peb - get a physical eraseblock. + * @ubi: UBI device description object + * @dtype: type of data which will be stored in this physical eraseblock + * + * This function returns a physical eraseblock in case of success and a + * negative error code in case of failure. Might sleep. + */ +int ubi_wl_get_peb(struct ubi_device *ubi, int dtype) +{ + int err, protect, medium_ec; + struct ubi_wl_entry *e, *first, *last; + struct ubi_wl_prot_entry *pe; + + ubi_assert(dtype == UBI_LONGTERM || dtype == UBI_SHORTTERM || + dtype == UBI_UNKNOWN); + + pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); + if (!pe) + return -ENOMEM; + +retry: + spin_lock(&ubi->wl_lock); + if (!ubi->free.rb_node) { + if (ubi->works_count == 0) { + ubi_assert(list_empty(&ubi->works)); + ubi_err("no free eraseblocks"); + spin_unlock(&ubi->wl_lock); + kfree(pe); + return -ENOSPC; + } + spin_unlock(&ubi->wl_lock); + + err = produce_free_peb(ubi); + if (err < 0) { + kfree(pe); + return err; + } + goto retry; + } + + switch (dtype) { + case UBI_LONGTERM: + /* + * For long term data we pick a physical eraseblock + * with high erase counter. But the highest erase + * counter we can pick is bounded by the the lowest + * erase counter plus %WL_FREE_MAX_DIFF. + */ + e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + protect = LT_PROTECTION; + break; + case UBI_UNKNOWN: + /* + * For unknown data we pick a physical eraseblock with + * medium erase counter. But we by no means can pick a + * physical eraseblock with erase counter greater or + * equivalent than the lowest erase counter plus + * %WL_FREE_MAX_DIFF. + */ + first = rb_entry(rb_first(&ubi->free), + struct ubi_wl_entry, rb); + last = rb_entry(rb_last(&ubi->free), + struct ubi_wl_entry, rb); + + if (last->ec - first->ec < WL_FREE_MAX_DIFF) + e = rb_entry(ubi->free.rb_node, + struct ubi_wl_entry, rb); + else { + medium_ec = (first->ec + WL_FREE_MAX_DIFF)/2; + e = find_wl_entry(&ubi->free, medium_ec); + } + protect = U_PROTECTION; + break; + case UBI_SHORTTERM: + /* + * For short term data we pick a physical eraseblock + * with the lowest erase counter as we expect it will + * be erased soon. + */ + e = rb_entry(rb_first(&ubi->free), + struct ubi_wl_entry, rb); + protect = ST_PROTECTION; + break; + default: + protect = 0; + e = NULL; + BUG(); + } + + /* + * Move the physical eraseblock to the protection trees where it will + * be protected from being moved for some time. + */ + paranoid_check_in_wl_tree(e, &ubi->free); + rb_erase(&e->rb, &ubi->free); + prot_tree_add(ubi, e, pe, protect); + + dbg_wl("PEB %d EC %d, protection %d", e->pnum, e->ec, protect); + spin_unlock(&ubi->wl_lock); + + return e->pnum; +} + +/** + * prot_tree_del - remove a physical eraseblock from the protection trees + * @ubi: UBI device description object + * @pnum: the physical eraseblock to remove + * + * This function returns PEB @pnum from the protection trees and returns zero + * in case of success and %-ENODEV if the PEB was not found in the protection + * trees. + */ +static int prot_tree_del(struct ubi_device *ubi, int pnum) +{ + struct rb_node *p; + struct ubi_wl_prot_entry *pe = NULL; + + p = ubi->prot.pnum.rb_node; + while (p) { + + pe = rb_entry(p, struct ubi_wl_prot_entry, rb_pnum); + + if (pnum == pe->e->pnum) + goto found; + + if (pnum < pe->e->pnum) + p = p->rb_left; + else + p = p->rb_right; + } + + return -ENODEV; + +found: + ubi_assert(pe->e->pnum == pnum); + rb_erase(&pe->rb_aec, &ubi->prot.aec); + rb_erase(&pe->rb_pnum, &ubi->prot.pnum); + kfree(pe); + return 0; +} + +/** + * sync_erase - synchronously erase a physical eraseblock. + * @ubi: UBI device description object + * @e: the the physical eraseblock to erase + * @torture: if the physical eraseblock has to be tortured + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, int torture) +{ + int err; + struct ubi_ec_hdr *ec_hdr; + unsigned long long ec = e->ec; + + dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec); + + err = paranoid_check_ec(ubi, e->pnum, e->ec); + if (err > 0) + return -EINVAL; + + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); + if (!ec_hdr) + return -ENOMEM; + + err = ubi_io_sync_erase(ubi, e->pnum, torture); + if (err < 0) + goto out_free; + + ec += err; + if (ec > UBI_MAX_ERASECOUNTER) { + /* + * Erase counter overflow. Upgrade UBI and use 64-bit + * erase counters internally. + */ + ubi_err("erase counter overflow at PEB %d, EC %llu", + e->pnum, ec); + err = -EINVAL; + goto out_free; + } + + dbg_wl("erased PEB %d, new EC %llu", e->pnum, ec); + + ec_hdr->ec = cpu_to_be64(ec); + + err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr); + if (err) + goto out_free; + + e->ec = ec; + spin_lock(&ubi->wl_lock); + if (e->ec > ubi->max_ec) + ubi->max_ec = e->ec; + spin_unlock(&ubi->wl_lock); + +out_free: + kfree(ec_hdr); + return err; +} + +/** + * check_protection_over - check if it is time to stop protecting some + * physical eraseblocks. + * @ubi: UBI device description object + * + * This function is called after each erase operation, when the absolute erase + * counter is incremented, to check if some physical eraseblock have not to be + * protected any longer. These physical eraseblocks are moved from the + * protection trees to the used tree. + */ +static void check_protection_over(struct ubi_device *ubi) +{ + struct ubi_wl_prot_entry *pe; + + /* + * There may be several protected physical eraseblock to remove, + * process them all. + */ + while (1) { + spin_lock(&ubi->wl_lock); + if (!ubi->prot.aec.rb_node) { + spin_unlock(&ubi->wl_lock); + break; + } + + pe = rb_entry(rb_first(&ubi->prot.aec), + struct ubi_wl_prot_entry, rb_aec); + + if (pe->abs_ec > ubi->abs_ec) { + spin_unlock(&ubi->wl_lock); + break; + } + + dbg_wl("PEB %d protection over, abs_ec %llu, PEB abs_ec %llu", + pe->e->pnum, ubi->abs_ec, pe->abs_ec); + rb_erase(&pe->rb_aec, &ubi->prot.aec); + rb_erase(&pe->rb_pnum, &ubi->prot.pnum); + wl_tree_add(pe->e, &ubi->used); + spin_unlock(&ubi->wl_lock); + + kfree(pe); + cond_resched(); + } +} + +/** + * schedule_ubi_work - schedule a work. + * @ubi: UBI device description object + * @wrk: the work to schedule + * + * This function enqueues a work defined by @wrk to the tail of the pending + * works list. + */ +static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk) +{ + spin_lock(&ubi->wl_lock); + list_add_tail(&wrk->list, &ubi->works); + ubi_assert(ubi->works_count >= 0); + ubi->works_count += 1; + if (ubi->thread_enabled) + wake_up_process(ubi->bgt_thread); + spin_unlock(&ubi->wl_lock); +} + +static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, + int cancel); + +/** + * schedule_erase - schedule an erase work. + * @ubi: UBI device description object + * @e: the WL entry of the physical eraseblock to erase + * @torture: if the physical eraseblock has to be tortured + * + * This function returns zero in case of success and a %-ENOMEM in case of + * failure. + */ +static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, + int torture) +{ + struct ubi_work *wl_wrk; + + dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", + e->pnum, e->ec, torture); + + wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + if (!wl_wrk) + return -ENOMEM; + + wl_wrk->func = &erase_worker; + wl_wrk->e = e; + wl_wrk->torture = torture; + + schedule_ubi_work(ubi, wl_wrk); + return 0; +} + +/** + * wear_leveling_worker - wear-leveling worker function. + * @ubi: UBI device description object + * @wrk: the work object + * @cancel: non-zero if the worker has to free memory and exit + * + * This function copies a more worn out physical eraseblock to a less worn out + * one. Returns zero in case of success and a negative error code in case of + * failure. + */ +static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, + int cancel) +{ + int err, put = 0, scrubbing = 0, protect = 0; + struct ubi_wl_prot_entry *uninitialized_var(pe); + struct ubi_wl_entry *e1, *e2; + struct ubi_vid_hdr *vid_hdr; + + kfree(wrk); + + if (cancel) + return 0; + + vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); + if (!vid_hdr) + return -ENOMEM; + + mutex_lock(&ubi->move_mutex); + spin_lock(&ubi->wl_lock); + ubi_assert(!ubi->move_from && !ubi->move_to); + ubi_assert(!ubi->move_to_put); + + if (!ubi->free.rb_node || + (!ubi->used.rb_node && !ubi->scrub.rb_node)) { + /* + * No free physical eraseblocks? Well, they must be waiting in + * the queue to be erased. Cancel movement - it will be + * triggered again when a free physical eraseblock appears. + * + * No used physical eraseblocks? They must be temporarily + * protected from being moved. They will be moved to the + * @ubi->used tree later and the wear-leveling will be + * triggered again. + */ + dbg_wl("cancel WL, a list is empty: free %d, used %d", + !ubi->free.rb_node, !ubi->used.rb_node); + goto out_cancel; + } + + if (!ubi->scrub.rb_node) { + /* + * Now pick the least worn-out used physical eraseblock and a + * highly worn-out free physical eraseblock. If the erase + * counters differ much enough, start wear-leveling. + */ + e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); + e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + + if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { + dbg_wl("no WL needed: min used EC %d, max free EC %d", + e1->ec, e2->ec); + goto out_cancel; + } + paranoid_check_in_wl_tree(e1, &ubi->used); + rb_erase(&e1->rb, &ubi->used); + dbg_wl("move PEB %d EC %d to PEB %d EC %d", + e1->pnum, e1->ec, e2->pnum, e2->ec); + } else { + /* Perform scrubbing */ + scrubbing = 1; + e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, rb); + e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + paranoid_check_in_wl_tree(e1, &ubi->scrub); + rb_erase(&e1->rb, &ubi->scrub); + dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum); + } + + paranoid_check_in_wl_tree(e2, &ubi->free); + rb_erase(&e2->rb, &ubi->free); + ubi->move_from = e1; + ubi->move_to = e2; + spin_unlock(&ubi->wl_lock); + + /* + * Now we are going to copy physical eraseblock @e1->pnum to @e2->pnum. + * We so far do not know which logical eraseblock our physical + * eraseblock (@e1) belongs to. We have to read the volume identifier + * header first. + * + * Note, we are protected from this PEB being unmapped and erased. The + * 'ubi_wl_put_peb()' would wait for moving to be finished if the PEB + * which is being moved was unmapped. + */ + + err = ubi_io_read_vid_hdr(ubi, e1->pnum, vid_hdr, 0); + if (err && err != UBI_IO_BITFLIPS) { + if (err == UBI_IO_PEB_FREE) { + /* + * We are trying to move PEB without a VID header. UBI + * always write VID headers shortly after the PEB was + * given, so we have a situation when it did not have + * chance to write it down because it was preempted. + * Just re-schedule the work, so that next time it will + * likely have the VID header in place. + */ + dbg_wl("PEB %d has no VID header", e1->pnum); + goto out_not_moved; + } + + ubi_err("error %d while reading VID header from PEB %d", + err, e1->pnum); + if (err > 0) + err = -EIO; + goto out_error; + } + + err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); + if (err) { + + if (err < 0) + goto out_error; + if (err == 1) + goto out_not_moved; + + /* + * For some reason the LEB was not moved - it might be because + * the volume is being deleted. We should prevent this PEB from + * being selected for wear-levelling movement for some "time", + * so put it to the protection tree. + */ + + dbg_wl("cancelled moving PEB %d", e1->pnum); + pe = kmalloc(sizeof(struct ubi_wl_prot_entry), GFP_NOFS); + if (!pe) { + err = -ENOMEM; + goto out_error; + } + + protect = 1; + } + + ubi_free_vid_hdr(ubi, vid_hdr); + spin_lock(&ubi->wl_lock); + if (protect) + prot_tree_add(ubi, e1, pe, protect); + if (!ubi->move_to_put) + wl_tree_add(e2, &ubi->used); + else + put = 1; + ubi->move_from = ubi->move_to = NULL; + ubi->move_to_put = ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); + + if (put) { + /* + * Well, the target PEB was put meanwhile, schedule it for + * erasure. + */ + dbg_wl("PEB %d was put meanwhile, erase", e2->pnum); + err = schedule_erase(ubi, e2, 0); + if (err) + goto out_error; + } + + if (!protect) { + err = schedule_erase(ubi, e1, 0); + if (err) + goto out_error; + } + + + dbg_wl("done"); + mutex_unlock(&ubi->move_mutex); + return 0; + + /* + * For some reasons the LEB was not moved, might be an error, might be + * something else. @e1 was not changed, so return it back. @e2 might + * be changed, schedule it for erasure. + */ +out_not_moved: + ubi_free_vid_hdr(ubi, vid_hdr); + spin_lock(&ubi->wl_lock); + if (scrubbing) + wl_tree_add(e1, &ubi->scrub); + else + wl_tree_add(e1, &ubi->used); + ubi->move_from = ubi->move_to = NULL; + ubi->move_to_put = ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); + + err = schedule_erase(ubi, e2, 0); + if (err) + goto out_error; + + mutex_unlock(&ubi->move_mutex); + return 0; + +out_error: + ubi_err("error %d while moving PEB %d to PEB %d", + err, e1->pnum, e2->pnum); + + ubi_free_vid_hdr(ubi, vid_hdr); + spin_lock(&ubi->wl_lock); + ubi->move_from = ubi->move_to = NULL; + ubi->move_to_put = ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); + + kmem_cache_free(ubi_wl_entry_slab, e1); + kmem_cache_free(ubi_wl_entry_slab, e2); + ubi_ro_mode(ubi); + + mutex_unlock(&ubi->move_mutex); + return err; + +out_cancel: + ubi->wl_scheduled = 0; + spin_unlock(&ubi->wl_lock); + mutex_unlock(&ubi->move_mutex); + ubi_free_vid_hdr(ubi, vid_hdr); + return 0; +} + +/** + * ensure_wear_leveling - schedule wear-leveling if it is needed. + * @ubi: UBI device description object + * + * This function checks if it is time to start wear-leveling and schedules it + * if yes. This function returns zero in case of success and a negative error + * code in case of failure. + */ +static int ensure_wear_leveling(struct ubi_device *ubi) +{ + int err = 0; + struct ubi_wl_entry *e1; + struct ubi_wl_entry *e2; + struct ubi_work *wrk; + + spin_lock(&ubi->wl_lock); + if (ubi->wl_scheduled) + /* Wear-leveling is already in the work queue */ + goto out_unlock; + + /* + * If the ubi->scrub tree is not empty, scrubbing is needed, and the + * the WL worker has to be scheduled anyway. + */ + if (!ubi->scrub.rb_node) { + if (!ubi->used.rb_node || !ubi->free.rb_node) + /* No physical eraseblocks - no deal */ + goto out_unlock; + + /* + * We schedule wear-leveling only if the difference between the + * lowest erase counter of used physical eraseblocks and a high + * erase counter of free physical eraseblocks is greater then + * %UBI_WL_THRESHOLD. + */ + e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, rb); + e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF); + + if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) + goto out_unlock; + dbg_wl("schedule wear-leveling"); + } else + dbg_wl("schedule scrubbing"); + + ubi->wl_scheduled = 1; + spin_unlock(&ubi->wl_lock); + + wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + if (!wrk) { + err = -ENOMEM; + goto out_cancel; + } + + wrk->func = &wear_leveling_worker; + schedule_ubi_work(ubi, wrk); + return err; + +out_cancel: + spin_lock(&ubi->wl_lock); + ubi->wl_scheduled = 0; +out_unlock: + spin_unlock(&ubi->wl_lock); + return err; +} + +/** + * erase_worker - physical eraseblock erase worker function. + * @ubi: UBI device description object + * @wl_wrk: the work object + * @cancel: non-zero if the worker has to free memory and exit + * + * This function erases a physical eraseblock and perform torture testing if + * needed. It also takes care about marking the physical eraseblock bad if + * needed. Returns zero in case of success and a negative error code in case of + * failure. + */ +static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, + int cancel) +{ + struct ubi_wl_entry *e = wl_wrk->e; + int pnum = e->pnum, err, need; + + if (cancel) { + dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); + kfree(wl_wrk); + kmem_cache_free(ubi_wl_entry_slab, e); + return 0; + } + + dbg_wl("erase PEB %d EC %d", pnum, e->ec); + + err = sync_erase(ubi, e, wl_wrk->torture); + if (!err) { + /* Fine, we've erased it successfully */ + kfree(wl_wrk); + + spin_lock(&ubi->wl_lock); + ubi->abs_ec += 1; + wl_tree_add(e, &ubi->free); + spin_unlock(&ubi->wl_lock); + + /* + * One more erase operation has happened, take care about protected + * physical eraseblocks. + */ + check_protection_over(ubi); + + /* And take care about wear-leveling */ + err = ensure_wear_leveling(ubi); + return err; + } + + ubi_err("failed to erase PEB %d, error %d", pnum, err); + kfree(wl_wrk); + kmem_cache_free(ubi_wl_entry_slab, e); + + if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || + err == -EBUSY) { + int err1; + + /* Re-schedule the LEB for erasure */ + err1 = schedule_erase(ubi, e, 0); + if (err1) { + err = err1; + goto out_ro; + } + return err; + } else if (err != -EIO) { + /* + * If this is not %-EIO, we have no idea what to do. Scheduling + * this physical eraseblock for erasure again would cause + * errors again and again. Well, lets switch to RO mode. + */ + goto out_ro; + } + + /* It is %-EIO, the PEB went bad */ + + if (!ubi->bad_allowed) { + ubi_err("bad physical eraseblock %d detected", pnum); + goto out_ro; + } + + spin_lock(&ubi->volumes_lock); + need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1; + if (need > 0) { + need = ubi->avail_pebs >= need ? need : ubi->avail_pebs; + ubi->avail_pebs -= need; + ubi->rsvd_pebs += need; + ubi->beb_rsvd_pebs += need; + if (need > 0) + ubi_msg("reserve more %d PEBs", need); + } + + if (ubi->beb_rsvd_pebs == 0) { + spin_unlock(&ubi->volumes_lock); + ubi_err("no reserved physical eraseblocks"); + goto out_ro; + } + + spin_unlock(&ubi->volumes_lock); + ubi_msg("mark PEB %d as bad", pnum); + + err = ubi_io_mark_bad(ubi, pnum); + if (err) + goto out_ro; + + spin_lock(&ubi->volumes_lock); + ubi->beb_rsvd_pebs -= 1; + ubi->bad_peb_count += 1; + ubi->good_peb_count -= 1; + ubi_calculate_reserved(ubi); + if (ubi->beb_rsvd_pebs == 0) + ubi_warn("last PEB from the reserved pool was used"); + spin_unlock(&ubi->volumes_lock); + + return err; + +out_ro: + ubi_ro_mode(ubi); + return err; +} + +/** + * ubi_wl_put_peb - return a physical eraseblock to the wear-leveling unit. + * @ubi: UBI device description object + * @pnum: physical eraseblock to return + * @torture: if this physical eraseblock has to be tortured + * + * This function is called to return physical eraseblock @pnum to the pool of + * free physical eraseblocks. The @torture flag has to be set if an I/O error + * occurred to this @pnum and it has to be tested. This function returns zero + * in case of success, and a negative error code in case of failure. + */ +int ubi_wl_put_peb(struct ubi_device *ubi, int pnum, int torture) +{ + int err; + struct ubi_wl_entry *e; + + dbg_wl("PEB %d", pnum); + ubi_assert(pnum >= 0); + ubi_assert(pnum < ubi->peb_count); + +retry: + spin_lock(&ubi->wl_lock); + e = ubi->lookuptbl[pnum]; + if (e == ubi->move_from) { + /* + * User is putting the physical eraseblock which was selected to + * be moved. It will be scheduled for erasure in the + * wear-leveling worker. + */ + dbg_wl("PEB %d is being moved, wait", pnum); + spin_unlock(&ubi->wl_lock); + + /* Wait for the WL worker by taking the @ubi->move_mutex */ + mutex_lock(&ubi->move_mutex); + mutex_unlock(&ubi->move_mutex); + goto retry; + } else if (e == ubi->move_to) { + /* + * User is putting the physical eraseblock which was selected + * as the target the data is moved to. It may happen if the EBA + * unit already re-mapped the LEB in 'ubi_eba_copy_leb()' but + * the WL unit has not put the PEB to the "used" tree yet, but + * it is about to do this. So we just set a flag which will + * tell the WL worker that the PEB is not needed anymore and + * should be scheduled for erasure. + */ + dbg_wl("PEB %d is the target of data moving", pnum); + ubi_assert(!ubi->move_to_put); + ubi->move_to_put = 1; + spin_unlock(&ubi->wl_lock); + return 0; + } else { + if (in_wl_tree(e, &ubi->used)) { + paranoid_check_in_wl_tree(e, &ubi->used); + rb_erase(&e->rb, &ubi->used); + } else if (in_wl_tree(e, &ubi->scrub)) { + paranoid_check_in_wl_tree(e, &ubi->scrub); + rb_erase(&e->rb, &ubi->scrub); + } else { + err = prot_tree_del(ubi, e->pnum); + if (err) { + ubi_err("PEB %d not found", pnum); + ubi_ro_mode(ubi); + spin_unlock(&ubi->wl_lock); + return err; + } + } + } + spin_unlock(&ubi->wl_lock); + + err = schedule_erase(ubi, e, torture); + if (err) { + spin_lock(&ubi->wl_lock); + wl_tree_add(e, &ubi->used); + spin_unlock(&ubi->wl_lock); + } + + return err; +} + +/** + * ubi_wl_scrub_peb - schedule a physical eraseblock for scrubbing. + * @ubi: UBI device description object + * @pnum: the physical eraseblock to schedule + * + * If a bit-flip in a physical eraseblock is detected, this physical eraseblock + * needs scrubbing. This function schedules a physical eraseblock for + * scrubbing which is done in background. This function returns zero in case of + * success and a negative error code in case of failure. + */ +int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) +{ + struct ubi_wl_entry *e; + + ubi_msg("schedule PEB %d for scrubbing", pnum); + +retry: + spin_lock(&ubi->wl_lock); + e = ubi->lookuptbl[pnum]; + if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub)) { + spin_unlock(&ubi->wl_lock); + return 0; + } + + if (e == ubi->move_to) { + /* + * This physical eraseblock was used to move data to. The data + * was moved but the PEB was not yet inserted to the proper + * tree. We should just wait a little and let the WL worker + * proceed. + */ + spin_unlock(&ubi->wl_lock); + dbg_wl("the PEB %d is not in proper tree, retry", pnum); + yield(); + goto retry; + } + + if (in_wl_tree(e, &ubi->used)) { + paranoid_check_in_wl_tree(e, &ubi->used); + rb_erase(&e->rb, &ubi->used); + } else { + int err; + + err = prot_tree_del(ubi, e->pnum); + if (err) { + ubi_err("PEB %d not found", pnum); + ubi_ro_mode(ubi); + spin_unlock(&ubi->wl_lock); + return err; + } + } + + wl_tree_add(e, &ubi->scrub); + spin_unlock(&ubi->wl_lock); + + /* + * Technically scrubbing is the same as wear-leveling, so it is done + * by the WL worker. + */ + return ensure_wear_leveling(ubi); +} + +/** + * ubi_wl_flush - flush all pending works. + * @ubi: UBI device description object + * + * This function returns zero in case of success and a negative error code in + * case of failure. + */ +int ubi_wl_flush(struct ubi_device *ubi) +{ + int err; + + /* + * Erase while the pending works queue is not empty, but not more then + * the number of currently pending works. + */ + dbg_wl("flush (%d pending works)", ubi->works_count); + while (ubi->works_count) { + err = do_work(ubi); + if (err) + return err; + } + + /* + * Make sure all the works which have been done in parallel are + * finished. + */ + down_write(&ubi->work_sem); + up_write(&ubi->work_sem); + + /* + * And in case last was the WL worker and it cancelled the LEB + * movement, flush again. + */ + while (ubi->works_count) { + dbg_wl("flush more (%d pending works)", ubi->works_count); + err = do_work(ubi); + if (err) + return err; + } + + return 0; +} + +/** + * tree_destroy - destroy an RB-tree. + * @root: the root of the tree to destroy + */ +static void tree_destroy(struct rb_root *root) +{ + struct rb_node *rb; + struct ubi_wl_entry *e; + + rb = root->rb_node; + while (rb) { + if (rb->rb_left) + rb = rb->rb_left; + else if (rb->rb_right) + rb = rb->rb_right; + else { + e = rb_entry(rb, struct ubi_wl_entry, rb); + + rb = rb_parent(rb); + if (rb) { + if (rb->rb_left == &e->rb) + rb->rb_left = NULL; + else + rb->rb_right = NULL; + } + + kmem_cache_free(ubi_wl_entry_slab, e); + } + } +} + +/** + * ubi_thread - UBI background thread. + * @u: the UBI device description object pointer + */ +int ubi_thread(void *u) +{ + int failures = 0; + struct ubi_device *ubi = u; + + ubi_msg("background thread \"%s\" started, PID %d", + ubi->bgt_name, task_pid_nr(current)); + + set_freezable(); + for (;;) { + int err; + + if (kthread_should_stop()) + break; + + if (try_to_freeze()) + continue; + + spin_lock(&ubi->wl_lock); + if (list_empty(&ubi->works) || ubi->ro_mode || + !ubi->thread_enabled) { + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock(&ubi->wl_lock); + schedule(); + continue; + } + spin_unlock(&ubi->wl_lock); + + err = do_work(ubi); + if (err) { + ubi_err("%s: work failed with error code %d", + ubi->bgt_name, err); + if (failures++ > WL_MAX_FAILURES) { + /* + * Too many failures, disable the thread and + * switch to read-only mode. + */ + ubi_msg("%s: %d consecutive failures", + ubi->bgt_name, WL_MAX_FAILURES); + ubi_ro_mode(ubi); + break; + } + } else + failures = 0; + + cond_resched(); + } + + dbg_wl("background thread \"%s\" is killed", ubi->bgt_name); + return 0; +} + +/** + * cancel_pending - cancel all pending works. + * @ubi: UBI device description object + */ +static void cancel_pending(struct ubi_device *ubi) +{ + while (!list_empty(&ubi->works)) { + struct ubi_work *wrk; + + wrk = list_entry(ubi->works.next, struct ubi_work, list); + list_del(&wrk->list); + wrk->func(ubi, wrk, 1); + ubi->works_count -= 1; + ubi_assert(ubi->works_count >= 0); + } +} + +/** + * ubi_wl_init_scan - initialize the wear-leveling unit using scanning + * information. + * @ubi: UBI device description object + * @si: scanning information + * + * This function returns zero in case of success, and a negative error code in + * case of failure. + */ +int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) +{ + int err; + struct rb_node *rb1, *rb2; + struct ubi_scan_volume *sv; + struct ubi_scan_leb *seb, *tmp; + struct ubi_wl_entry *e; + + + ubi->used = ubi->free = ubi->scrub = RB_ROOT; + ubi->prot.pnum = ubi->prot.aec = RB_ROOT; + spin_lock_init(&ubi->wl_lock); + mutex_init(&ubi->move_mutex); + init_rwsem(&ubi->work_sem); + ubi->max_ec = si->max_ec; + INIT_LIST_HEAD(&ubi->works); + + sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num); + + err = -ENOMEM; + ubi->lookuptbl = kzalloc(ubi->peb_count * sizeof(void *), GFP_KERNEL); + if (!ubi->lookuptbl) + return err; + + list_for_each_entry_safe(seb, tmp, &si->erase, u.list) { + cond_resched(); + + e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); + if (!e) + goto out_free; + + e->pnum = seb->pnum; + e->ec = seb->ec; + ubi->lookuptbl[e->pnum] = e; + if (schedule_erase(ubi, e, 0)) { + kmem_cache_free(ubi_wl_entry_slab, e); + goto out_free; + } + } + + list_for_each_entry(seb, &si->free, u.list) { + cond_resched(); + + e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); + if (!e) + goto out_free; + + e->pnum = seb->pnum; + e->ec = seb->ec; + ubi_assert(e->ec >= 0); + wl_tree_add(e, &ubi->free); + ubi->lookuptbl[e->pnum] = e; + } + + list_for_each_entry(seb, &si->corr, u.list) { + cond_resched(); + + e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); + if (!e) + goto out_free; + + e->pnum = seb->pnum; + e->ec = seb->ec; + ubi->lookuptbl[e->pnum] = e; + if (schedule_erase(ubi, e, 0)) { + kmem_cache_free(ubi_wl_entry_slab, e); + goto out_free; + } + } + + ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { + ubi_rb_for_each_entry(rb2, seb, &sv->root, u.rb) { + cond_resched(); + + e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL); + if (!e) + goto out_free; + + e->pnum = seb->pnum; + e->ec = seb->ec; + ubi->lookuptbl[e->pnum] = e; + if (!seb->scrub) { + dbg_wl("add PEB %d EC %d to the used tree", + e->pnum, e->ec); + wl_tree_add(e, &ubi->used); + } else { + dbg_wl("add PEB %d EC %d to the scrub tree", + e->pnum, e->ec); + wl_tree_add(e, &ubi->scrub); + } + } + } + + if (ubi->avail_pebs < WL_RESERVED_PEBS) { + ubi_err("no enough physical eraseblocks (%d, need %d)", + ubi->avail_pebs, WL_RESERVED_PEBS); + goto out_free; + } + ubi->avail_pebs -= WL_RESERVED_PEBS; + ubi->rsvd_pebs += WL_RESERVED_PEBS; + + /* Schedule wear-leveling if needed */ + err = ensure_wear_leveling(ubi); + if (err) + goto out_free; + + return 0; + +out_free: + cancel_pending(ubi); + tree_destroy(&ubi->used); + tree_destroy(&ubi->free); + tree_destroy(&ubi->scrub); + kfree(ubi->lookuptbl); + return err; +} + +/** + * protection_trees_destroy - destroy the protection RB-trees. + * @ubi: UBI device description object + */ +static void protection_trees_destroy(struct ubi_device *ubi) +{ + struct rb_node *rb; + struct ubi_wl_prot_entry *pe; + + rb = ubi->prot.aec.rb_node; + while (rb) { + if (rb->rb_left) + rb = rb->rb_left; + else if (rb->rb_right) + rb = rb->rb_right; + else { + pe = rb_entry(rb, struct ubi_wl_prot_entry, rb_aec); + + rb = rb_parent(rb); + if (rb) { + if (rb->rb_left == &pe->rb_aec) + rb->rb_left = NULL; + else + rb->rb_right = NULL; + } + + kmem_cache_free(ubi_wl_entry_slab, pe->e); + kfree(pe); + } + } +} + +/** + * ubi_wl_close - close the wear-leveling unit. + * @ubi: UBI device description object + */ +void ubi_wl_close(struct ubi_device *ubi) +{ + dbg_wl("close the UBI wear-leveling unit"); + + cancel_pending(ubi); + protection_trees_destroy(ubi); + tree_destroy(&ubi->used); + tree_destroy(&ubi->free); + tree_destroy(&ubi->scrub); + kfree(ubi->lookuptbl); +} + +#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID + +/** + * paranoid_check_ec - make sure that the erase counter of a physical eraseblock + * is correct. + * @ubi: UBI device description object + * @pnum: the physical eraseblock number to check + * @ec: the erase counter to check + * + * This function returns zero if the erase counter of physical eraseblock @pnum + * is equivalent to @ec, %1 if not, and a negative error code if an error + * occurred. + */ +static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) +{ + int err; + long long read_ec; + struct ubi_ec_hdr *ec_hdr; + + ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); + if (!ec_hdr) + return -ENOMEM; + + err = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0); + if (err && err != UBI_IO_BITFLIPS) { + /* The header does not have to exist */ + err = 0; + goto out_free; + } + + read_ec = be64_to_cpu(ec_hdr->ec); + if (ec != read_ec) { + ubi_err("paranoid check failed for PEB %d", pnum); + ubi_err("read EC is %lld, should be %d", read_ec, ec); + ubi_dbg_dump_stack(); + err = 1; + } else + err = 0; + +out_free: + kfree(ec_hdr); + return err; +} + +/** + * paranoid_check_in_wl_tree - make sure that a wear-leveling entry is present + * in a WL RB-tree. + * @e: the wear-leveling entry to check + * @root: the root of the tree + * + * This function returns zero if @e is in the @root RB-tree and %1 if it + * is not. + */ +static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, + struct rb_root *root) +{ + if (in_wl_tree(e, root)) + return 0; + + ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ", + e->pnum, e->ec, root); + ubi_dbg_dump_stack(); + return 1; +} + +#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ -- cgit v1.1 From 7e6ee7ad27de5216db1baef76f38c3429c8f4a2a Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:32:36 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 6/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- include/exports.h | 1 + include/jffs2/load_kernel.h | 5 + include/linux/crc32.h | 27 +++++ include/linux/mtd/partitions.h | 84 ++++++++++++++++ include/linux/types.h | 24 +++++ include/ubi_uboot.h | 217 +++++++++++++++++++++++++++++++++++++++++ lib_generic/vsprintf.c | 23 +++++ 7 files changed, 381 insertions(+) create mode 100644 include/linux/crc32.h create mode 100644 include/linux/mtd/partitions.h create mode 100644 include/ubi_uboot.h diff --git a/include/exports.h b/include/exports.h index 6377875..0620e9e 100644 --- a/include/exports.h +++ b/include/exports.h @@ -25,6 +25,7 @@ char *getenv (char *name); int setenv (char *varname, char *varvalue); long simple_strtol(const char *cp,char **endp,unsigned int base); int strcmp(const char * cs,const char * ct); +int ustrtoul(const char *cp, char **endp, unsigned int base); #ifdef CONFIG_HAS_UID void forceenv (char *varname, char *varvalue); #endif diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h index 551fd0c..e9b7d6e 100644 --- a/include/jffs2/load_kernel.h +++ b/include/jffs2/load_kernel.h @@ -73,4 +73,9 @@ struct mtdids { #define putLabeledWord(x, y) printf("%s %08x\n", x, (unsigned int)y) #define led_blink(x, y, z, a) +/* common/cmd_jffs2.c */ +extern int mtdparts_init(void); +extern int find_dev_and_part(const char *id, struct mtd_device **dev, + u8 *part_num, struct part_info **part); + #endif /* load_kernel_h */ diff --git a/include/linux/crc32.h b/include/linux/crc32.h new file mode 100644 index 0000000..e133157 --- /dev/null +++ b/include/linux/crc32.h @@ -0,0 +1,27 @@ +/* + * crc32.h + * See linux/lib/crc32.c for license and changes + */ +#ifndef _LINUX_CRC32_H +#define _LINUX_CRC32_H + +#include +//#include + +extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); +//extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); + +#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length) + +/* + * Helpers for hash table generation of ethernet nics: + * + * Ethernet sends the least significant bit of a byte first, thus crc32_le + * is used. The output of crc32_le is bit reversed [most significant bit + * is in bit nr 0], thus it must be reversed before use. Except for + * nics that bit swap the result internally... + */ +//#define ether_crc(length, data) bitrev32(crc32_le(~0, data, length)) +//#define ether_crc_le(length, data) crc32_le(~0, data, length) + +#endif /* _LINUX_CRC32_H */ diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h new file mode 100644 index 0000000..b41e5f5 --- /dev/null +++ b/include/linux/mtd/partitions.h @@ -0,0 +1,84 @@ +/* + * MTD partitioning layer definitions + * + * (C) 2000 Nicolas Pitre + * + * This code is GPL + * + * $Id: partitions.h,v 1.17 2005/11/07 11:14:55 gleixner Exp $ + */ + +#ifndef MTD_PARTITIONS_H +#define MTD_PARTITIONS_H + +#include + + +/* + * Partition definition structure: + * + * An array of struct partition is passed along with a MTD object to + * add_mtd_partitions() to create them. + * + * For each partition, these fields are available: + * name: string that will be used to label the partition's MTD device. + * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition + * will extend to the end of the master MTD device. + * offset: absolute starting position within the master MTD device; if + * defined as MTDPART_OFS_APPEND, the partition will start where the + * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. + * mask_flags: contains flags that have to be masked (removed) from the + * master MTD flag set for the corresponding MTD partition. + * For example, to force a read-only partition, simply adding + * MTD_WRITEABLE to the mask_flags will do the trick. + * + * Note: writeable partitions require their size and offset be + * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). + */ + +struct mtd_partition { + char *name; /* identifier string */ + u_int32_t size; /* partition size */ + u_int32_t offset; /* offset within the master MTD space */ + u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ + struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ + struct mtd_info **mtdp; /* pointer to store the MTD object */ +}; + +#define MTDPART_OFS_NXTBLK (-2) +#define MTDPART_OFS_APPEND (-1) +#define MTDPART_SIZ_FULL (0) + + +int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); +int del_mtd_partitions(struct mtd_info *); + +#if 0 +/* + * Functions dealing with the various ways of partitioning the space + */ + +struct mtd_part_parser { + struct list_head list; + struct module *owner; + const char *name; + int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); +}; + +extern int register_mtd_parser(struct mtd_part_parser *parser); +extern int deregister_mtd_parser(struct mtd_part_parser *parser); +extern int parse_mtd_partitions(struct mtd_info *master, const char **types, + struct mtd_partition **pparts, unsigned long origin); + +#define put_partition_parser(p) do { module_put((p)->owner); } while(0) + +struct device; +struct device_node; + +int __devinit of_mtd_parse_partitions(struct device *dev, + struct mtd_info *mtd, + struct device_node *node, + struct mtd_partition **pparts); +#endif + +#endif diff --git a/include/linux/types.h b/include/linux/types.h index df4808f..1b0b4a4 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -119,6 +119,30 @@ typedef __s64 int64_t; * Below are truly Linux-specific types that should never collide with * any application/library that wants linux/types.h. */ +#ifdef __CHECKER__ +#define __bitwise__ __attribute__((bitwise)) +#else +#define __bitwise__ +#endif +#ifdef __CHECK_ENDIAN__ +#define __bitwise __bitwise__ +#else +#define __bitwise +#endif + +typedef __u16 __bitwise __le16; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __le32; +typedef __u32 __bitwise __be32; +#if defined(__GNUC__) +typedef __u64 __bitwise __le64; +typedef __u64 __bitwise __be64; +#endif +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __wsum; + + +typedef unsigned __bitwise__ gfp_t; struct ustat { __kernel_daddr_t f_tfree; diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h new file mode 100644 index 0000000..295f2c0 --- /dev/null +++ b/include/ubi_uboot.h @@ -0,0 +1,217 @@ +/* + * Header file for UBI support for U-Boot + * + * Adaptation from kernel to U-Boot + * + * Copyright (C) 2005-2007 Samsung Electronics + * Kyungmin Park + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __UBOOT_UBI_H +#define __UBOOT_UBI_H + +#include +#include +#include +#include +#include + +#ifdef CONFIG_CMD_ONENAND +#include +#endif + +#include + +#define DPRINTK(format, args...) \ +do { \ + printf("%s[%d]: " format "\n", __func__, __LINE__, ##args); \ +} while (0) + +/* configurable */ +#define CONFIG_MTD_UBI_WL_THRESHOLD 4096 +#define CONFIG_MTD_UBI_BEB_RESERVE 1 +#define UBI_IO_DEBUG 0 + +/* debug options (Linux: drivers/mtd/ubi/Kconfig.debug) */ +#undef CONFIG_MTD_UBI_DEBUG +#undef CONFIG_MTD_UBI_DEBUG_PARANOID +#undef CONFIG_MTD_UBI_DEBUG_MSG +#undef CONFIG_MTD_UBI_DEBUG_MSG_EBA +#undef CONFIG_MTD_UBI_DEBUG_MSG_WL +#undef CONFIG_MTD_UBI_DEBUG_MSG_IO +#undef CONFIG_MTD_UBI_DEBUG_MSG_BLD +#define CONFIG_MTD_UBI_DEBUG_DISABLE_BGT + +/* compiler options */ +#define uninitialized_var(x) x = x + +/* build.c */ +#define get_device(...) +#define put_device(...) +#define ubi_sysfs_init(...) 0 +#define ubi_sysfs_close(...) do { } while (0) +static inline int is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + +/* FIXME */ +#define MKDEV(...) 0 +#define MAJOR(dev) 0 +#define MINOR(dev) 0 + +#define alloc_chrdev_region(...) 0 +#define unregister_chrdev_region(...) + +#define class_create(...) __builtin_return_address(0) +#define class_create_file(...) 0 +#define class_remove_file(...) +#define class_destroy(...) +#define misc_register(...) 0 +#define misc_deregister(...) + +/* vmt.c */ +#define device_register(...) 0 +#define volume_sysfs_init(...) 0 +#define volume_sysfs_close(...) do { } while (0) + +/* kapi.c */ + +/* eba.c */ + +/* io.c */ +#define init_waitqueue_head(...) do { } while (0) +#define wait_event_interruptible(...) 0 +#define wake_up_interruptible(...) do { } while (0) +#define print_hex_dump(...) do { } while (0) +#define dump_stack(...) do { } while (0) + +/* wl.c */ +#define task_pid_nr(x) 0 +#define set_freezable(...) do { } while (0) +#define try_to_freeze(...) 0 +#define set_current_state(...) do { } while (0) +#define kthread_should_stop(...) 0 +#define schedule() do { } while (0) + +/* upd.c */ +static inline unsigned long copy_from_user(void *dest, const void *src, + unsigned long count) +{ + memcpy((void *)dest, (void *)src, count); + return 0; +} + +/* common */ +typedef int spinlock_t; +typedef int wait_queue_head_t; +#define spin_lock_init(...) +#define spin_lock(...) +#define spin_unlock(...) + +#define mutex_init(...) +#define mutex_lock(...) +#define mutex_unlock(...) + +#define init_rwsem(...) do { } while (0) +#define down_read(...) do { } while (0) +#define down_write(...) do { } while (0) +#define down_write_trylock(...) 0 +#define up_read(...) do { } while (0) +#define up_write(...) do { } while (0) + +struct kmem_cache { int i; }; +#define kmem_cache_create(...) 1 +#define kmem_cache_alloc(obj, gfp) malloc(sizeof(struct ubi_wl_entry)) +#define kmem_cache_free(obj, size) free(size) +#define kmem_cache_destroy(...) + +#define cond_resched() do { } while (0) +#define yield() do { } while (0) + +#define KERN_WARNING +#define KERN_ERR +#define KERN_NOTICE +#define KERN_DEBUG + +#define GFP_KERNEL 0 +#define GFP_NOFS 1 + +#define __user +#define __init +#define __exit + +#define kthread_create(...) __builtin_return_address(0) +#define kthread_stop(...) do { } while (0) +#define wake_up_process(...) do { } while (0) + +#define BUS_ID_SIZE 20 + +struct rw_semaphore { int i; }; +struct device { + struct device *parent; + struct class *class; + char bus_id[BUS_ID_SIZE]; /* position on parent bus */ + dev_t devt; /* dev_t, creates the sysfs "dev" */ + void (*release)(struct device *dev); +}; +struct mutex { int i; }; +struct kernel_param { int i; }; + +struct cdev { + int owner; + dev_t dev; +}; +#define cdev_init(...) do { } while (0) +#define cdev_add(...) 0 +#define cdev_del(...) do { } while (0) + +#define MAX_ERRNO 4095 +#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO) + +static inline void *ERR_PTR(long error) +{ + return (void *) error; +} + +static inline long PTR_ERR(const void *ptr) +{ + return (long) ptr; +} + +static inline long IS_ERR(const void *ptr) +{ + return IS_ERR_VALUE((unsigned long)ptr); +} + +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) + +/* module */ +#define THIS_MODULE 0 +#define try_module_get(...) 0 +#define module_put(...) do { } while (0) +#define module_init(...) +#define module_exit(...) +#define EXPORT_SYMBOL(...) +#define EXPORT_SYMBOL_GPL(...) +#define module_param_call(...) +#define MODULE_PARM_DESC(...) +#define MODULE_VERSION(...) +#define MODULE_DESCRIPTION(...) +#define MODULE_AUTHOR(...) +#define MODULE_LICENSE(...) + +#include "../drivers/mtd/ubi/ubi.h" + +/* functions */ +extern int ubi_mtd_param_parse(const char *val, struct kernel_param *kp); +extern int ubi_init(void); + +extern struct ubi_device *ubi_devices[]; + +#endif diff --git a/lib_generic/vsprintf.c b/lib_generic/vsprintf.c index 6e903db..767dde1 100644 --- a/lib_generic/vsprintf.c +++ b/lib_generic/vsprintf.c @@ -55,6 +55,29 @@ long simple_strtol(const char *cp,char **endp,unsigned int base) return simple_strtoul(cp,endp,base); } +int ustrtoul(const char *cp, char **endp, unsigned int base) +{ + unsigned long result = simple_strtoul(cp, endp, base); + switch (**endp) { + case 'G' : + result *= 1024; + /* fall through */ + case 'M': + result *= 1024; + /* fall through */ + case 'K': + case 'k': + result *= 1024; + if ((*endp)[1] == 'i') { + if ((*endp)[2] == 'B') + (*endp) += 3; + else + (*endp) += 2; + } + } + return result; +} + #ifdef CONFIG_SYS_64BIT_STRTOUL unsigned long long simple_strtoull (const char *cp, char **endp, unsigned int base) { -- cgit v1.1 From 47ae6693f54f80455ae32c2e0d995e0e4bdc15b9 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:36:36 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 7/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- include/linux/mtd/ubi.h | 186 +++++++++++++++++++++++++++++++++ include/mtd/ubi-user.h | 268 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 454 insertions(+) create mode 100644 include/linux/mtd/ubi.h create mode 100644 include/mtd/ubi-user.h diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h new file mode 100644 index 0000000..a017891 --- /dev/null +++ b/include/linux/mtd/ubi.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __LINUX_UBI_H__ +#define __LINUX_UBI_H__ + +//#include +#include +#include + +/* + * enum ubi_open_mode - UBI volume open mode constants. + * + * UBI_READONLY: read-only mode + * UBI_READWRITE: read-write mode + * UBI_EXCLUSIVE: exclusive mode + */ +enum { + UBI_READONLY = 1, + UBI_READWRITE, + UBI_EXCLUSIVE +}; + +/** + * struct ubi_volume_info - UBI volume description data structure. + * @vol_id: volume ID + * @ubi_num: UBI device number this volume belongs to + * @size: how many physical eraseblocks are reserved for this volume + * @used_bytes: how many bytes of data this volume contains + * @used_ebs: how many physical eraseblocks of this volume actually contain any + * data + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @corrupted: non-zero if the volume is corrupted (static volumes only) + * @upd_marker: non-zero if the volume has update marker set + * @alignment: volume alignment + * @usable_leb_size: how many bytes are available in logical eraseblocks of + * this volume + * @name_len: volume name length + * @name: volume name + * @cdev: UBI volume character device major and minor numbers + * + * The @corrupted flag is only relevant to static volumes and is always zero + * for dynamic ones. This is because UBI does not care about dynamic volume + * data protection and only cares about protecting static volume data. + * + * The @upd_marker flag is set if the volume update operation was interrupted. + * Before touching the volume data during the update operation, UBI first sets + * the update marker flag for this volume. If the volume update operation was + * further interrupted, the update marker indicates this. If the update marker + * is set, the contents of the volume is certainly damaged and a new volume + * update operation has to be started. + * + * To put it differently, @corrupted and @upd_marker fields have different + * semantics: + * o the @corrupted flag means that this static volume is corrupted for some + * reasons, but not because an interrupted volume update + * o the @upd_marker field means that the volume is damaged because of an + * interrupted update operation. + * + * I.e., the @corrupted flag is never set if the @upd_marker flag is set. + * + * The @used_bytes and @used_ebs fields are only really needed for static + * volumes and contain the number of bytes stored in this static volume and how + * many eraseblock this data occupies. In case of dynamic volumes, the + * @used_bytes field is equivalent to @size*@usable_leb_size, and the @used_ebs + * field is equivalent to @size. + * + * In general, logical eraseblock size is a property of the UBI device, not + * of the UBI volume. Indeed, the logical eraseblock size depends on the + * physical eraseblock size and on how much bytes UBI headers consume. But + * because of the volume alignment (@alignment), the usable size of logical + * eraseblocks if a volume may be less. The following equation is true: + * @usable_leb_size = LEB size - (LEB size mod @alignment), + * where LEB size is the logical eraseblock size defined by the UBI device. + * + * The alignment is multiple to the minimal flash input/output unit size or %1 + * if all the available space is used. + * + * To put this differently, alignment may be considered is a way to change + * volume logical eraseblock sizes. + */ +struct ubi_volume_info { + int ubi_num; + int vol_id; + int size; + long long used_bytes; + int used_ebs; + int vol_type; + int corrupted; + int upd_marker; + int alignment; + int usable_leb_size; + int name_len; + const char *name; + dev_t cdev; +}; + +/** + * struct ubi_device_info - UBI device description data structure. + * @ubi_num: ubi device number + * @leb_size: logical eraseblock size on this UBI device + * @min_io_size: minimal I/O unit size + * @ro_mode: if this device is in read-only mode + * @cdev: UBI character device major and minor numbers + * + * Note, @leb_size is the logical eraseblock size offered by the UBI device. + * Volumes of this UBI device may have smaller logical eraseblock size if their + * alignment is not equivalent to %1. + */ +struct ubi_device_info { + int ubi_num; + int leb_size; + int min_io_size; + int ro_mode; + dev_t cdev; +}; + +/* UBI descriptor given to users when they open UBI volumes */ +struct ubi_volume_desc; + +int ubi_get_device_info(int ubi_num, struct ubi_device_info *di); +void ubi_get_volume_info(struct ubi_volume_desc *desc, + struct ubi_volume_info *vi); +struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode); +struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, + int mode); +void ubi_close_volume(struct ubi_volume_desc *desc); +int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, + int len, int check); +int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, + int offset, int len, int dtype); +int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, + int len, int dtype); +int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum); +int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum); +int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype); +int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum); + +/* + * This function is the same as the 'ubi_leb_read()' function, but it does not + * provide the checking capability. + */ +static inline int ubi_read(struct ubi_volume_desc *desc, int lnum, char *buf, + int offset, int len) +{ + return ubi_leb_read(desc, lnum, buf, offset, len, 0); +} + +/* + * This function is the same as the 'ubi_leb_write()' functions, but it does + * not have the data type argument. + */ +static inline int ubi_write(struct ubi_volume_desc *desc, int lnum, + const void *buf, int offset, int len) +{ + return ubi_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN); +} + +/* + * This function is the same as the 'ubi_leb_change()' functions, but it does + * not have the data type argument. + */ +static inline int ubi_change(struct ubi_volume_desc *desc, int lnum, + const void *buf, int len) +{ + return ubi_leb_change(desc, lnum, buf, len, UBI_UNKNOWN); +} + +#endif /* !__LINUX_UBI_H__ */ diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h new file mode 100644 index 0000000..a7421f1 --- /dev/null +++ b/include/mtd/ubi-user.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __UBI_USER_H__ +#define __UBI_USER_H__ + +/* + * UBI device creation (the same as MTD device attachment) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * MTD devices may be attached using %UBI_IOCATT ioctl command of the UBI + * control device. The caller has to properly fill and pass + * &struct ubi_attach_req object - UBI will attach the MTD device specified in + * the request and return the newly created UBI device number as the ioctl + * return value. + * + * UBI device deletion (the same as MTD device detachment) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * An UBI device maybe deleted with %UBI_IOCDET ioctl command of the UBI + * control device. + * + * UBI volume creation + * ~~~~~~~~~~~~~~~~~~~ + * + * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * device. A &struct ubi_mkvol_req object has to be properly filled and a + * pointer to it has to be passed to the IOCTL. + * + * UBI volume deletion + * ~~~~~~~~~~~~~~~~~~~ + * + * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * device should be used. A pointer to the 32-bit volume ID hast to be passed + * to the IOCTL. + * + * UBI volume re-size + * ~~~~~~~~~~~~~~~~~~ + * + * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * device should be used. A &struct ubi_rsvol_req object has to be properly + * filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volume update + * ~~~~~~~~~~~~~~~~~ + * + * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * corresponding UBI volume character device. A pointer to a 64-bit update + * size should be passed to the IOCTL. After this, UBI expects user to write + * this number of bytes to the volume character device. The update is finished + * when the claimed number of bytes is passed. So, the volume update sequence + * is something like: + * + * fd = open("/dev/my_volume"); + * ioctl(fd, UBI_IOCVOLUP, &image_size); + * write(fd, buf, image_size); + * close(fd); + * + * Atomic eraseblock change + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL + * command of the corresponding UBI volume character device. A pointer to + * &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is + * expected to write the requested amount of bytes. This is similar to the + * "volume update" IOCTL. + */ + +/* + * When a new UBI volume or UBI device is created, users may either specify the + * volume/device number they want to create or to let UBI automatically assign + * the number using these constants. + */ +#define UBI_VOL_NUM_AUTO (-1) +#define UBI_DEV_NUM_AUTO (-1) + +/* Maximum volume name length */ +#define UBI_MAX_VOLUME_NAME 127 + +/* IOCTL commands of UBI character devices */ + +#define UBI_IOC_MAGIC 'o' + +/* Create an UBI volume */ +#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) +/* Remove an UBI volume */ +#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) +/* Re-size an UBI volume */ +#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) + +/* IOCTL commands of the UBI control character device */ + +#define UBI_CTRL_IOC_MAGIC 'o' + +/* Attach an MTD device */ +#define UBI_IOCATT _IOW(UBI_CTRL_IOC_MAGIC, 64, struct ubi_attach_req) +/* Detach an MTD device */ +#define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t) + +/* IOCTL commands of UBI volume character devices */ + +#define UBI_VOL_IOC_MAGIC 'O' + +/* Start UBI volume update */ +#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) +/* An eraseblock erasure command, used for debugging, disabled by default */ +#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) +/* An atomic eraseblock change command */ +#define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) + +/* Maximum MTD device name length supported by UBI */ +#define MAX_UBI_MTD_NAME_LEN 127 + +/* + * UBI data type hint constants. + * + * UBI_LONGTERM: long-term data + * UBI_SHORTTERM: short-term data + * UBI_UNKNOWN: data persistence is unknown + * + * These constants are used when data is written to UBI volumes in order to + * help the UBI wear-leveling unit to find more appropriate physical + * eraseblocks. + */ +enum { + UBI_LONGTERM = 1, + UBI_SHORTTERM = 2, + UBI_UNKNOWN = 3, +}; + +/* + * UBI volume type constants. + * + * @UBI_DYNAMIC_VOLUME: dynamic volume + * @UBI_STATIC_VOLUME: static volume + */ +enum { + UBI_DYNAMIC_VOLUME = 3, + UBI_STATIC_VOLUME = 4, +}; + +/** + * struct ubi_attach_req - attach MTD device request. + * @ubi_num: UBI device number to create + * @mtd_num: MTD device number to attach + * @vid_hdr_offset: VID header offset (use defaults if %0) + * @padding: reserved for future, not used, has to be zeroed + * + * This data structure is used to specify MTD device UBI has to attach and the + * parameters it has to use. The number which should be assigned to the new UBI + * device is passed in @ubi_num. UBI may automatically assign the number if + * @UBI_DEV_NUM_AUTO is passed. In this case, the device number is returned in + * @ubi_num. + * + * Most applications should pass %0 in @vid_hdr_offset to make UBI use default + * offset of the VID header within physical eraseblocks. The default offset is + * the next min. I/O unit after the EC header. For example, it will be offset + * 512 in case of a 512 bytes page NAND flash with no sub-page support. Or + * it will be 512 in case of a 2KiB page NAND flash with 4 512-byte sub-pages. + * + * But in rare cases, if this optimizes things, the VID header may be placed to + * a different offset. For example, the boot-loader might do things faster if the + * VID header sits at the end of the first 2KiB NAND page with 4 sub-pages. As + * the boot-loader would not normally need to read EC headers (unless it needs + * UBI in RW mode), it might be faster to calculate ECC. This is weird example, + * but it real-life example. So, in this example, @vid_hdr_offer would be + * 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes + * aligned, which is OK, as UBI is clever enough to realize this is 4th sub-page + * of the first page and add needed padding. + */ +struct ubi_attach_req { + int32_t ubi_num; + int32_t mtd_num; + int32_t vid_hdr_offset; + uint8_t padding[12]; +}; + +/** + * struct ubi_mkvol_req - volume description data structure used in + * volume creation requests. + * @vol_id: volume number + * @alignment: volume alignment + * @bytes: volume size in bytes + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @padding1: reserved for future, not used, has to be zeroed + * @name_len: volume name length + * @padding2: reserved for future, not used, has to be zeroed + * @name: volume name + * + * This structure is used by user-space programs when creating new volumes. The + * @used_bytes field is only necessary when creating static volumes. + * + * The @alignment field specifies the required alignment of the volume logical + * eraseblock. This means, that the size of logical eraseblocks will be aligned + * to this number, i.e., + * (UBI device logical eraseblock size) mod (@alignment) = 0. + * + * To put it differently, the logical eraseblock of this volume may be slightly + * shortened in order to make it properly aligned. The alignment has to be + * multiple of the flash minimal input/output unit, or %1 to utilize the entire + * available space of logical eraseblocks. + * + * The @alignment field may be useful, for example, when one wants to maintain + * a block device on top of an UBI volume. In this case, it is desirable to fit + * an integer number of blocks in logical eraseblocks of this UBI volume. With + * alignment it is possible to update this volume using plane UBI volume image + * BLOBs, without caring about how to properly align them. + */ +struct ubi_mkvol_req { + int32_t vol_id; + int32_t alignment; + int64_t bytes; + int8_t vol_type; + int8_t padding1; + int16_t name_len; + int8_t padding2[4]; + char name[UBI_MAX_VOLUME_NAME + 1]; +} __attribute__ ((packed)); + +/** + * struct ubi_rsvol_req - a data structure used in volume re-size requests. + * @vol_id: ID of the volume to re-size + * @bytes: new size of the volume in bytes + * + * Re-sizing is possible for both dynamic and static volumes. But while dynamic + * volumes may be re-sized arbitrarily, static volumes cannot be made to be + * smaller then the number of bytes they bear. To arbitrarily shrink a static + * volume, it must be wiped out first (by means of volume update operation with + * zero number of bytes). + */ +struct ubi_rsvol_req { + int64_t bytes; + int32_t vol_id; +} __attribute__ ((packed)); + +/** + * struct ubi_leb_change_req - a data structure used in atomic logical + * eraseblock change requests. + * @lnum: logical eraseblock number to change + * @bytes: how many bytes will be written to the logical eraseblock + * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) + * @padding: reserved for future, not used, has to be zeroed + */ +struct ubi_leb_change_req { + int32_t lnum; + int32_t bytes; + uint8_t dtype; + uint8_t padding[7]; +} __attribute__ ((packed)); + +#endif /* __UBI_USER_H__ */ -- cgit v1.1 From 58be3a1056d88c6d05f3e914389282807e69923a Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:38:24 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 8/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- Makefile | 1 + include/linux/mtd/ubi-header.h | 360 ----------------------------------------- include/linux/mtd/ubi-user.h | 161 ------------------ 3 files changed, 1 insertion(+), 521 deletions(-) delete mode 100644 include/linux/mtd/ubi-header.h delete mode 100644 include/linux/mtd/ubi-user.h diff --git a/Makefile b/Makefile index fd521b6..befb608 100644 --- a/Makefile +++ b/Makefile @@ -230,6 +230,7 @@ LIBS += drivers/mtd/libmtd.a LIBS += drivers/mtd/nand/libnand.a LIBS += drivers/mtd/nand_legacy/libnand_legacy.a LIBS += drivers/mtd/onenand/libonenand.a +LIBS += drivers/mtd/ubi/libubi.a LIBS += drivers/mtd/spi/libspi_flash.a LIBS += drivers/net/libnet.a LIBS += drivers/net/phy/libphy.a diff --git a/include/linux/mtd/ubi-header.h b/include/linux/mtd/ubi-header.h deleted file mode 100644 index fa479c7..0000000 --- a/include/linux/mtd/ubi-header.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: Artem Bityutskiy (Битюцкий Артём) - * Thomas Gleixner - * Frank Haverkamp - * Oliver Lohmann - * Andreas Arnez - */ - -/* - * This file defines the layout of UBI headers and all the other UBI on-flash - * data structures. May be included by user-space. - */ - -#ifndef __UBI_HEADER_H__ -#define __UBI_HEADER_H__ - -#include - -/* The version of UBI images supported by this implementation */ -#define UBI_VERSION 1 - -/* The highest erase counter value supported by this implementation */ -#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF - -/* The initial CRC32 value used when calculating CRC checksums */ -#define UBI_CRC32_INIT 0xFFFFFFFFU - -/* Erase counter header magic number (ASCII "UBI#") */ -#define UBI_EC_HDR_MAGIC 0x55424923 -/* Volume identifier header magic number (ASCII "UBI!") */ -#define UBI_VID_HDR_MAGIC 0x55424921 - -/* - * Volume type constants used in the volume identifier header. - * - * @UBI_VID_DYNAMIC: dynamic volume - * @UBI_VID_STATIC: static volume - */ -enum { - UBI_VID_DYNAMIC = 1, - UBI_VID_STATIC = 2 -}; - -/* - * Compatibility constants used by internal volumes. - * - * @UBI_COMPAT_DELETE: delete this internal volume before anything is written - * to the flash - * @UBI_COMPAT_RO: attach this device in read-only mode - * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its - * physical eraseblocks, don't allow the wear-leveling unit to move them - * @UBI_COMPAT_REJECT: reject this UBI image - */ -enum { - UBI_COMPAT_DELETE = 1, - UBI_COMPAT_RO = 2, - UBI_COMPAT_PRESERVE = 4, - UBI_COMPAT_REJECT = 5 -}; - -/* - * ubi16_t/ubi32_t/ubi64_t - 16, 32, and 64-bit integers used in UBI on-flash - * data structures. - */ -typedef struct { - uint16_t int16; -} __attribute__ ((packed)) ubi16_t; - -typedef struct { - uint32_t int32; -} __attribute__ ((packed)) ubi32_t; - -typedef struct { - uint64_t int64; -} __attribute__ ((packed)) ubi64_t; - -/* - * In this implementation of UBI uses the big-endian format for on-flash - * integers. The below are the corresponding conversion macros. - */ -#define cpu_to_ubi16(x) ((ubi16_t){__cpu_to_be16(x)}) -#define ubi16_to_cpu(x) ((uint16_t)__be16_to_cpu((x).int16)) - -#define cpu_to_ubi32(x) ((ubi32_t){__cpu_to_be32(x)}) -#define ubi32_to_cpu(x) ((uint32_t)__be32_to_cpu((x).int32)) - -#define cpu_to_ubi64(x) ((ubi64_t){__cpu_to_be64(x)}) -#define ubi64_to_cpu(x) ((uint64_t)__be64_to_cpu((x).int64)) - -/* Sizes of UBI headers */ -#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr) -#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) - -/* Sizes of UBI headers without the ending CRC */ -#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(ubi32_t)) -#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(ubi32_t)) - -/** - * struct ubi_ec_hdr - UBI erase counter header. - * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) - * @version: version of UBI implementation which is supposed to accept this - * UBI image - * @padding1: reserved for future, zeroes - * @ec: the erase counter - * @vid_hdr_offset: where the VID header starts - * @data_offset: where the user data start - * @padding2: reserved for future, zeroes - * @hdr_crc: erase counter header CRC checksum - * - * The erase counter header takes 64 bytes and has a plenty of unused space for - * future usage. The unused fields are zeroed. The @version field is used to - * indicate the version of UBI implementation which is supposed to be able to - * work with this UBI image. If @version is greater then the current UBI - * version, the image is rejected. This may be useful in future if something - * is changed radically. This field is duplicated in the volume identifier - * header. - * - * The @vid_hdr_offset and @data_offset fields contain the offset of the the - * volume identifier header and user data, relative to the beginning of the - * physical eraseblock. These values have to be the same for all physical - * eraseblocks. - */ -struct ubi_ec_hdr { - ubi32_t magic; - uint8_t version; - uint8_t padding1[3]; - ubi64_t ec; /* Warning: the current limit is 31-bit anyway! */ - ubi32_t vid_hdr_offset; - ubi32_t data_offset; - uint8_t padding2[36]; - ubi32_t hdr_crc; -} __attribute__ ((packed)); - -/** - * struct ubi_vid_hdr - on-flash UBI volume identifier header. - * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) - * @version: UBI implementation version which is supposed to accept this UBI - * image (%UBI_VERSION) - * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) - * @copy_flag: if this logical eraseblock was copied from another physical - * eraseblock (for wear-leveling reasons) - * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, - * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) - * @vol_id: ID of this volume - * @lnum: logical eraseblock number - * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be - * removed, kept only for not breaking older UBI users) - * @data_size: how many bytes of data this logical eraseblock contains - * @used_ebs: total number of used logical eraseblocks in this volume - * @data_pad: how many bytes at the end of this physical eraseblock are not - * used - * @data_crc: CRC checksum of the data stored in this logical eraseblock - * @padding1: reserved for future, zeroes - * @sqnum: sequence number - * @padding2: reserved for future, zeroes - * @hdr_crc: volume identifier header CRC checksum - * - * The @sqnum is the value of the global sequence counter at the time when this - * VID header was created. The global sequence counter is incremented each time - * UBI writes a new VID header to the flash, i.e. when it maps a logical - * eraseblock to a new physical eraseblock. The global sequence counter is an - * unsigned 64-bit integer and we assume it never overflows. The @sqnum - * (sequence number) is used to distinguish between older and newer versions of - * logical eraseblocks. - * - * There are 2 situations when there may be more then one physical eraseblock - * corresponding to the same logical eraseblock, i.e., having the same @vol_id - * and @lnum values in the volume identifier header. Suppose we have a logical - * eraseblock L and it is mapped to the physical eraseblock P. - * - * 1. Because UBI may erase physical eraseblocks asynchronously, the following - * situation is possible: L is asynchronously erased, so P is scheduled for - * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, - * so P1 is written to, then an unclean reboot happens. Result - there are 2 - * physical eraseblocks P and P1 corresponding to the same logical eraseblock - * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the - * flash. - * - * 2. From time to time UBI moves logical eraseblocks to other physical - * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P - * to P1, and an unclean reboot happens before P is physically erased, there - * are two physical eraseblocks P and P1 corresponding to L and UBI has to - * select one of them when the flash is attached. The @sqnum field says which - * PEB is the original (obviously P will have lower @sqnum) and the copy. But - * it is not enough to select the physical eraseblock with the higher sequence - * number, because the unclean reboot could have happen in the middle of the - * copying process, so the data in P is corrupted. It is also not enough to - * just select the physical eraseblock with lower sequence number, because the - * data there may be old (consider a case if more data was added to P1 after - * the copying). Moreover, the unclean reboot may happen when the erasure of P - * was just started, so it result in unstable P, which is "mostly" OK, but - * still has unstable bits. - * - * UBI uses the @copy_flag field to indicate that this logical eraseblock is a - * copy. UBI also calculates data CRC when the data is moved and stores it at - * the @data_crc field of the copy (P1). So when UBI needs to pick one physical - * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is - * examined. If it is cleared, the situation* is simple and the newer one is - * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC - * checksum is correct, this physical eraseblock is selected (P1). Otherwise - * the older one (P) is selected. - * - * Note, there is an obsolete @leb_ver field which was used instead of @sqnum - * in the past. But it is not used anymore and we keep it in order to be able - * to deal with old UBI images. It will be removed at some point. - * - * There are 2 sorts of volumes in UBI: user volumes and internal volumes. - * Internal volumes are not seen from outside and are used for various internal - * UBI purposes. In this implementation there is only one internal volume - the - * layout volume. Internal volumes are the main mechanism of UBI extensions. - * For example, in future one may introduce a journal internal volume. Internal - * volumes have their own reserved range of IDs. - * - * The @compat field is only used for internal volumes and contains the "degree - * of their compatibility". It is always zero for user volumes. This field - * provides a mechanism to introduce UBI extensions and to be still compatible - * with older UBI binaries. For example, if someone introduced a journal in - * future, he would probably use %UBI_COMPAT_DELETE compatibility for the - * journal volume. And in this case, older UBI binaries, which know nothing - * about the journal volume, would just delete this volume and work perfectly - * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image - * - it just ignores the Ext3fs journal. - * - * The @data_crc field contains the CRC checksum of the contents of the logical - * eraseblock if this is a static volume. In case of dynamic volumes, it does - * not contain the CRC checksum as a rule. The only exception is when the - * data of the physical eraseblock was moved by the wear-leveling unit, then - * the wear-leveling unit calculates the data CRC and stores it in the - * @data_crc field. And of course, the @copy_flag is %in this case. - * - * The @data_size field is used only for static volumes because UBI has to know - * how many bytes of data are stored in this eraseblock. For dynamic volumes, - * this field usually contains zero. The only exception is when the data of the - * physical eraseblock was moved to another physical eraseblock for - * wear-leveling reasons. In this case, UBI calculates CRC checksum of the - * contents and uses both @data_crc and @data_size fields. In this case, the - * @data_size field contains data size. - * - * The @used_ebs field is used only for static volumes and indicates how many - * eraseblocks the data of the volume takes. For dynamic volumes this field is - * not used and always contains zero. - * - * The @data_pad is calculated when volumes are created using the alignment - * parameter. So, effectively, the @data_pad field reduces the size of logical - * eraseblocks of this volume. This is very handy when one uses block-oriented - * software (say, cramfs) on top of the UBI volume. - */ -struct ubi_vid_hdr { - ubi32_t magic; - uint8_t version; - uint8_t vol_type; - uint8_t copy_flag; - uint8_t compat; - ubi32_t vol_id; - ubi32_t lnum; - ubi32_t leb_ver; /* obsolete, to be removed, don't use */ - ubi32_t data_size; - ubi32_t used_ebs; - ubi32_t data_pad; - ubi32_t data_crc; - uint8_t padding1[4]; - ubi64_t sqnum; - uint8_t padding2[12]; - ubi32_t hdr_crc; -} __attribute__ ((packed)); - -/* Internal UBI volumes count */ -#define UBI_INT_VOL_COUNT 1 - -/* - * Starting ID of internal volumes. There is reserved room for 4096 internal - * volumes. - */ -#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) - -/* The layout volume contains the volume table */ - -#define UBI_LAYOUT_VOL_ID UBI_INTERNAL_VOL_START -#define UBI_LAYOUT_VOLUME_EBS 2 -#define UBI_LAYOUT_VOLUME_NAME "layout volume" -#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT - -/* The maximum number of volumes per one UBI device */ -#define UBI_MAX_VOLUMES 128 - -/* The maximum volume name length */ -#define UBI_VOL_NAME_MAX 127 - -/* Size of the volume table record */ -#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) - -/* Size of the volume table record without the ending CRC */ -#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(ubi32_t)) - -/** - * struct ubi_vtbl_record - a record in the volume table. - * @reserved_pebs: how many physical eraseblocks are reserved for this volume - * @alignment: volume alignment - * @data_pad: how many bytes are unused at the end of the each physical - * eraseblock to satisfy the requested alignment - * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @upd_marker: if volume update was started but not finished - * @name_len: volume name length - * @name: the volume name - * @padding2: reserved, zeroes - * @crc: a CRC32 checksum of the record - * - * The volume table records are stored in the volume table, which is stored in - * the layout volume. The layout volume consists of 2 logical eraseblock, each - * of which contains a copy of the volume table (i.e., the volume table is - * duplicated). The volume table is an array of &struct ubi_vtbl_record - * objects indexed by the volume ID. - * - * If the size of the logical eraseblock is large enough to fit - * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES - * records. Otherwise, it contains as many records as it can fit (i.e., size of - * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). - * - * The @upd_marker flag is used to implement volume update. It is set to %1 - * before update and set to %0 after the update. So if the update operation was - * interrupted, UBI knows that the volume is corrupted. - * - * The @alignment field is specified when the volume is created and cannot be - * later changed. It may be useful, for example, when a block-oriented file - * system works on top of UBI. The @data_pad field is calculated using the - * logical eraseblock size and @alignment. The alignment must be multiple to the - * minimal flash I/O unit. If @alignment is 1, all the available space of - * the physical eraseblocks is used. - * - * Empty records contain all zeroes and the CRC checksum of those zeroes. - */ -struct ubi_vtbl_record { - ubi32_t reserved_pebs; - ubi32_t alignment; - ubi32_t data_pad; - uint8_t vol_type; - uint8_t upd_marker; - ubi16_t name_len; - uint8_t name[UBI_VOL_NAME_MAX+1]; - uint8_t padding2[24]; - ubi32_t crc; -} __attribute__ ((packed)); - -#endif /* !__UBI_HEADER_H__ */ diff --git a/include/linux/mtd/ubi-user.h b/include/linux/mtd/ubi-user.h deleted file mode 100644 index fe06ded..0000000 --- a/include/linux/mtd/ubi-user.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Artem Bityutskiy (Битюцкий Артём) - */ - -#ifndef __UBI_USER_H__ -#define __UBI_USER_H__ - -/* - * UBI volume creation - * ~~~~~~~~~~~~~~~~~~~ - * - * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character - * device. A &struct ubi_mkvol_req object has to be properly filled and a - * pointer to it has to be passed to the IOCTL. - * - * UBI volume deletion - * ~~~~~~~~~~~~~~~~~~~ - * - * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character - * device should be used. A pointer to the 32-bit volume ID hast to be passed - * to the IOCTL. - * - * UBI volume re-size - * ~~~~~~~~~~~~~~~~~~ - * - * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character - * device should be used. A &struct ubi_rsvol_req object has to be properly - * filled and a pointer to it has to be passed to the IOCTL. - * - * UBI volume update - * ~~~~~~~~~~~~~~~~~ - * - * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the - * corresponding UBI volume character device. A pointer to a 64-bit update - * size should be passed to the IOCTL. After then, UBI expects user to write - * this number of bytes to the volume character device. The update is finished - * when the claimed number of bytes is passed. So, the volume update sequence - * is something like: - * - * fd = open("/dev/my_volume"); - * ioctl(fd, UBI_IOCVOLUP, &image_size); - * write(fd, buf, image_size); - * close(fd); - */ - -/* - * When a new volume is created, users may either specify the volume number they - * want to create or to let UBI automatically assign a volume number using this - * constant. - */ -#define UBI_VOL_NUM_AUTO (-1) - -/* Maximum volume name length */ -#define UBI_MAX_VOLUME_NAME 127 - -/* IOCTL commands of UBI character devices */ - -#define UBI_IOC_MAGIC 'o' - -/* Create an UBI volume */ -#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) -/* Remove an UBI volume */ -#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) -/* Re-size an UBI volume */ -#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) - -/* IOCTL commands of UBI volume character devices */ - -#define UBI_VOL_IOC_MAGIC 'O' - -/* Start UBI volume update */ -#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) -/* An eraseblock erasure command, used for debugging, disabled by default */ -#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) - -/* - * UBI volume type constants. - * - * @UBI_DYNAMIC_VOLUME: dynamic volume - * @UBI_STATIC_VOLUME: static volume - */ -enum { - UBI_DYNAMIC_VOLUME = 3, - UBI_STATIC_VOLUME = 4 -}; - -/** - * struct ubi_mkvol_req - volume description data structure used in - * volume creation requests. - * @vol_id: volume number - * @alignment: volume alignment - * @bytes: volume size in bytes - * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @padding1: reserved for future, not used - * @name_len: volume name length - * @padding2: reserved for future, not used - * @name: volume name - * - * This structure is used by userspace programs when creating new volumes. The - * @used_bytes field is only necessary when creating static volumes. - * - * The @alignment field specifies the required alignment of the volume logical - * eraseblock. This means, that the size of logical eraseblocks will be aligned - * to this number, i.e., - * (UBI device logical eraseblock size) mod (@alignment) = 0. - * - * To put it differently, the logical eraseblock of this volume may be slightly - * shortened in order to make it properly aligned. The alignment has to be - * multiple of the flash minimal input/output unit, or %1 to utilize the entire - * available space of logical eraseblocks. - * - * The @alignment field may be useful, for example, when one wants to maintain - * a block device on top of an UBI volume. In this case, it is desirable to fit - * an integer number of blocks in logical eraseblocks of this UBI volume. With - * alignment it is possible to update this volume using plane UBI volume image - * BLOBs, without caring about how to properly align them. - */ -struct ubi_mkvol_req { - int32_t vol_id; - int32_t alignment; - int64_t bytes; - int8_t vol_type; - int8_t padding1; - int16_t name_len; - int8_t padding2[4]; - char name[UBI_MAX_VOLUME_NAME+1]; -} __attribute__ ((packed)); - -/** - * struct ubi_rsvol_req - a data structure used in volume re-size requests. - * @vol_id: ID of the volume to re-size - * @bytes: new size of the volume in bytes - * - * Re-sizing is possible for both dynamic and static volumes. But while dynamic - * volumes may be re-sized arbitrarily, static volumes cannot be made to be - * smaller then the number of bytes they bear. To arbitrarily shrink a static - * volume, it must be wiped out first (by means of volume update operation with - * zero number of bytes). - */ -struct ubi_rsvol_req { - int64_t bytes; - int32_t vol_id; -} __attribute__ ((packed)); - -#endif /* __UBI_USER_H__ */ -- cgit v1.1 From 694a0b3f1c0accd0de94b89555155d69f8022824 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 11:47:05 +0100 Subject: UBI: Add UBI command support This patch adds these UBI commands: ubi part [nand|onenand] [part] - Show or set current partition ubi info [l[ayout]] -Display volume and UBI layout information ubi create[vol] volume [size] [type] - Create volume name with size ubi write[vol] address volume size - Write volume from address with size ubi read[vol] address volume [size] - Read volume to address with size ubi remove[vol] volume - Remove volume Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- common/Makefile | 1 + common/cmd_ubi.c | 628 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 629 insertions(+) create mode 100644 common/cmd_ubi.c diff --git a/common/Makefile b/common/Makefile index 6484b23..9dec4ec 100644 --- a/common/Makefile +++ b/common/Makefile @@ -139,6 +139,7 @@ COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o +COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o ifdef CONFIG_CMD_USB COBJS-y += cmd_usb.o diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c new file mode 100644 index 0000000..a5c5064 --- /dev/null +++ b/common/cmd_ubi.c @@ -0,0 +1,628 @@ +/* + * Unsorted Block Image commands + * + * Copyright (C) 2008 Samsung Electronics + * Kyungmin Park + * + * Copyright 2008 Stefan Roese , DENX Software Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DEV_TYPE_NONE 0 +#define DEV_TYPE_NAND 1 +#define DEV_TYPE_ONENAND 2 + +/* Private own data */ +static struct ubi_device *ubi; + +struct selected_dev { + char dev_name[32]; /* NAND/OneNAND etc */ + char part_name[80]; + int type; + int nr; + struct mtd_info *mtd_info; +}; + +static struct selected_dev ubi_dev; + +static void ubi_dump_vol_info(const struct ubi_volume *vol) +{ + ubi_msg("volume information dump:"); + ubi_msg("vol_id %d", vol->vol_id); + ubi_msg("reserved_pebs %d", vol->reserved_pebs); + ubi_msg("alignment %d", vol->alignment); + ubi_msg("data_pad %d", vol->data_pad); + ubi_msg("vol_type %d", vol->vol_type); + ubi_msg("name_len %d", vol->name_len); + ubi_msg("usable_leb_size %d", vol->usable_leb_size); + ubi_msg("used_ebs %d", vol->used_ebs); + ubi_msg("used_bytes %lld", vol->used_bytes); + ubi_msg("last_eb_bytes %d", vol->last_eb_bytes); + ubi_msg("corrupted %d", vol->corrupted); + ubi_msg("upd_marker %d", vol->upd_marker); + + if (vol->name_len <= UBI_VOL_NAME_MAX && + strnlen(vol->name, vol->name_len + 1) == vol->name_len) { + ubi_msg("name %s", vol->name); + } else { + ubi_msg("the 1st 5 characters of the name: %c%c%c%c%c", + vol->name[0], vol->name[1], vol->name[2], + vol->name[3], vol->name[4]); + } + printf("\n"); +} + +static void display_volume_info(struct ubi_device *ubi) +{ + int i; + + for (i = 0; i < (ubi->vtbl_slots + 1); i++) { + if (!ubi->volumes[i]) + continue; /* Empty record */ + ubi_dump_vol_info(ubi->volumes[i]); + } +} + +static void display_ubi_info(struct ubi_device *ubi) +{ + ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); + ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); + ubi_msg("physical eraseblock size: %d bytes (%d KiB)", + ubi->peb_size, ubi->peb_size >> 10); + ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); + ubi_msg("number of good PEBs: %d", ubi->good_peb_count); + ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); + ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); + ubi_msg("VID header offset: %d (aligned %d)", + ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); + ubi_msg("data offset: %d", ubi->leb_start); + ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); + ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); + ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); + ubi_msg("number of user volumes: %d", + ubi->vol_count - UBI_INT_VOL_COUNT); + ubi_msg("available PEBs: %d", ubi->avail_pebs); + ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); + ubi_msg("number of PEBs reserved for bad PEB handling: %d", + ubi->beb_rsvd_pebs); + ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); +} + +static int ubi_info(int layout) +{ + if (layout) + display_volume_info(ubi); + else + display_ubi_info(ubi); + + return 0; +} + +static int parse_num(size_t *num, const char *token) +{ + char *endp; + size_t n; + + n = (size_t) ustrtoul(token, &endp, 0); + if (*endp) + return -EINVAL; + + *num = n; + return 0; +} + +static int verify_mkvol_req(const struct ubi_device *ubi, + const struct ubi_mkvol_req *req) +{ + int n, err = -EINVAL; + + if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 || + req->name_len < 0) + goto bad; + + if ((req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots) && + req->vol_id != UBI_VOL_NUM_AUTO) + goto bad; + + if (req->alignment == 0) + goto bad; + + if (req->bytes == 0) + goto bad; + + if (req->vol_type != UBI_DYNAMIC_VOLUME && + req->vol_type != UBI_STATIC_VOLUME) + goto bad; + + if (req->alignment > ubi->leb_size) + goto bad; + + n = req->alignment % ubi->min_io_size; + if (req->alignment != 1 && n) + goto bad; + + if (req->name_len > UBI_VOL_NAME_MAX) { + err = -ENAMETOOLONG; + goto bad; + } + + return 0; +bad: + printf("bad volume creation request"); + return err; +} + +static int ubi_create_vol(char *volume, int size, int dynamic) +{ + struct ubi_mkvol_req req; + int err; + + if (dynamic) + req.vol_type = UBI_DYNAMIC_VOLUME; + else + req.vol_type = UBI_STATIC_VOLUME; + + req.vol_id = UBI_VOL_NUM_AUTO; + req.alignment = 1; + req.bytes = size; + + strcpy(req.name, volume); + req.name_len = strlen(volume); + req.name[req.name_len] = '\0'; + req.padding1 = 0; + /* It's duplicated at drivers/mtd/ubi/cdev.c */ + err = verify_mkvol_req(ubi, &req); + if (err) { + printf("verify_mkvol_req failed %d\n", err); + return err; + } + printf("Creating %s volume %s of size %d\n", + dynamic ? "dynamic" : "static", volume, size); + /* Call real ubi create volume */ + return ubi_create_volume(ubi, &req); +} + +static int ubi_remove_vol(char *volume) +{ + int i, err, reserved_pebs; + int found = 0, vol_id = 0; + struct ubi_volume *vol; + + for (i = 0; i < ubi->vtbl_slots; i++) { + vol = ubi->volumes[i]; + if (vol && !strcmp(vol->name, volume)) { + printf("Volume %s found at valid %d\n", volume, i); + vol_id = i; + found = 1; + break; + } + } + if (!found) { + printf("%s volume not found\n", volume); + return -ENODEV; + } + printf("remove UBI volume %s (id %d)\n", vol->name, vol->vol_id); + + if (ubi->ro_mode) { + printf("It's read-only mode\n"); + err = -EROFS; + goto out_err; + } + + err = ubi_change_vtbl_record(ubi, vol_id, NULL); + if (err) { + printf("Error changing Vol tabel record err=%x\n", err); + goto out_err; + } + reserved_pebs = vol->reserved_pebs; + for (i = 0; i < vol->reserved_pebs; i++) { + err = ubi_eba_unmap_leb(ubi, vol, i); + if (err) + goto out_err; + } + + kfree(vol->eba_tbl); + ubi->volumes[vol_id]->eba_tbl = NULL; + ubi->volumes[vol_id] = NULL; + + ubi->rsvd_pebs -= reserved_pebs; + ubi->avail_pebs += reserved_pebs; + i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; + if (i > 0) { + i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; + ubi->avail_pebs -= i; + ubi->rsvd_pebs += i; + ubi->beb_rsvd_pebs += i; + if (i > 0) + ubi_msg("reserve more %d PEBs", i); + } + ubi->vol_count -= 1; + + return 0; +out_err: + ubi_err("cannot remove volume %d, error %d", vol_id, err); + return err; +} + +static int ubi_volume_write(char *volume, void *buf, size_t size) +{ + int i = 0, err = -1; + int rsvd_bytes = 0; + int found = 0; + struct ubi_volume *vol; + + for (i = 0; i < ubi->vtbl_slots; i++) { + vol = ubi->volumes[i]; + if (vol && !strcmp(vol->name, volume)) { + printf("Volume \"%s\" found at volume id %d\n", volume, i); + found = 1; + break; + } + } + if (!found) { + printf("%s volume not found\n", volume); + return 1; + } + rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad); + if (size < 0 || size > rsvd_bytes) { + printf("rsvd_bytes=%d vol->reserved_pebs=%d ubi->leb_size=%d\n", + rsvd_bytes, vol->reserved_pebs, ubi->leb_size); + printf("vol->data_pad=%d\n", vol->data_pad); + printf("Size > volume size !!\n"); + return 1; + } + + err = ubi_start_update(ubi, vol, size); + if (err < 0) { + printf("Cannot start volume update\n"); + return err; + } + + err = ubi_more_update_data(ubi, vol, buf, size); + if (err < 0) { + printf("Couldnt or partially wrote data \n"); + return err; + } + + if (err) { + size = err; + + err = ubi_check_volume(ubi, vol->vol_id); + if ( err < 0 ) + return err; + + if (err) { + ubi_warn("volume %d on UBI device %d is corrupted", + vol->vol_id, ubi->ubi_num); + vol->corrupted = 1; + } + + vol->checked = 1; + ubi_gluebi_updated(vol); + } + + return 0; +} + +static int ubi_volume_read(char *volume, char *buf, size_t size) +{ + int err, lnum, off, len, tbuf_size, i = 0; + size_t count_save = size; + void *tbuf; + unsigned long long tmp; + struct ubi_volume *vol = NULL; + loff_t offp = 0; + + for (i = 0; i < ubi->vtbl_slots; i++) { + vol = ubi->volumes[i]; + if (vol && !strcmp(vol->name, volume)) { + printf("Volume %s found at volume id %d\n", + volume, vol->vol_id); + break; + } + } + if (i == ubi->vtbl_slots) { + printf("%s volume not found\n", volume); + return 0; + } + + printf("read %i bytes from volume %d to %x(buf address)\n", + (int) size, vol->vol_id, (unsigned)buf); + + if (vol->updating) { + printf("updating"); + return -EBUSY; + } + if (vol->upd_marker) { + printf("damaged volume, update marker is set"); + return -EBADF; + } + if (offp == vol->used_bytes) + return 0; + + if (size == 0) { + printf("Read [%lu] bytes\n", (unsigned long) vol->used_bytes); + size = vol->used_bytes; + } + + if (vol->corrupted) + printf("read from corrupted volume %d", vol->vol_id); + if (offp + size > vol->used_bytes) + count_save = size = vol->used_bytes - offp; + + tbuf_size = vol->usable_leb_size; + if (size < tbuf_size) + tbuf_size = ALIGN(size, ubi->min_io_size); + tbuf = malloc(tbuf_size); + if (!tbuf) { + printf("NO MEM\n"); + return -ENOMEM; + } + len = size > tbuf_size ? tbuf_size : size; + + tmp = offp; + off = do_div(tmp, vol->usable_leb_size); + lnum = tmp; + printf("off=%d lnum=%d\n", off, lnum); + do { + if (off + len >= vol->usable_leb_size) + len = vol->usable_leb_size - off; + + err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0); + if (err) { + printf("read err %x\n", err); + break; + } + off += len; + if (off == vol->usable_leb_size) { + lnum += 1; + off -= vol->usable_leb_size; + } + + size -= len; + offp += len; + + printf("buf = %x\n", (unsigned)buf); + memcpy(buf, tbuf, len); + printf("buf[0] = %x\n", buf[0]); + + buf += len; + len = size > tbuf_size ? tbuf_size : size; + } while (size); + + free(tbuf); + return err ? err : count_save - size; +} + +static int ubi_dev_scan(struct mtd_info *info, char *ubidev) +{ + struct mtd_device *dev; + struct part_info *part; + struct mtd_partition mtd_part; + char buffer[32]; + u8 pnum; + int err; + + if (mtdparts_init() != 0) + return 1; + + if (find_dev_and_part(ubidev, &dev, &pnum, &part) != 0) + return 1; + + sprintf(buffer, "mtd=%d", pnum); + memset(&mtd_part, 0, sizeof(mtd_part)); + mtd_part.name = buffer; + mtd_part.size = part->size; + mtd_part.offset = part->offset; + add_mtd_partitions(info, &mtd_part, 1); + + err = ubi_mtd_param_parse(buffer, NULL); + if (err) { + del_mtd_partitions(info); + return err; + } + + err = ubi_init(); + if (err) { + del_mtd_partitions(info); + return err; + } + + return 0; +} + +static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ + size_t size = 0; + ulong addr = 0; + int err = 0; + + if (argc < 2) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if (strcmp(argv[1], "part") == 0) { + /* Print current partition */ + if (argc == 2) { + if (ubi_dev.type == DEV_TYPE_NONE) { + printf("Error, no UBI device/partition selected!\n"); + return 1; + } + + printf("%s Device %d: %s, partition %s\n", ubi_dev.dev_name, + ubi_dev.nr, ubi_dev.mtd_info->name, ubi_dev.part_name); + return 0; + } + + if (argc < 4) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + /* todo: get dev number for NAND... */ + ubi_dev.nr = 0; + + /* + * Check for nand|onenand selection + */ +#if defined(CONFIG_CMD_NAND) + if (strcmp(argv[2], "nand") == 0) { + strcpy(ubi_dev.dev_name, "NAND"); + ubi_dev.type = DEV_TYPE_NAND; + ubi_dev.mtd_info = &nand_info[ubi_dev.nr]; + } +#endif +#if defined(CONFIG_CMD_ONENAND) + if (strcmp(argv[2], "onenand") == 0) { + strcpy(ubi_dev.dev_name, "OneNAND"); + ubi_dev.type = DEV_TYPE_ONENAND; + ubi_dev.mtd_info = &onenand_mtd; + } +#endif + + if (ubi_dev.type == DEV_TYPE_NONE) { + printf("Error, no UBI device/partition selected!\n"); + return 1; + } + + strcpy(ubi_dev.part_name, argv[3]); + err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name); + if (err) { + printf("UBI init error %d\n", err); + return err; + } + + ubi = ubi_devices[0]; + + return 0; + } + + if ((strcmp(argv[1], "part") != 0) && (ubi_dev.type == DEV_TYPE_NONE)) { + printf("Error, no UBI device/partition selected!\n"); + return 1; + } + + if (strcmp(argv[1], "info") == 0) { + int layout = 0; + if (argc > 2 && !strncmp(argv[2], "l", 1)) + layout = 1; + return ubi_info(layout); + } + + if (strncmp(argv[1], "create", 6) == 0) { + int dynamic = 1; /* default: dynamic volume */ + + /* Use maximum available size */ + size = 0; + + /* E.g., create volume size type */ + if (argc == 5) { + if (strncmp(argv[4], "s", 1) == 0) + dynamic = 0; + else if (strncmp(argv[4], "d", 1) != 0) { + printf("Incorrect type\n"); + return 1; + } + argc--; + } + /* E.g., create volume size */ + if (argc == 4) { + err = parse_num(&size, argv[3]); + if (err) { + printf("Incorrect type\n"); + return err; + } + argc--; + } + /* Use maximum available size */ + if (!size) + size = ubi->avail_pebs * ubi->leb_size; + /* E.g., create volume */ + if (argc == 3) + return ubi_create_vol(argv[2], size, dynamic); + } + + if (strncmp(argv[1], "remove", 6) == 0) { + /* E.g., remove volume */ + if (argc == 3) + return ubi_remove_vol(argv[2]); + } + + if (strncmp(argv[1], "write", 5) == 0) { + if (argc < 5) { + printf("Please see usage\n"); + return 1; + } + + addr = simple_strtoul(argv[2], NULL, 16); + err = parse_num(&size, argv[4]); + if (err) { + printf("Please see usage\n"); + return err; + } + + return ubi_volume_write(argv[3], (void *)addr, size); + } + + if (strncmp(argv[1], "read", 4) == 0) { + size = 0; + + /* E.g., read volume size */ + if (argc == 5) { + err = parse_num(&size, argv[4]); + if (err) { + printf("Please see usage\n"); + return err; + } + argc--; + } + + /* E.g., read volume */ + if (argc == 4) { + addr = simple_strtoul(argv[2], NULL, 16); + argc--; + } + + if (argc == 3) + return ubi_volume_read(argv[3], (char *)addr, size); + } + + printf("Please see usage\n"); + return -1; +} + +U_BOOT_CMD(ubi, 6, 1, do_ubi, + "ubi - ubi commands\n", + "part [nand|onenand] [part]" + " - Show or set current partition\n" + "ubi info [l[ayout]]" + " - Display volume and ubi layout information\n" + "ubi create[vol] volume [size] [type]" + " - create volume name with size\n" + "ubi write[vol] address volume size" + " - Write volume from address with size\n" + "ubi read[vol] address volume [size]" + " - Read volume to address with size\n" + "ubi remove[vol] volume" + " - Remove volume\n" + "[Legends]\n" + " volume: charater name\n" + " size: KiB, MiB, GiB, and bytes\n" + " type: s[tatic] or d[ynamic] (default=dynamic)\n" +); -- cgit v1.1 From 8000b086b33a5a81f3f390f37e178db7956dc08b Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 24 Oct 2008 14:55:33 +0200 Subject: ARM: Add Apollon UBI support To enable UBI on Apollon you need to uncomment the CONFIG_SYS_USE_UBI macro. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- board/apollon/Makefile | 3 +- include/configs/apollon.h | 74 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/board/apollon/Makefile b/board/apollon/Makefile index 9bac9a6..f20de3c 100644 --- a/board/apollon/Makefile +++ b/board/apollon/Makefile @@ -25,9 +25,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := apollon.o mem.o sys_info.o +COBJS-y := apollon.o mem.o sys_info.o SOBJS := lowlevel_init.o +COBJS := $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) diff --git a/include/configs/apollon.h b/include/configs/apollon.h index d71ed44..dff47fc 100644 --- a/include/configs/apollon.h +++ b/include/configs/apollon.h @@ -53,6 +53,9 @@ #define CONFIG_SYS_USE_NOR 1 #endif +/* uncommnet if you want to use UBI */ +#define CONFIG_SYS_USE_UBI + #include /* get chip and board defs */ #define V_SCLK 12000000 @@ -73,8 +76,9 @@ * Size of malloc() pool */ #define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_128K) -#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for initial data */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) +/* bytes reserved for initial data */ +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* * Hardware drivers @@ -116,6 +120,13 @@ #define CONFIG_CMD_DIAG #define CONFIG_CMD_ONENAND +#ifdef CONFIG_SYS_USE_UBI +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_UBI +#define CONFIG_RBTREE +#define CONFIG_MTD_PARTITIONS +#endif + #undef CONFIG_CMD_AUTOSCRIPT #ifndef CONFIG_SYS_USE_NOR @@ -133,24 +144,39 @@ #define CONFIG_BOOTFILE "uImage" #define CONFIG_ETHADDR 00:0E:99:00:24:20 -#ifdef CONFIG_APOLLON_PLUS -# define CONFIG_BOOTARGS "root=/dev/nfs rw mem=64M console=ttyS0,115200n8 ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2" +#ifdef CONFIG_APOLLON_PLUS +#define CONFIG_SYS_MEM "mem=64M" +#else +#define CONFIG_SYS_MEM "mem=128" +#endif + +#ifdef CONFIG_SYS_USE_UBI +#define CONFIG_SYS_UBI "ubi.mtd=4" #else -# define CONFIG_BOOTARGS "root=/dev/nfs rw mem=128M console=ttyS0,115200n8 ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2" +#define CONFIG_SYS_UBI "" #endif +#define CONFIG_BOOTARGS "root=/dev/nfs rw " CONFIG_SYS_MEM \ + " console=ttyS0,115200n8" \ + " ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:" \ + "apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2 " \ + CONFIG_SYS_UBI + #define CONFIG_EXTRA_ENV_SETTINGS \ "Image=tftp 0x80008000 Image; go 0x80008000\0" \ "zImage=tftp 0x80180000 zImage; go 0x80180000\0" \ "uImage=tftp 0x80180000 uImage; bootm 0x80180000\0" \ "uboot=tftp 0x80008000 u-boot.bin; go 0x80008000\0" \ - "xloader=tftp 0x80180000 x-load.bin; cp.w 0x80180000 0x00000400 0x1000; go 0x00000400\0" \ + "xloader=tftp 0x80180000 x-load.bin; " \ + " cp.w 0x80180000 0x00000400 0x1000; go 0x00000400\0" \ "syncmode50=mw.w 0x1e442 0xc0c4; mw 0x6800a060 0xe30d1201\0" \ "syncmode=mw.w 0x1e442 0xe0f4; mw 0x6800a060 0xe30d1201\0" \ "norboot=cp32 0x18040000 0x80008000 0x200000; go 0x80008000\0" \ - "oneboot=onenand read 0x80008000 0x40000 0x200000; go 0x80008000\0"\ + "oneboot=onenand read 0x80008000 0x40000 0x200000; go 0x80008000\0" \ "onesyncboot=run syncmode oneboot\0" \ - "updateb=tftp 0x80180000 u-boot-onenand.bin; onenand erase 0x0 0x20000; onenand write 0x80180000 0x0 0x20000\0" \ + "updateb=tftp 0x80180000 u-boot-onenand.bin; " \ + " onenand erase 0x0 0x20000; onenand write 0x80180000 0x0 0x20000\0" \ + "ubi=setenv bootargs ${bootargs} ubi.mtd=4 ${mtdparts}; run uImage\0" \ "bootcmd=run uboot\0" /* @@ -164,14 +190,15 @@ /* Print Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) #define CONFIG_SYS_MAXARGS 16 /* max number of command args */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */ - -#define CONFIG_SYS_MEMTEST_START (OMAP2420_SDRC_CS0) /* memtest works on */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START (OMAP2420_SDRC_CS0) #define CONFIG_SYS_MEMTEST_END (OMAP2420_SDRC_CS0+SZ_31M) #undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */ - -#define CONFIG_SYS_LOAD_ADDR (OMAP2420_SDRC_CS0) /* default load address */ +/* default load address */ +#define CONFIG_SYS_LOAD_ADDR (OMAP2420_SDRC_CS0) /* The 2420 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) * or by 32KHz clk, or from external sig. This rate is divided by a local @@ -211,13 +238,15 @@ # define CONFIG_SYS_MAX_FLASH_BANKS 1 # define CONFIG_SYS_MAX_FLASH_SECT 1024 /*----------------------------------------------------------------------- - * CFI FLASH driver setup */ -# define CONFIG_SYS_FLASH_CFI 1 /* Flash memory is CFI compliant */ +/* Flash memory is CFI compliant */ +# define CONFIG_SYS_FLASH_CFI 1 # define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ -/* #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 */ /* Use buffered writes (~10x faster) */ -# define CONFIG_SYS_FLASH_PROTECTION 1 /* Use h/w sector protection*/ +/* Use buffered writes (~10x faster) */ +/* #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 */ +/* Use h/w sector protection*/ +# define CONFIG_SYS_FLASH_PROTECTION 1 #else /* !CONFIG_SYS_USE_NOR */ # define CONFIG_SYS_NO_FLASH 1 @@ -228,4 +257,15 @@ #define CONFIG_ENV_IS_IN_ONENAND 1 #define CONFIG_ENV_ADDR 0x00020000 +#ifdef CONFIG_SYS_USE_UBI +#define CONFIG_JFFS2_CMDLINE +#define MTDIDS_DEFAULT "onenand0=onenand" +#define MTDPARTS_DEFAULT "mtdparts=onenand:128k(bootloader)," \ + "128k(params)," \ + "2m(kernel)," \ + "16m(rootfs)," \ + "32m(fs)," \ + "-(ubifs)" +#endif + #endif /* __CONFIG_H */ -- cgit v1.1 From 25fb4eaaeab3f8866020818f4729d990dcc91cf0 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 20 Nov 2008 11:46:20 +0100 Subject: ppc4xx: Clear all potentially pending exceptions in MCSR This is needed on Canyonlands which still has an exception pending while running relocate_code(). This leads to a failure after trap_init() is moved to the top of board_init_r(). Signed-off-by: Stefan Roese --- cpu/ppc4xx/start.S | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 882ef21..84d7a28 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -1440,6 +1440,10 @@ relocate_code: dccci 0,0 /* Invalidate data cache, now no longer our stack */ sync isync + + /* Clear all potential pending exceptions */ + mfspr r1,mcsr + mtspr mcsr,r1 #ifdef CONFIG_SYS_TLB_FOR_BOOT_FLASH addi r1,r0,CONFIG_SYS_TLB_FOR_BOOT_FLASH /* Use defined TLB */ #else -- cgit v1.1 From ad229a44e162af0f65e57e4e3dc133d5f0364ecb Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Fri, 7 Nov 2008 13:55:14 +0100 Subject: AT91: Use AT91_CPU_CLOCK in displays Introduce AT91_CPU_CLOCK and use it for displaying the CPU speed in the LCD driver. Also make AT91_MAIN_CLOCK and AT91_MASTER_CLOCK reflect the corresponding board clocks. Signed-off-by: Stelian Pop --- board/atmel/at91cap9adk/at91cap9adk.c | 2 +- board/atmel/at91sam9261ek/at91sam9261ek.c | 2 +- board/atmel/at91sam9263ek/at91sam9263ek.c | 2 +- board/atmel/at91sam9rlek/at91sam9rlek.c | 2 +- include/configs/at91cap9adk.h | 7 ++++--- include/configs/at91sam9260ek.h | 8 +++++--- include/configs/at91sam9261ek.h | 7 ++++--- include/configs/at91sam9263ek.h | 7 ++++--- include/configs/at91sam9rlek.h | 7 ++++--- 9 files changed, 25 insertions(+), 19 deletions(-) diff --git a/board/atmel/at91cap9adk/at91cap9adk.c b/board/atmel/at91cap9adk/at91cap9adk.c index af145cc..f7d68b7 100644 --- a/board/atmel/at91cap9adk/at91cap9adk.c +++ b/board/atmel/at91cap9adk/at91cap9adk.c @@ -342,7 +342,7 @@ void lcd_show_board_info(void) lcd_printf ("at91support@atmel.com\n"); lcd_printf ("%s CPU at %s MHz\n", AT91_CPU_NAME, - strmhz(temp, AT91_MAIN_CLOCK)); + strmhz(temp, AT91_CPU_CLOCK)); dram_size = 0; for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c index 185d6e1..14f236d 100644 --- a/board/atmel/at91sam9261ek/at91sam9261ek.c +++ b/board/atmel/at91sam9261ek/at91sam9261ek.c @@ -225,7 +225,7 @@ void lcd_show_board_info(void) lcd_printf ("at91support@atmel.com\n"); lcd_printf ("%s CPU at %s MHz\n", AT91_CPU_NAME, - strmhz(temp, AT91_MAIN_CLOCK)); + strmhz(temp, AT91_CPU_CLOCK)); dram_size = 0; for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) diff --git a/board/atmel/at91sam9263ek/at91sam9263ek.c b/board/atmel/at91sam9263ek/at91sam9263ek.c index 4feed9a..ebd4649 100644 --- a/board/atmel/at91sam9263ek/at91sam9263ek.c +++ b/board/atmel/at91sam9263ek/at91sam9263ek.c @@ -276,7 +276,7 @@ void lcd_show_board_info(void) lcd_printf ("at91support@atmel.com\n"); lcd_printf ("%s CPU at %s MHz\n", AT91_CPU_NAME, - strmhz(temp, AT91_MAIN_CLOCK)); + strmhz(temp, AT91_CPU_CLOCK)); dram_size = 0; for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) diff --git a/board/atmel/at91sam9rlek/at91sam9rlek.c b/board/atmel/at91sam9rlek/at91sam9rlek.c index 992dd4c..b6fef9d 100644 --- a/board/atmel/at91sam9rlek/at91sam9rlek.c +++ b/board/atmel/at91sam9rlek/at91sam9rlek.c @@ -197,7 +197,7 @@ void lcd_show_board_info(void) lcd_printf ("at91support@atmel.com\n"); lcd_printf ("%s CPU at %s MHz\n", AT91_CPU_NAME, - strmhz(temp, AT91_MAIN_CLOCK)); + strmhz(temp, AT91_CPU_CLOCK)); dram_size = 0; for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) diff --git a/include/configs/at91cap9adk.h b/include/configs/at91cap9adk.h index 30a7cb4..667e049 100644 --- a/include/configs/at91cap9adk.h +++ b/include/configs/at91cap9adk.h @@ -29,9 +29,10 @@ /* ARM asynchronous clock */ #define AT91_CPU_NAME "AT91CAP9" -#define AT91_MAIN_CLOCK 200000000 /* from 12 MHz crystal */ -#define AT91_MASTER_CLOCK 100000000 /* peripheral = main / 2 */ -#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ +#define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */ +#define AT91_MASTER_CLOCK 100000000 /* peripheral */ +#define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index be9a8eb..81c8d39 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -28,9 +28,11 @@ #define __CONFIG_H /* ARM asynchronous clock */ -#define AT91_MAIN_CLOCK 198656000 /* from 18.432 MHz crystal */ -#define AT91_MASTER_CLOCK 99328000 /* peripheral = main / 2 */ -#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ +#define AT91_CPU_NAME "AT91SAM9260" +#define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ +#define AT91_MASTER_CLOCK 100000000 /* peripheral */ +#define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index add31c9..efe35a4 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -29,9 +29,10 @@ /* ARM asynchronous clock */ #define AT91_CPU_NAME "AT91SAM9261" -#define AT91_MAIN_CLOCK 198656000 /* from 18.432 MHz crystal */ -#define AT91_MASTER_CLOCK 99328000 /* peripheral = main / 2 */ -#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ +#define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ +#define AT91_MASTER_CLOCK 100000000 /* peripheral */ +#define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index 555cb7f..ef5b666 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -29,9 +29,10 @@ /* ARM asynchronous clock */ #define AT91_CPU_NAME "AT91SAM9263" -#define AT91_MAIN_CLOCK 199919000 /* from 16.367 MHz crystal */ -#define AT91_MASTER_CLOCK 99959500 /* peripheral = main / 2 */ -#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ +#define AT91_MAIN_CLOCK 16367660 /* 16.367 MHz crystal */ +#define AT91_MASTER_CLOCK 100000000 /* peripheral */ +#define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91sam9rlek.h b/include/configs/at91sam9rlek.h index 648d60e..35dac47 100644 --- a/include/configs/at91sam9rlek.h +++ b/include/configs/at91sam9rlek.h @@ -29,9 +29,10 @@ /* ARM asynchronous clock */ #define AT91_CPU_NAME "AT91SAM9RL" -#define AT91_MAIN_CLOCK 200000000 /* from 12.000 MHz crystal */ -#define AT91_MASTER_CLOCK 100000000 /* peripheral = main / 2 */ -#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ +#define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */ +#define AT91_MASTER_CLOCK 100000000 /* peripheral */ +#define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ -- cgit v1.1 From 3e0cda071a67cb5709e3fa4faf6b31a731859acc Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Sun, 9 Nov 2008 00:14:46 +0100 Subject: AT91: Enable PLLB for USB At least some (old ?) versions of the AT91Bootstrap do not set up the PLLB correctly to 48 MHz in order to make USB host function correctly. This patch sets up the PLLB to the same values Linux uses, and makes USB work ok on the following CPUs: - AT91CAP9 - AT91SAM9260 - AT91SAM9263 This patch also defines CONFIG_USB_STORAGE and CONFIG_CMD_FAT for all the relevant AT91CAP9/AT91SAM9 atmel boards. Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- cpu/arm926ejs/at91/usb.c | 18 ++++++++++++++++++ include/configs/afeb9260.h | 1 + include/configs/at91cap9adk.h | 3 +++ include/configs/at91sam9260ek.h | 2 ++ include/configs/at91sam9261ek.h | 1 + include/configs/at91sam9263ek.h | 2 ++ 6 files changed, 27 insertions(+) diff --git a/cpu/arm926ejs/at91/usb.c b/cpu/arm926ejs/at91/usb.c index 7cb082d..2f5c337 100644 --- a/cpu/arm926ejs/at91/usb.c +++ b/cpu/arm926ejs/at91/usb.c @@ -31,6 +31,15 @@ int usb_cpu_init(void) { + +#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ + defined(CONFIG_AT91SAM9263) + /* Enable PLLB */ + at91_sys_write(AT91_CKGR_PLLBR, CFG_AT91_PLLB); + while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) + ; +#endif + /* Enable USB host clock. */ at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_UHP); #ifdef CONFIG_AT91SAM9261 @@ -51,6 +60,15 @@ int usb_cpu_stop(void) #else at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP); #endif + +#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ + defined(CONFIG_AT91SAM9263) + /* Disable PLLB */ + at91_sys_write(AT91_CKGR_PLLBR, 0); + while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != 0) + ; +#endif + return 0; } diff --git a/include/configs/afeb9260.h b/include/configs/afeb9260.h index 755952f..f077ad9 100644 --- a/include/configs/afeb9260.h +++ b/include/configs/afeb9260.h @@ -29,6 +29,7 @@ /* ARM asynchronous clock */ #define AT91_MAIN_CLOCK 18429952 /* from 18.432 MHz crystal */ #define AT91_MASTER_CLOCK 89999598 /* peripheral = main / 2 */ +#define CFG_AT91_PLLB 0x107c3e18 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91cap9adk.h b/include/configs/at91cap9adk.h index 667e049..aeb06ac 100644 --- a/include/configs/at91cap9adk.h +++ b/include/configs/at91cap9adk.h @@ -32,6 +32,7 @@ #define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CFG_AT91_PLLB 0x10073e01 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ @@ -137,6 +138,8 @@ #define CONFIG_SYS_USB_OHCI_REGS_BASE 0x00700000 /* AT91_BASE_UHP */ #define CONFIG_SYS_USB_OHCI_SLOT_NAME "at91cap9" #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 +#define CONFIG_USB_STORAGE 1 +#define CONFIG_CMD_FAT 1 #define CONFIG_SYS_LOAD_ADDR 0x72000000 /* load address */ diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index 81c8d39..fbc470f 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -32,6 +32,7 @@ #define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CFG_AT91_PLLB 0x107c3e18 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ @@ -123,6 +124,7 @@ #define CONFIG_SYS_USB_OHCI_SLOT_NAME "at91sam9260" #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 #define CONFIG_USB_STORAGE 1 +#define CONFIG_CMD_FAT 1 #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index efe35a4..bd66823 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -137,6 +137,7 @@ #define CONFIG_SYS_USB_OHCI_SLOT_NAME "at91sam9261" #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 #define CONFIG_USB_STORAGE 1 +#define CONFIG_CMD_FAT 1 #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index ef5b666..a2b09ca 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -32,6 +32,7 @@ #define AT91_MAIN_CLOCK 16367660 /* 16.367 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ +#define CFG_AT91_PLLB 0x133a3e8d /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ @@ -143,6 +144,7 @@ #define CONFIG_SYS_USB_OHCI_SLOT_NAME "at91sam9263" #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 #define CONFIG_USB_STORAGE 1 +#define CONFIG_CMD_FAT 1 #define CONFIG_SYS_LOAD_ADDR 0x22000000 /* load address */ -- cgit v1.1 From 263b749e2e25473a48776d317bd2a7e2ddcdd212 Mon Sep 17 00:00:00 2001 From: Ilko Iliev Date: Sun, 9 Nov 2008 15:53:14 +0100 Subject: lib_arm: do_bootm_linux() - correct a small mistake This patch corrects a small bug in the "if" condition: the parameter "flag" is 0 and the "if" condition is always true. The result is - the boom command doesn't start the kernel. Affected targets: all arm based. Signed-off-by: Ilko Iliev --- lib_arm/bootm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 8e264ce..7dbde7d 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -67,7 +67,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) char *commandline = getenv ("bootargs"); #endif - if ((flag != 0) || (flag != BOOTM_STATE_OS_GO)) + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; theKernel = (void (*)(int, int, uint))images->ep; -- cgit v1.1 From e23c7c95a96eb0f068efe5c532215a10a1512a95 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Mon, 10 Nov 2008 20:15:25 +0100 Subject: ARM: OMAP: Convert IO macros Convert IO macros to readx/writex. Signed-off-by: Dirk Behme --- drivers/i2c/omap24xx_i2c.c | 131 ++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 67 deletions(-) diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index d2e8207..4427938 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -25,9 +25,6 @@ #include #include -#define inw(a) __raw_readw(a) -#define outw(a,v) __raw_writew(a,v) - static void wait_for_bb (void); static u16 wait_for_pin (void); static void flush_fifo(void); @@ -36,32 +33,32 @@ void i2c_init (int speed, int slaveadd) { u16 scl; - outw(0x2, I2C_SYSC); /* for ES2 after soft reset */ + writew(0x2, I2C_SYSC); /* for ES2 after soft reset */ udelay(1000); - outw(0x0, I2C_SYSC); /* will probably self clear but */ + writew(0x0, I2C_SYSC); /* will probably self clear but */ - if (inw (I2C_CON) & I2C_CON_EN) { - outw (0, I2C_CON); + if (readw (I2C_CON) & I2C_CON_EN) { + writew (0, I2C_CON); udelay (50000); } /* 12MHz I2C module clock */ - outw (0, I2C_PSC); + writew (0, I2C_PSC); speed = speed/1000; /* 100 or 400 */ scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */ - outw (scl, I2C_SCLL); - outw (scl, I2C_SCLH); + writew (scl, I2C_SCLL); + writew (scl, I2C_SCLH); /* own address */ - outw (slaveadd, I2C_OA); - outw (I2C_CON_EN, I2C_CON); + writew (slaveadd, I2C_OA); + writew (I2C_CON_EN, I2C_CON); /* have to enable intrrupts or OMAP i2c module doesn't work */ - outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | - I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE); + writew (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | + I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE); udelay (1000); flush_fifo(); - outw (0xFFFF, I2C_STAT); - outw (0, I2C_CNT); + writew (0xFFFF, I2C_STAT); + writew (0, I2C_CNT); } static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) @@ -73,19 +70,19 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) wait_for_bb (); /* one byte only */ - outw (1, I2C_CNT); + writew (1, I2C_CNT); /* set slave address */ - outw (devaddr, I2C_SA); + writew (devaddr, I2C_SA); /* no stop bit needed here */ - outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON); status = wait_for_pin (); if (status & I2C_STAT_XRDY) { /* Important: have to use byte access */ - *(volatile u8 *) (I2C_DATA) = regoffset; + writeb (regoffset, I2C_DATA); udelay (20000); - if (inw (I2C_STAT) & I2C_STAT_NACK) { + if (readw (I2C_STAT) & I2C_STAT_NACK) { i2c_error = 1; } } else { @@ -94,42 +91,42 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) if (!i2c_error) { /* free bus, otherwise we can't use a combined transction */ - outw (0, I2C_CON); - while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) { + writew (0, I2C_CON); + while (readw (I2C_STAT) || (readw (I2C_CON) & I2C_CON_MST)) { udelay (10000); /* Have to clear pending interrupt to clear I2C_STAT */ - outw (0xFFFF, I2C_STAT); + writew (0xFFFF, I2C_STAT); } wait_for_bb (); /* set slave address */ - outw (devaddr, I2C_SA); + writew (devaddr, I2C_SA); /* read one byte from slave */ - outw (1, I2C_CNT); + writew (1, I2C_CNT); /* need stop bit here */ - outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, - I2C_CON); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, + I2C_CON); status = wait_for_pin (); if (status & I2C_STAT_RRDY) { - *value = inw (I2C_DATA); + *value = readw (I2C_DATA); udelay (20000); } else { i2c_error = 1; } if (!i2c_error) { - outw (I2C_CON_EN, I2C_CON); - while (inw (I2C_STAT) - || (inw (I2C_CON) & I2C_CON_MST)) { + writew (I2C_CON_EN, I2C_CON); + while (readw (I2C_STAT) + || (readw (I2C_CON) & I2C_CON_MST)) { udelay (10000); - outw (0xFFFF, I2C_STAT); + writew (0xFFFF, I2C_STAT); } } } flush_fifo(); - outw (0xFFFF, I2C_STAT); - outw (0, I2C_CNT); + writew (0xFFFF, I2C_STAT); + writew (0, I2C_CNT); return i2c_error; } @@ -142,22 +139,22 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value) wait_for_bb (); /* two bytes */ - outw (2, I2C_CNT); + writew (2, I2C_CNT); /* set slave address */ - outw (devaddr, I2C_SA); + writew (devaddr, I2C_SA); /* stop bit needed here */ - outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | - I2C_CON_STP, I2C_CON); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | + I2C_CON_STP, I2C_CON); /* wait until state change */ status = wait_for_pin (); if (status & I2C_STAT_XRDY) { /* send out two bytes */ - outw ((value << 8) + regoffset, I2C_DATA); + writew ((value << 8) + regoffset, I2C_DATA); /* must have enough delay to allow BB bit to go low */ udelay (50000); - if (inw (I2C_STAT) & I2C_STAT_NACK) { + if (readw (I2C_STAT) & I2C_STAT_NACK) { i2c_error = 1; } } else { @@ -167,18 +164,18 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value) if (!i2c_error) { int eout = 200; - outw (I2C_CON_EN, I2C_CON); - while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) { + writew (I2C_CON_EN, I2C_CON); + while ((stat = readw (I2C_STAT)) || (readw (I2C_CON) & I2C_CON_MST)) { udelay (1000); /* have to read to clear intrrupt */ - outw (0xFFFF, I2C_STAT); + writew (0xFFFF, I2C_STAT); if(--eout == 0) /* better leave with error than hang */ break; } } flush_fifo(); - outw (0xFFFF, I2C_STAT); - outw (0, I2C_CNT); + writew (0xFFFF, I2C_STAT); + writew (0, I2C_CNT); return i2c_error; } @@ -189,10 +186,10 @@ static void flush_fifo(void) * you get a bus error */ while(1){ - stat = inw(I2C_STAT); + stat = readw(I2C_STAT); if(stat == I2C_STAT_RRDY){ - inw(I2C_DATA); - outw(I2C_STAT_RRDY,I2C_STAT); + readw(I2C_DATA); + writew(I2C_STAT_RRDY,I2C_STAT); udelay(1000); }else break; @@ -203,7 +200,7 @@ int i2c_probe (uchar chip) { int res = 1; /* default = fail */ - if (chip == inw (I2C_OA)) { + if (chip == readw (I2C_OA)) { return res; } @@ -211,27 +208,27 @@ int i2c_probe (uchar chip) wait_for_bb (); /* try to read one byte */ - outw (1, I2C_CNT); + writew (1, I2C_CNT); /* set slave address */ - outw (chip, I2C_SA); + writew (chip, I2C_SA); /* stop bit needed here */ - outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON); /* enough delay for the NACK bit set */ udelay (50000); - if (!(inw (I2C_STAT) & I2C_STAT_NACK)) { + if (!(readw (I2C_STAT) & I2C_STAT_NACK)) { res = 0; /* success case */ flush_fifo(); - outw(0xFFFF, I2C_STAT); + writew(0xFFFF, I2C_STAT); } else { - outw(0xFFFF, I2C_STAT); /* failue, clear sources*/ - outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */ + writew(0xFFFF, I2C_STAT); /* failue, clear sources*/ + writew (readw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */ udelay(20000); wait_for_bb (); } flush_fifo(); - outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/ - outw(0xFFFF, I2C_STAT); + writew (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/ + writew(0xFFFF, I2C_STAT); return res; } @@ -290,17 +287,17 @@ static void wait_for_bb (void) int timeout = 10; u16 stat; - outw(0xFFFF, I2C_STAT); /* clear current interruts...*/ - while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) { - outw (stat, I2C_STAT); + writew(0xFFFF, I2C_STAT); /* clear current interruts...*/ + while ((stat = readw (I2C_STAT) & I2C_STAT_BB) && timeout--) { + writew (stat, I2C_STAT); udelay (50000); } if (timeout <= 0) { printf ("timed out in wait_for_bb: I2C_STAT=%x\n", - inw (I2C_STAT)); + readw (I2C_STAT)); } - outw(0xFFFF, I2C_STAT); /* clear delayed stuff*/ + writew(0xFFFF, I2C_STAT); /* clear delayed stuff*/ } static u16 wait_for_pin (void) @@ -310,7 +307,7 @@ static u16 wait_for_pin (void) do { udelay (1000); - status = inw (I2C_STAT); + status = readw (I2C_STAT); } while ( !(status & (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | @@ -318,8 +315,8 @@ static u16 wait_for_pin (void) if (timeout <= 0) { printf ("timed out in wait_for_pin: I2C_STAT=%x\n", - inw (I2C_STAT)); - outw(0xFFFF, I2C_STAT); + readw (I2C_STAT)); + writew(0xFFFF, I2C_STAT); } return status; } -- cgit v1.1 From 711e2b2af820d21d9931d4cf8057d3894600fd54 Mon Sep 17 00:00:00 2001 From: "Steven A. Falco" Date: Thu, 20 Nov 2008 14:37:57 -0500 Subject: ppc4xx: Delete unused definitions for SDR0_DDRCFG from ppc4xx.h The definitions of bits in SDR_CFG are incorrect, and not used within U-Boot. Therefore, they can be removed. The naming of the sdr_ddrdl/sdr_cfg registers do not follow conventions, and are unused, so they can be removed too. A definition for SDR0_DDRCFG is added. Signed-off-by: Steven A. Falco Signed-off-by: Stefan Roese --- include/ppc440.h | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/include/ppc440.h b/include/ppc440.h index ea0ac86..4d2157a 100644 --- a/include/ppc440.h +++ b/include/ppc440.h @@ -169,18 +169,9 @@ #define sdr_ecid1 0x0081 #define sdr_ecid2 0x0082 #define sdr_jtag 0x00c0 -#if !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) -#define sdr_ddrdl 0x00e0 -#else -#define sdr_cfg 0x00e0 -#define SDR_CFG_LT2_MASK 0x01000000 /* Leakage test 2*/ -#define SDR_CFG_64_32BITS_MASK 0x01000000 /* Switch DDR 64 bits or 32 bits */ -#define SDR_CFG_32BITS 0x00000000 /* 32 bits */ -#define SDR_CFG_64BITS 0x01000000 /* 64 bits */ -#define SDR_CFG_MC_V2518_MASK 0x02000000 /* Low VDD2518 (2.5 or 1.8V) */ -#define SDR_CFG_MC_V25 0x00000000 /* 2.5 V */ -#define SDR_CFG_MC_V18 0x02000000 /* 1.8 V */ -#endif /* !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) */ +#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) +#define SDR0_DDRCFG 0x00e0 +#endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */ #define sdr_ebc 0x0100 #define sdr_uart0 0x0120 /* UART0 Config */ #define sdr_uart1 0x0121 /* UART1 Config */ -- cgit v1.1 From b14ca4b61a681f75f3125676e09d7ce6af66e927 Mon Sep 17 00:00:00 2001 From: Dave Mitchell Date: Thu, 20 Nov 2008 14:00:49 -0600 Subject: ppc4xx: Added ppc4xx-isram.h for internal SRAM and L2 cache DCRs Added include/asm-ppc/ppc4xx-isram.h and moved internal SRAM and L2 cache DCRs from ppc440.h to this new header. Also converted these DCR defines from lowercase to uppercase and modified referencing modules to use them. Signed-off-by: Dave Mitchell Signed-off-by: Stefan Roese --- board/amcc/luan/luan.c | 23 ++++++------- cpu/ppc4xx/start.S | 41 ++++++++++++----------- include/asm-ppc/ppc4xx-isram.h | 75 ++++++++++++++++++++++++++++++++++++++++++ include/ppc440.h | 39 ---------------------- 4 files changed, 108 insertions(+), 70 deletions(-) create mode 100644 include/asm-ppc/ppc4xx-isram.h diff --git a/board/amcc/luan/luan.c b/board/amcc/luan/luan.c index b28ebf9..de3e3d8 100644 --- a/board/amcc/luan/luan.c +++ b/board/amcc/luan/luan.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "epld.h" @@ -255,7 +256,7 @@ static int on_off( const char *s ) ************************************************************************/ static void l2cache_disable(void) { - mtdcr( l2_cache_cfg, 0 ); + mtdcr( L2_CACHE_CFG, 0 ); } @@ -265,24 +266,24 @@ static void l2cache_disable(void) ************************************************************************/ static void l2cache_enable(void) /* see p258 7.4.1 Enabling L2 Cache */ { - mtdcr( l2_cache_cfg, 0x80000000 ); /* enable L2_MODE L2_CFG[L2M] */ + mtdcr( L2_CACHE_CFG, 0x80000000 ); /* enable L2_MODE L2_CFG[L2M] */ - mtdcr( l2_cache_addr, 0 ); /* set L2_ADDR with all zeros */ + mtdcr( L2_CACHE_ADDR, 0 ); /* set L2_ADDR with all zeros */ - mtdcr( l2_cache_cmd, 0x80000000 ); /* issue HCLEAR command via L2_CMD */ + mtdcr( L2_CACHE_CMD, 0x80000000 ); /* issue HCLEAR command via L2_CMD */ - while (!(mfdcr( l2_cache_stat ) & 0x80000000 )) ;; /* poll L2_SR for completion */ + while (!(mfdcr( L2_CACHE_STAT ) & 0x80000000 )) ;; /* poll L2_SR for completion */ - mtdcr( l2_cache_cmd, 0x10000000 ); /* clear cache errors L2_CMD[CCP] */ + mtdcr( L2_CACHE_CMD, 0x10000000 ); /* clear cache errors L2_CMD[CCP] */ - mtdcr( l2_cache_cmd, 0x08000000 ); /* clear tag errors L2_CMD[CTE] */ + mtdcr( L2_CACHE_CMD, 0x08000000 ); /* clear tag errors L2_CMD[CTE] */ - mtdcr( l2_cache_snp0, 0 ); /* snoop registers */ - mtdcr( l2_cache_snp1, 0 ); + mtdcr( L2_CACHE_SNP0, 0 ); /* snoop registers */ + mtdcr( L2_CACHE_SNP1, 0 ); __asm__ volatile ("sync"); /* msync */ - mtdcr( l2_cache_cfg, 0xe0000000 ); /* inst and data use L2 */ + mtdcr( L2_CACHE_CFG, 0xe0000000 ); /* inst and data use L2 */ __asm__ volatile ("sync"); } @@ -294,7 +295,7 @@ static void l2cache_enable(void) /* see p258 7.4.1 Enabling L2 Cache */ ************************************************************************/ static int l2cache_status(void) { - return (mfdcr( l2_cache_cfg ) & 0x60000000) != 0; + return (mfdcr( L2_CACHE_CFG ) & 0x60000000) != 0; } diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 84d7a28..db34e84 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -72,6 +72,7 @@ #include #include +#include #ifndef CONFIG_IDENT_STRING #define CONFIG_IDENT_STRING "" @@ -679,65 +680,65 @@ _start: defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_460SX) - mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */ + mtdcr L2_CACHE_CFG,r0 /* Ensure L2 Cache is off */ #endif lis r2,0x7fff ori r2,r2,0xffff - mfdcr r1,isram0_dpc + mfdcr r1,ISRAM0_DPC and r1,r1,r2 /* Disable parity check */ - mtdcr isram0_dpc,r1 - mfdcr r1,isram0_pmeg + mtdcr ISRAM0_DPC,r1 + mfdcr r1,ISRAM0_PMEG and r1,r1,r2 /* Disable pwr mgmt */ - mtdcr isram0_pmeg,r1 + mtdcr ISRAM0_PMEG,r1 lis r1,0x8000 /* BAS = 8000_0000 */ #if defined(CONFIG_440GX) || defined(CONFIG_440SP) ori r1,r1,0x0980 /* first 64k */ - mtdcr isram0_sb0cr,r1 + mtdcr ISRAM0_SB0CR,r1 lis r1,0x8001 ori r1,r1,0x0980 /* second 64k */ - mtdcr isram0_sb1cr,r1 + mtdcr ISRAM0_SB1CR,r1 lis r1, 0x8002 ori r1,r1, 0x0980 /* third 64k */ - mtdcr isram0_sb2cr,r1 + mtdcr ISRAM0_SB2CR,r1 lis r1, 0x8003 ori r1,r1, 0x0980 /* fourth 64k */ - mtdcr isram0_sb3cr,r1 + mtdcr ISRAM0_SB3CR,r1 #elif defined(CONFIG_440SPE) lis r1,0x0000 /* BAS = 0000_0000 */ ori r1,r1,0x0984 /* first 64k */ - mtdcr isram0_sb0cr,r1 + mtdcr ISRAM0_SB0CR,r1 lis r1,0x0001 ori r1,r1,0x0984 /* second 64k */ - mtdcr isram0_sb1cr,r1 + mtdcr ISRAM0_SB1CR,r1 lis r1, 0x0002 ori r1,r1, 0x0984 /* third 64k */ - mtdcr isram0_sb2cr,r1 + mtdcr ISRAM0_SB2CR,r1 lis r1, 0x0003 ori r1,r1, 0x0984 /* fourth 64k */ - mtdcr isram0_sb3cr,r1 + mtdcr ISRAM0_SB3CR,r1 #elif defined(CONFIG_460EX) || defined(CONFIG_460GT) lis r1,0x4000 /* BAS = 8000_0000 */ ori r1,r1,0x4580 /* 16k */ - mtdcr isram0_sb0cr,r1 + mtdcr ISRAM0_SB0CR,r1 #elif defined(CONFIG_460SX) lis r1,0x0000 /* BAS = 0000_0000 */ ori r1,r1,0x0B84 /* first 128k */ - mtdcr isram0_sb0cr,r1 + mtdcr ISRAM0_SB0CR,r1 lis r1,0x0001 ori r1,r1,0x0B84 /* second 128k */ - mtdcr isram0_sb1cr,r1 + mtdcr ISRAM0_SB1CR,r1 lis r1, 0x0002 ori r1,r1, 0x0B84 /* third 128k */ - mtdcr isram0_sb2cr,r1 + mtdcr ISRAM0_SB2CR,r1 lis r1, 0x0003 ori r1,r1, 0x0B84 /* fourth 128k */ - mtdcr isram0_sb3cr,r1 + mtdcr ISRAM0_SB3CR,r1 #elif defined(CONFIG_440GP) ori r1,r1,0x0380 /* 8k rw */ - mtdcr isram0_sb0cr,r1 - mtdcr isram0_sb1cr,r0 /* Disable bank 1 */ + mtdcr ISRAM0_SB0CR,r1 + mtdcr ISRAM0_SB1CR,r0 /* Disable bank 1 */ #endif #endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */ diff --git a/include/asm-ppc/ppc4xx-isram.h b/include/asm-ppc/ppc4xx-isram.h new file mode 100644 index 0000000..d6d17ac --- /dev/null +++ b/include/asm-ppc/ppc4xx-isram.h @@ -0,0 +1,75 @@ + +/* + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _PPC4xx_ISRAM_H_ +#define _PPC4xx_ISRAM_H_ + +/* + * Internal SRAM + */ +#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) +#define ISRAM0_DCR_BASE 0x380 +#else +#define ISRAM0_DCR_BASE 0x020 +#endif +#define ISRAM0_SB0CR (ISRAM0_DCR_BASE+0x00) /* SRAM bank config 0*/ +#define ISRAM0_SB1CR (ISRAM0_DCR_BASE+0x01) /* SRAM bank config 1*/ +#define ISRAM0_SB2CR (ISRAM0_DCR_BASE+0x02) /* SRAM bank config 2*/ +#define ISRAM0_SB3CR (ISRAM0_DCR_BASE+0x03) /* SRAM bank config 3*/ +#define ISRAM0_BEAR (ISRAM0_DCR_BASE+0x04) /* SRAM bus error addr reg */ +#define ISRAM0_BESR0 (ISRAM0_DCR_BASE+0x05) /* SRAM bus error status reg 0 */ +#define ISRAM0_BESR1 (ISRAM0_DCR_BASE+0x06) /* SRAM bus error status reg 1 */ +#define ISRAM0_PMEG (ISRAM0_DCR_BASE+0x07) /* SRAM power management */ +#define ISRAM0_CID (ISRAM0_DCR_BASE+0x08) /* SRAM bus core id reg */ +#define ISRAM0_REVID (ISRAM0_DCR_BASE+0x09) /* SRAM bus revision id reg */ +#define ISRAM0_DPC (ISRAM0_DCR_BASE+0x0a) /* SRAM data parity check reg */ + +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#define ISRAM1_DCR_BASE 0x0B0 +#define ISRAM1_SB0CR (ISRAM1_DCR_BASE+0x00) /* SRAM1 bank config 0*/ +#define ISRAM1_BEAR (ISRAM1_DCR_BASE+0x04) /* SRAM1 bus error addr reg */ +#define ISRAM1_BESR0 (ISRAM1_DCR_BASE+0x05) /* SRAM1 bus error status reg 0 */ +#define ISRAM1_BESR1 (ISRAM1_DCR_BASE+0x06) /* SRAM1 bus error status reg 1 */ +#define ISRAM1_PMEG (ISRAM1_DCR_BASE+0x07) /* SRAM1 power management */ +#define ISRAM1_CID (ISRAM1_DCR_BASE+0x08) /* SRAM1 bus core id reg */ +#define ISRAM1_REVID (ISRAM1_DCR_BASE+0x09) /* SRAM1 bus revision id reg */ +#define ISRAM1_DPC (ISRAM1_DCR_BASE+0x0a) /* SRAM1 data parity check reg */ +#endif /* CONFIG_460EX || CONFIG_460GT */ + +/* + * L2 Cache + */ +#if defined (CONFIG_440GX) || \ + defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ + defined(CONFIG_460SX) +#define L2_CACHE_BASE 0x030 +#define L2_CACHE_CFG (L2_CACHE_BASE+0x00) /* L2 Cache Config */ +#define L2_CACHE_CMD (L2_CACHE_BASE+0x01) /* L2 Cache Command */ +#define L2_CACHE_ADDR (L2_CACHE_BASE+0x02) /* L2 Cache Address */ +#define L2_CACHE_DATA (L2_CACHE_BASE+0x03) /* L2 Cache Data */ +#define L2_CACHE_STAT (L2_CACHE_BASE+0x04) /* L2 Cache Status */ +#define L2_CACHE_CVER (L2_CACHE_BASE+0x05) /* L2 Cache Revision ID */ +#define L2_CACHE_SNP0 (L2_CACHE_BASE+0x06) /* L2 Cache Snoop reg 0 */ +#define L2_CACHE_SNP1 (L2_CACHE_BASE+0x07) /* L2 Cache Snoop reg 1 */ +#endif /* CONFIG_440GX */ + +#endif /* _PPC4xx_ISRAM_H_ */ diff --git a/include/ppc440.h b/include/ppc440.h index 4d2157a..01f6eaf 100644 --- a/include/ppc440.h +++ b/include/ppc440.h @@ -607,45 +607,6 @@ #endif /* 440EP || 440GR || 440EPX || 440GRX */ -/*----------------------------------------------------------------------------- - | L2 Cache - +----------------------------------------------------------------------------*/ -#if defined (CONFIG_440GX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_460SX) -#define L2_CACHE_BASE 0x030 -#define l2_cache_cfg (L2_CACHE_BASE+0x00) /* L2 Cache Config */ -#define l2_cache_cmd (L2_CACHE_BASE+0x01) /* L2 Cache Command */ -#define l2_cache_addr (L2_CACHE_BASE+0x02) /* L2 Cache Address */ -#define l2_cache_data (L2_CACHE_BASE+0x03) /* L2 Cache Data */ -#define l2_cache_stat (L2_CACHE_BASE+0x04) /* L2 Cache Status */ -#define l2_cache_cver (L2_CACHE_BASE+0x05) /* L2 Cache Revision ID */ -#define l2_cache_snp0 (L2_CACHE_BASE+0x06) /* L2 Cache Snoop reg 0 */ -#define l2_cache_snp1 (L2_CACHE_BASE+0x07) /* L2 Cache Snoop reg 1 */ - -#endif /* CONFIG_440GX */ - -/*----------------------------------------------------------------------------- - | Internal SRAM - +----------------------------------------------------------------------------*/ -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -#define ISRAM0_DCR_BASE 0x380 -#else -#define ISRAM0_DCR_BASE 0x020 -#endif -#define isram0_sb0cr (ISRAM0_DCR_BASE+0x00) /* SRAM bank config 0*/ -#define isram0_sb1cr (ISRAM0_DCR_BASE+0x01) /* SRAM bank config 1*/ -#define isram0_sb2cr (ISRAM0_DCR_BASE+0x02) /* SRAM bank config 2*/ -#define isram0_sb3cr (ISRAM0_DCR_BASE+0x03) /* SRAM bank config 3*/ -#define isram0_bear (ISRAM0_DCR_BASE+0x04) /* SRAM bus error addr reg */ -#define isram0_besr0 (ISRAM0_DCR_BASE+0x05) /* SRAM bus error status reg 0 */ -#define isram0_besr1 (ISRAM0_DCR_BASE+0x06) /* SRAM bus error status reg 1 */ -#define isram0_pmeg (ISRAM0_DCR_BASE+0x07) /* SRAM power management */ -#define isram0_cid (ISRAM0_DCR_BASE+0x08) /* SRAM bus core id reg */ -#define isram0_revid (ISRAM0_DCR_BASE+0x09) /* SRAM bus revision id reg */ -#define isram0_dpc (ISRAM0_DCR_BASE+0x0a) /* SRAM data parity check reg */ - #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_460EX) || defined(CONFIG_460GT) -- cgit v1.1 From ddf45cc758d394591fb9bcdcbe96530f733f2bce Mon Sep 17 00:00:00 2001 From: Dave Mitchell Date: Thu, 20 Nov 2008 14:09:50 -0600 Subject: ppc4xx: Changed 460EX/GT OCM TLB and internal SRAM initialization Expanded OCM TLB to allow access to 64K OCM as well as 256K of internal SRAM. Adjusted internal SRAM initialization to match updated user manual recommendation. OCM & ISRAM are now mapped as follows: physical virtual size ISRAM 0x4_0000_0000 0xE300_0000 256k OCM 0x4_0004_0000 0xE304_0000 64k A single TLB was used for this mapping. Signed-off-by: Dave Mitchell Signed-off-by: Stefan Roese --- board/amcc/canyonlands/init.S | 2 +- cpu/ppc4xx/start.S | 27 ++++++++++++++++++++------- include/configs/canyonlands.h | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/board/amcc/canyonlands/init.S b/board/amcc/canyonlands/init.S index 51b46d7..0b66796 100644 --- a/board/amcc/canyonlands/init.S +++ b/board/amcc/canyonlands/init.S @@ -89,7 +89,7 @@ tlbtab: #endif /* TLB-entry for OCM */ - tlbentry(CONFIG_SYS_OCM_BASE, SZ_16K, 0x00040000, 4, AC_R|AC_W|AC_X|SA_I) + tlbentry(CONFIG_SYS_OCM_BASE, SZ_1M, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I) /* TLB-entry for Local Configuration registers => peripherals */ tlbentry(CONFIG_SYS_LOCAL_CONF_REGS, SZ_16M, CONFIG_SYS_LOCAL_CONF_REGS, 4, AC_R|AC_W|AC_X|SA_G|SA_I) diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index db34e84..e68cf9b 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -678,9 +678,12 @@ _start: /* not all PPC's have internal SRAM usable as L2-cache */ #if defined(CONFIG_440GX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_460SX) mtdcr L2_CACHE_CFG,r0 /* Ensure L2 Cache is off */ +#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) + lis r1, 0x0000 + ori r1,r1,0x0008 /* Set L2_CACHE_CFG[RDBW]=1 */ + mtdcr L2_CACHE_CFG,r1 #endif lis r2,0x7fff @@ -705,8 +708,8 @@ _start: lis r1, 0x8003 ori r1,r1, 0x0980 /* fourth 64k */ mtdcr ISRAM0_SB3CR,r1 -#elif defined(CONFIG_440SPE) - lis r1,0x0000 /* BAS = 0000_0000 */ +#elif defined(CONFIG_440SPE) || defined(CONFIG_460EX) || defined(CONFIG_460GT) + lis r1,0x0000 /* BAS = X_0000_0000 */ ori r1,r1,0x0984 /* first 64k */ mtdcr ISRAM0_SB0CR,r1 lis r1,0x0001 @@ -718,10 +721,20 @@ _start: lis r1, 0x0003 ori r1,r1, 0x0984 /* fourth 64k */ mtdcr ISRAM0_SB3CR,r1 -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) - lis r1,0x4000 /* BAS = 8000_0000 */ - ori r1,r1,0x4580 /* 16k */ - mtdcr ISRAM0_SB0CR,r1 +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) + lis r2,0x7fff + ori r2,r2,0xffff + mfdcr r1,ISRAM1_DPC + and r1,r1,r2 /* Disable parity check */ + mtdcr ISRAM1_DPC,r1 + mfdcr r1,ISRAM1_PMEG + and r1,r1,r2 /* Disable pwr mgmt */ + mtdcr ISRAM1_PMEG,r1 + + lis r1,0x0004 /* BAS = 4_0004_0000 */ + ori r1,r1,0x0984 /* 64k */ + mtdcr ISRAM1_SB0CR,r1 +#endif #elif defined(CONFIG_460SX) lis r1,0x0000 /* BAS = 0000_0000 */ ori r1,r1,0x0B84 /* first 128k */ diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index f8e8801..faf6304 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -102,7 +102,7 @@ #define CONFIG_SYS_FLASH_BASE_PHYS (((u64)CONFIG_SYS_FLASH_BASE_PHYS_H << 32) | \ (u64)CONFIG_SYS_FLASH_BASE_PHYS_L) -#define CONFIG_SYS_OCM_BASE 0xE3000000 /* OCM: 16k */ +#define CONFIG_SYS_OCM_BASE 0xE3000000 /* OCM: 64k */ #define CONFIG_SYS_SRAM_BASE 0xE8000000 /* SRAM: 256k */ #define CONFIG_SYS_LOCAL_CONF_REGS 0xEF000000 -- cgit v1.1 From 1a6a00dcc5bdfc6e9b4b00f39c1f583a7f96fc7f Mon Sep 17 00:00:00 2001 From: Yuri Tikhonov Date: Fri, 14 Nov 2008 16:19:19 +0300 Subject: ppc4xx: katmai: Change default config This patch enables support for EXT2, and increases the CONFIG_SYS_BOOTMAPSZ size for the default configuration of the katmai boards to use them as the RAID-reference AMCC setups. EXT2 enabling allows one to boot kernels from the EXT2 formatted Compact Flash cards. CONFIG_SYS_BOOTMAPSZ increasing allows one to boot the Linux kernels, which use PAGE_SIZE of 256KB. Otherwise, the memory area with DTB file (which is placed at the end of the bootmap area) will turn out to be overlapped with the BSS segment of the 256KB kernel, and zeroed in early_init() of Linux. Actually, increasing of the bootmap size could be done via setting of the bootm_size U-Boot variable, but it looks like the current U-Boot implementation have some bootm_size- related functionality lost. In many places through the U-Boot code the CONFIG_SYS_BOOTMAPSZ definition is used directly (instead of trying to read the corresponding value from the environment). The same is truth for the boot_jump_linux() function in lib_ppc/bootm.c, where U-Boot transfers control to Linux passing the CONFIG_SYS_BOOTMAPSZ (not bootm_size) value to the booting kernel. Signed-off-by: Yuri Tikhonov Signed-off-by: Ilya Yanok Signed-off-by: Stefan Roese --- include/configs/katmai.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/configs/katmai.h b/include/configs/katmai.h index 58694cc..ea6cf0d 100644 --- a/include/configs/katmai.h +++ b/include/configs/katmai.h @@ -53,6 +53,13 @@ #define CONFIG_HOSTNAME katmai #include "amcc-common.h" +/* + * For booting 256K-paged Linux we should have 16MB of memory + * for Linux initial memory map + */ +#undef CONFIG_SYS_BOOTMAPSZ +#define CONFIG_SYS_BOOTMAPSZ (16 << 20) + #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ #undef CONFIG_SHOW_BOOT_PROGRESS @@ -189,6 +196,7 @@ /* * Commands additional to the ones defined in amcc-common.h */ +#define CONFIG_CMD_EXT2 #define CONFIG_CMD_DATE #define CONFIG_CMD_PCI #define CONFIG_CMD_SDRAM -- cgit v1.1 From de01c76c3ccc4e6c5989228eed58e955a3a1a968 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 21 Nov 2008 13:06:06 +0100 Subject: ppc4xx: ML2 shouldn't include the 4xx EMAC driver Signed-off-by: Stefan Roese --- board/ml2/u-boot.lds | 1 - 1 file changed, 1 deletion(-) diff --git a/board/ml2/u-boot.lds b/board/ml2/u-boot.lds index 28c6546..13ceea0 100644 --- a/board/ml2/u-boot.lds +++ b/board/ml2/u-boot.lds @@ -63,7 +63,6 @@ SECTIONS cpu/ppc4xx/4xx_uart.o (.text) cpu/ppc4xx/cpu_init.o (.text) cpu/ppc4xx/speed.o (.text) - drivers/net/4xx_enet.o (.text) common/dlmalloc.o (.text) lib_generic/crc32.o (.text) lib_ppc/extable.o (.text) -- cgit v1.1 From a5c4067017631d903e1afa6ad615f0ce19fea517 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 24 Nov 2008 08:31:16 +0100 Subject: UBI: Change parsing of size in commands to default to hex Currently the size parameters of the UBI commands (e.g. "ubi write") are decoded as decimal instead of hex as default. This patch now interprets all these values consistantly as hex, as all other standard U-Boot commands do. Signed-off-by: Stefan Roese --- common/cmd_ubi.c | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index a5c5064..57ce3cc 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -29,6 +29,7 @@ /* Private own data */ static struct ubi_device *ubi; +static char buffer[80]; struct selected_dev { char dev_name[32]; /* NAND/OneNAND etc */ @@ -113,19 +114,6 @@ static int ubi_info(int layout) return 0; } -static int parse_num(size_t *num, const char *token) -{ - char *endp; - size_t n; - - n = (size_t) ustrtoul(token, &endp, 0); - if (*endp) - return -EINVAL; - - *num = n; - return 0; -} - static int verify_mkvol_req(const struct ubi_device *ubi, const struct ubi_mkvol_req *req) { @@ -378,7 +366,6 @@ static int ubi_volume_read(char *volume, char *buf, size_t size) tmp = offp; off = do_div(tmp, vol->usable_leb_size); lnum = tmp; - printf("off=%d lnum=%d\n", off, lnum); do { if (off + len >= vol->usable_leb_size) len = vol->usable_leb_size - off; @@ -397,9 +384,7 @@ static int ubi_volume_read(char *volume, char *buf, size_t size) size -= len; offp += len; - printf("buf = %x\n", (unsigned)buf); memcpy(buf, tbuf, len); - printf("buf[0] = %x\n", buf[0]); buf += len; len = size > tbuf_size ? tbuf_size : size; @@ -414,7 +399,6 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev) struct mtd_device *dev; struct part_info *part; struct mtd_partition mtd_part; - char buffer[32]; u8 pnum; int err; @@ -543,11 +527,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } /* E.g., create volume size */ if (argc == 4) { - err = parse_num(&size, argv[3]); - if (err) { - printf("Incorrect type\n"); - return err; - } + addr = simple_strtoul(argv[3], NULL, 16); argc--; } /* Use maximum available size */ @@ -571,11 +551,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } addr = simple_strtoul(argv[2], NULL, 16); - err = parse_num(&size, argv[4]); - if (err) { - printf("Please see usage\n"); - return err; - } + size = simple_strtoul(argv[4], NULL, 16); return ubi_volume_write(argv[3], (void *)addr, size); } @@ -585,11 +561,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* E.g., read volume size */ if (argc == 5) { - err = parse_num(&size, argv[4]); - if (err) { - printf("Please see usage\n"); - return err; - } + size = simple_strtoul(argv[4], NULL, 16); argc--; } -- cgit v1.1 From 45aa5a7f4d5bcb79927ddfc896c1d7c4326e235d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 17 Nov 2008 14:45:22 +0100 Subject: cfi_flash: Make all flash access functions weak This patch defines all flash access functions as weak so that they can be overridden by board specific versions. This will be used by the upcoming VCTH board support where the NOR FLASH unfortunately can't be accessed memory-mapped. Special accessor functions are needed here. To enable this weak functions you need to define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS in your board config header. Otherwise the "old" default functions will be used resulting in smaller code. Signed-off-by: Stefan Roese Acked-by: Haavard Skinnemoen --- drivers/mtd/cfi_flash.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 24e9b9f..f10d5fe 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -209,38 +209,38 @@ struct cfi_pri_hdr { u8 minor_version; } __attribute__((packed)); -static void flash_write8(u8 value, void *addr) +static void __flash_write8(u8 value, void *addr) { __raw_writeb(value, addr); } -static void flash_write16(u16 value, void *addr) +static void __flash_write16(u16 value, void *addr) { __raw_writew(value, addr); } -static void flash_write32(u32 value, void *addr) +static void __flash_write32(u32 value, void *addr) { __raw_writel(value, addr); } -static void flash_write64(u64 value, void *addr) +static void __flash_write64(u64 value, void *addr) { /* No architectures currently implement __raw_writeq() */ *(volatile u64 *)addr = value; } -static u8 flash_read8(void *addr) +static u8 __flash_read8(void *addr) { return __raw_readb(addr); } -static u16 flash_read16(void *addr) +static u16 __flash_read16(void *addr) { return __raw_readw(addr); } -static u32 flash_read32(void *addr) +static u32 __flash_read32(void *addr) { return __raw_readl(addr); } @@ -251,7 +251,25 @@ static u64 __flash_read64(void *addr) return *(volatile u64 *)addr; } +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS +void flash_write8(u8 value, void *addr)__attribute__((weak, alias("__flash_write8"))); +void flash_write16(u16 value, void *addr)__attribute__((weak, alias("__flash_write16"))); +void flash_write32(u32 value, void *addr)__attribute__((weak, alias("__flash_write32"))); +void flash_write64(u64 value, void *addr)__attribute__((weak, alias("__flash_write64"))); +u8 flash_read8(void *addr)__attribute__((weak, alias("__flash_read8"))); +u16 flash_read16(void *addr)__attribute__((weak, alias("__flash_read16"))); +u32 flash_read32(void *addr)__attribute__((weak, alias("__flash_read32"))); u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64"))); +#else +#define flash_write8 __flash_write8 +#define flash_write16 __flash_write16 +#define flash_write32 __flash_write32 +#define flash_write64 __flash_write64 +#define flash_read8 __flash_read8 +#define flash_read16 __flash_read16 +#define flash_read32 __flash_read32 +#define flash_read64 __flash_read64 +#endif /*----------------------------------------------------------------------- */ -- cgit v1.1 From ebc9784ce6528385bb8d2558e783622d4bbf20f8 Mon Sep 17 00:00:00 2001 From: Piotr Ziecik Date: Thu, 20 Nov 2008 15:17:38 +0100 Subject: cfi_flash: Export flash_sector_size() function. Export flash_sector_size() function from drivers/mtd/cfi_flash.c, so that it can be used in the upcoming cfi-mtd driver. Signed-off-by: Piotr Ziecik Signed-off-by: Stefan Roese --- drivers/mtd/cfi_flash.c | 2 -- include/flash.h | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index f10d5fe..37af627 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -175,8 +175,6 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS]; /* FLASH chips info */ #define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_8BIT #endif -typedef unsigned long flash_sect_t; - /* CFI standard query structure */ struct cfi_qry { u8 qry[3]; diff --git a/include/flash.h b/include/flash.h index a6e91b5..8a00c2f 100644 --- a/include/flash.h +++ b/include/flash.h @@ -58,6 +58,8 @@ typedef struct { #endif } flash_info_t; +typedef unsigned long flash_sect_t; + /* * Values for the width of the port */ @@ -92,6 +94,7 @@ extern int flash_erase (flash_info_t *, int, int); extern int flash_sect_erase (ulong addr_first, ulong addr_last); extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); extern int flash_sect_roundb (ulong *addr); +extern unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect); /* common/flash.c */ extern void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); -- cgit v1.1 From 6ea808efdf9aa5d9067fbfac32acde8539129ed2 Mon Sep 17 00:00:00 2001 From: Piotr Ziecik Date: Mon, 17 Nov 2008 15:49:32 +0100 Subject: cfi_flash: Add interface for flash verbosity control Add interface for flash verbosity control. It allows to disable output from low-level flash API. It is useful when calling these low-level functions from context other than flash commands (for example the MTD/CFI interface implmentation). Signed-off-by: Piotr Ziecik Signed-off-by: Stefan Roese --- drivers/mtd/cfi_flash.c | 33 ++++++++++++++++++++++----------- include/flash.h | 1 + 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 37af627..b8422e1 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -158,6 +158,7 @@ typedef union { #define NUM_ERASE_REGIONS 4 /* max. number of erase regions */ static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT }; +static uint flash_verbose = 1; /* use CONFIG_SYS_MAX_FLASH_BANKS_DETECT if defined */ #ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT @@ -1070,7 +1071,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) if (prot) { printf ("- Warning: %d protected sectors will not be erased!\n", prot); - } else { + } else if (flash_verbose) { putc ('\n'); } @@ -1117,11 +1118,14 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) if (flash_full_status_check (info, sect, info->erase_blk_tout, "erase")) { rcode = 1; - } else + } else if (flash_verbose) putc ('.'); } } - puts (" done\n"); + + if (flash_verbose) + puts (" done\n"); + return rcode; } @@ -1233,14 +1237,16 @@ void flash_print_info (flash_info_t * info) */ #ifdef CONFIG_FLASH_SHOW_PROGRESS #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \ - dots -= dots_sub; \ - if ((scale > 0) && (dots <= 0)) { \ - if ((digit % 5) == 0) \ - printf ("%d", digit / 5); \ - else \ - putc ('.'); \ - digit--; \ - dots += scale; \ + if (flash_verbose) { \ + dots -= dots_sub; \ + if ((scale > 0) && (dots <= 0)) { \ + if ((digit % 5) == 0) \ + printf ("%d", digit / 5); \ + else \ + putc ('.'); \ + digit--; \ + dots += scale; \ + } \ } #else #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) @@ -1958,6 +1964,11 @@ ulong flash_get_size (ulong base, int banknum) return (info->size); } +void flash_set_verbose(uint v) +{ + flash_verbose = v; +} + /*----------------------------------------------------------------------- */ unsigned long flash_init (void) diff --git a/include/flash.h b/include/flash.h index 8a00c2f..05fa572 100644 --- a/include/flash.h +++ b/include/flash.h @@ -95,6 +95,7 @@ extern int flash_sect_erase (ulong addr_first, ulong addr_last); extern int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); extern int flash_sect_roundb (ulong *addr); extern unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect); +extern void flash_set_verbose(uint); /* common/flash.c */ extern void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); -- cgit v1.1 From 91809ed51d8327a8dbbf29aa98a091154c282171 Mon Sep 17 00:00:00 2001 From: Piotr Ziecik Date: Mon, 17 Nov 2008 15:57:58 +0100 Subject: cfi-mtd: Add cfi-mtd driver. Add cfi-mtd driver, which exports CFI flash to MTD layer. This allows CFI flash devices to be used from MTD layer. Building of the new driver is controlled by CONFIG_FLASH_CFI_MTD option. Initialization is done by calling cfi_mtd_init() from flash_init(). Signed-off-by: Piotr Ziecik Signed-off-by: Stefan Roese --- README | 5 ++ drivers/mtd/Makefile | 1 + drivers/mtd/cfi_flash.c | 5 ++ drivers/mtd/cfi_mtd.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ include/flash.h | 8 ++ 5 files changed, 221 insertions(+) create mode 100644 drivers/mtd/cfi_mtd.c diff --git a/README b/README index 9455fa7..861ea83 100644 --- a/README +++ b/README @@ -2157,6 +2157,11 @@ Configuration Settings: This option also enables the building of the cfi_flash driver in the drivers directory +- CONFIG_FLASH_CFI_MTD + This option enables the building of the cfi_mtd driver + in the drivers directory. The driver exports CFI flash + to the MTD layer. + - CONFIG_SYS_FLASH_USE_BUFFER_WRITE Use buffered writes to flash. diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 6538f7a..47687d0 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -27,6 +27,7 @@ LIB := $(obj)libmtd.a COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o +COBJS-$(CONFIG_FLASH_CFI_MTD) += cfi_mtd.o COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o COBJS-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o COBJS-$(CONFIG_MW_EEPROM) += mw_eeprom.o diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index b8422e1..e8afe99 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -2087,5 +2087,10 @@ unsigned long flash_init (void) flash_get_info(apl[i].start)); } #endif + +#ifdef CONFIG_FLASH_CFI_MTD + cfi_mtd_init(); +#endif + return (size); } diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c new file mode 100644 index 0000000..cf82d92 --- /dev/null +++ b/drivers/mtd/cfi_mtd.c @@ -0,0 +1,202 @@ +/* + * (C) Copyright 2008 Semihalf + * + * Written by: Piotr Ziecik + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include + +#include +#include + +extern flash_info_t flash_info[]; + +static struct mtd_info cfi_mtd_info[CONFIG_SYS_MAX_FLASH_BANKS]; + +static int cfi_mtd_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + flash_info_t *fi = mtd->priv; + size_t a_start = fi->start[0] + instr->addr; + size_t a_end = a_start + instr->len; + int s_first = -1; + int s_last = -1; + int error, sect; + + for (sect = 0; sect < fi->sector_count - 1; sect++) { + if (a_start == fi->start[sect]) + s_first = sect; + + if (a_end == fi->start[sect + 1]) { + s_last = sect; + break; + } + } + + if (s_first >= 0 && s_first <= s_last) { + instr->state = MTD_ERASING; + + flash_set_verbose(0); + error = flash_erase(fi, s_first, s_last); + flash_set_verbose(1); + + if (error) { + instr->state = MTD_ERASE_FAILED; + return -EIO; + } + + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + return 0; + } + + return -EINVAL; +} + +static int cfi_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + flash_info_t *fi = mtd->priv; + u_char *f = (u_char*)(fi->start[0]) + from; + + memcpy(buf, f, len); + *retlen = len; + + return 0; +} + +static int cfi_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + flash_info_t *fi = mtd->priv; + u_long t = fi->start[0] + to; + int error; + + flash_set_verbose(0); + error = write_buff(fi, (u_char*)buf, t, len); + flash_set_verbose(1); + + if (!error) { + *retlen = len; + return 0; + } + + return -EIO; +} + +static void cfi_mtd_sync(struct mtd_info *mtd) +{ + /* + * This function should wait until all pending operations + * finish. However this driver is fully synchronous, so + * this function returns immediately + */ +} + +static int cfi_mtd_lock(struct mtd_info *mtd, loff_t ofs, size_t len) +{ + flash_info_t *fi = mtd->priv; + + flash_set_verbose(0); + flash_protect(FLAG_PROTECT_SET, fi->start[0] + ofs, + fi->start[0] + ofs + len - 1, fi); + flash_set_verbose(1); + + return 0; +} + +static int cfi_mtd_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) +{ + flash_info_t *fi = mtd->priv; + + flash_set_verbose(0); + flash_protect(FLAG_PROTECT_CLEAR, fi->start[0] + ofs, + fi->start[0] + ofs + len - 1, fi); + flash_set_verbose(1); + + return 0; +} + +static int cfi_mtd_set_erasesize(struct mtd_info *mtd, flash_info_t *fi) +{ + int sect_size = 0; + int sect; + + for (sect = 0; sect < fi->sector_count; sect++) { + if (!sect_size) { + sect_size = flash_sector_size(fi, sect); + continue; + } + + if (sect_size != flash_sector_size(fi, sect)) { + sect_size = 0; + break; + } + } + + if (!sect_size) { + puts("cfi-mtd: devices with multiple sector sizes are" + "not supported\n"); + return -EINVAL; + } + + mtd->erasesize = sect_size; + + return 0; +} + +int cfi_mtd_init(void) +{ + struct mtd_info *mtd; + flash_info_t *fi; + int error, i; + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + fi = &flash_info[i]; + mtd = &cfi_mtd_info[i]; + + memset(mtd, 0, sizeof(struct mtd_info)); + + error = cfi_mtd_set_erasesize(mtd, fi); + if (error) + continue; + + mtd->name = CFI_MTD_DEV_NAME; + mtd->type = MTD_NORFLASH; + mtd->flags = MTD_CAP_NORFLASH; + mtd->size = fi->size; + mtd->writesize = 1; + + mtd->erase = cfi_mtd_erase; + mtd->read = cfi_mtd_read; + mtd->write = cfi_mtd_write; + mtd->sync = cfi_mtd_sync; + mtd->lock = cfi_mtd_lock; + mtd->unlock = cfi_mtd_unlock; + mtd->priv = fi; + + if (add_mtd_device(mtd)) + return -ENOMEM; + } + + return 0; +} diff --git a/include/flash.h b/include/flash.h index 05fa572..6e2981c 100644 --- a/include/flash.h +++ b/include/flash.h @@ -86,6 +86,9 @@ typedef unsigned long flash_sect_t; /* convert between bit value and numeric value */ #define CFI_FLASH_SHIFT_WIDTH 3 + +/* cfi-mtd device name */ +#define CFI_MTD_DEV_NAME "cfi-mtd" /* Prototypes */ extern unsigned long flash_init (void); @@ -103,6 +106,11 @@ extern int flash_write (char *, ulong, ulong); extern flash_info_t *addr2info (ulong); extern int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); +/* drivers/mtd/cfi_mtd.c */ +#ifdef CONFIG_FLASH_CFI_MTD +extern int cfi_mtd_init(void); +#endif + /* board/?/flash.c */ #if defined(CONFIG_SYS_FLASH_PROTECTION) extern int flash_real_protect(flash_info_t *info, long sector, int prot); -- cgit v1.1 From e6a7edbc1778d27431ac663b40a71dafa5d20578 Mon Sep 17 00:00:00 2001 From: Piotr Ziecik Date: Mon, 17 Nov 2008 15:57:59 +0100 Subject: mtd: Remove a printf() from add_mtd_device(). Remove a printf() from add_mtd_device(), which produces spurious output. Signed-off-by: Piotr Ziecik Signed-off-by: Stefan Roese --- drivers/mtd/mtdcore.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 64bd7d4..6eb52ed 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -25,8 +25,6 @@ int add_mtd_device(struct mtd_info *mtd) mtd->index = i; mtd->usecount = 0; - printf("mtd: Giving out device %d to %s\n", - i, mtd->name); /* No need to get a refcount on the module containing the notifier, since we hold the mtd_table_mutex */ -- cgit v1.1 From 25ea652e907516a283b38237e83712a918f125d7 Mon Sep 17 00:00:00 2001 From: Piotr Ziecik Date: Mon, 17 Nov 2008 15:58:00 +0100 Subject: UBI: Add proof-of-concept CFI flash support With this patch UBI can be used on CFI flash chips. Signed-off-by: Piotr Ziecik Signed-off-by: Stefan Roese --- common/cmd_ubi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 57ce3cc..8446765 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -26,6 +26,7 @@ #define DEV_TYPE_NONE 0 #define DEV_TYPE_NAND 1 #define DEV_TYPE_ONENAND 2 +#define DEV_TYPE_NOR 3 /* Private own data */ static struct ubi_device *ubi; @@ -472,6 +473,13 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ubi_dev.mtd_info = &nand_info[ubi_dev.nr]; } #endif +#if defined(CONFIG_FLASH_CFI_MTD) + if (strcmp(argv[2], "nor") == 0) { + strcpy(ubi_dev.dev_name, "NOR"); + ubi_dev.type = DEV_TYPE_NOR; + ubi_dev.mtd_info = get_mtd_device_nm(CFI_MTD_DEV_NAME); + } +#endif #if defined(CONFIG_CMD_ONENAND) if (strcmp(argv[2], "onenand") == 0) { strcpy(ubi_dev.dev_name, "OneNAND"); @@ -581,7 +589,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD(ubi, 6, 1, do_ubi, "ubi - ubi commands\n", - "part [nand|onenand] [part]" + "part [nand|nor|onenand] [part]" " - Show or set current partition\n" "ubi info [l[ayout]]" " - Display volume and ubi layout information\n" -- cgit v1.1 From 8052352f20b33bef8f9872fc983eac73d4693c38 Mon Sep 17 00:00:00 2001 From: Jens Scharsig Date: Tue, 18 Nov 2008 10:48:46 +0100 Subject: at91rm9200: fix broken boot from nor flash This patch fix the broken boot from NOR Flash on AT91RM9200 boards, if CONFIG_AT91RM9200 is defined and nor preloader is used. Signed-off-by: Jens Scharsig --- cpu/arm920t/start.S | 5 +---- include/configs/at91rm9200dk.h | 2 ++ include/configs/cmc_pu2.h | 2 ++ include/configs/csb637.h | 2 ++ include/configs/kb9202.h | 2 ++ include/configs/mp2usb.h | 2 ++ 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S index 17977c2..f99d129 100644 --- a/cpu/arm920t/start.S +++ b/cpu/arm920t/start.S @@ -24,7 +24,6 @@ * MA 02111-1307 USA */ - #include #include #include @@ -178,8 +177,6 @@ copyex: bl cpu_init_crit #endif -#ifndef CONFIG_AT91RM9200 - #ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ @@ -198,7 +195,7 @@ copy_loop: cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop #endif /* CONFIG_SKIP_RELOCATE_UBOOT */ -#endif + /* Set up the stack */ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ diff --git a/include/configs/at91rm9200dk.h b/include/configs/at91rm9200dk.h index 633a053..5c239d7 100644 --- a/include/configs/at91rm9200dk.h +++ b/include/configs/at91rm9200dk.h @@ -72,6 +72,8 @@ #define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ #define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ #define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#else +#define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ /* * Size of malloc() pool diff --git a/include/configs/cmc_pu2.h b/include/configs/cmc_pu2.h index 527921e..cdd308d 100644 --- a/include/configs/cmc_pu2.h +++ b/include/configs/cmc_pu2.h @@ -71,6 +71,8 @@ #define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ #define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ #define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#else +#define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ /* diff --git a/include/configs/csb637.h b/include/configs/csb637.h index 38fd25c..682db44 100644 --- a/include/configs/csb637.h +++ b/include/configs/csb637.h @@ -72,6 +72,8 @@ #define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ #define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ #define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#else +#define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ /* * Size of malloc() pool diff --git a/include/configs/kb9202.h b/include/configs/kb9202.h index 55cda32..1ce8c69 100644 --- a/include/configs/kb9202.h +++ b/include/configs/kb9202.h @@ -51,6 +51,8 @@ #define CONFIG_INITRD_TAG 1 #define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_SKIP_RELOCATE_UBOOT /* undef this for direct boot from */ + /* NOR flash without preloader */ #define CONFIG_SYS_LONGHELP diff --git a/include/configs/mp2usb.h b/include/configs/mp2usb.h index 2ffeae6..cbbdb0c 100644 --- a/include/configs/mp2usb.h +++ b/include/configs/mp2usb.h @@ -76,6 +76,8 @@ #define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ #define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ #define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#else +#define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ /* -- cgit v1.1 From 58c696eed839af894e0265064669c402dc28b371 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 24 Nov 2008 21:50:59 +0100 Subject: AT91RM9200DK: fix broken boot from NOR flash Signed-off-by: Wolfgang Denk --- cpu/arm920t/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S index f99d129..5143cfc 100644 --- a/cpu/arm920t/start.S +++ b/cpu/arm920t/start.S @@ -258,7 +258,7 @@ cpu_init_crit: * find a lowlevel_init.S in your board directory. */ mov ip, lr -#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF) +#if defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF) #else bl lowlevel_init -- cgit v1.1 From 348c849d86a6f0785752b9bc497a34658713d1d1 Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Mon, 24 Nov 2008 15:11:08 +0100 Subject: ppc4xx: Remove unused code from PCI405 code Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/pci405/cmd_pci405.c | 871 ------------------------------------------ 1 file changed, 871 deletions(-) diff --git a/board/esd/pci405/cmd_pci405.c b/board/esd/pci405/cmd_pci405.c index 5c717e25..f558a2b 100644 --- a/board/esd/pci405/cmd_pci405.c +++ b/board/esd/pci405/cmd_pci405.c @@ -32,13 +32,9 @@ #include "pci405.h" - #if defined(CONFIG_CMD_BSP) extern int do_bootm (cmd_tbl_t *, int, int, char *[]); -extern int do_bootvx (cmd_tbl_t *, int, int, char *[]); -unsigned long get_dcr(unsigned short); - /* * Command loadpci: wait for signal from host and boot image. @@ -97,33 +93,6 @@ int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } else { sprintf(addr, "%08x", *ptr); -#if 0 - /* - * Boot image - */ - if (*ptr & 0x00000001) { - /* - * Boot VxWorks image via bootvx - */ - addr[strlen(addr)-1] = '0'; - printf("\nBooting VxWorks-Image at addr 0x%s ...\n", addr); - setenv("loadaddr", addr); - - local_args[0] = argv[0]; - local_args[1] = NULL; - status = do_bootvx (cmdtp, 0, 1, local_args); - } else { - /* - * Boot image via bootm (normally Linux) - */ - printf("\nBooting Image at addr 0x%s ...\n", addr); - setenv("loadaddr", addr); - - local_args[0] = argv[0]; - local_args[1] = NULL; - status = do_bootm (cmdtp, 0, 1, local_args); - } -#else /* * Boot image via bootm */ @@ -133,7 +102,6 @@ int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) local_args[0] = argv[0]; local_args[1] = NULL; status = do_bootm (cmdtp, 0, 1, local_args); -#endif } return 0; @@ -143,843 +111,4 @@ U_BOOT_CMD( "loadpci - Wait for pci-image and boot it\n", NULL ); - -#endif - -#if 1 /* test-only */ -int do_getpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int val; - int i; - - printf("\nPCI Configuration Regs for PPC405GP:"); - for (i=0; i<0x64; i+=4) { - pci_read_config_dword(PCIDEVID_405GP, i, &val); - if (!(i % 0x10)) { - printf("\n%02x: ", i); - } - printf("%08x ", val); - } - printf("\n"); - - return 0; -} -U_BOOT_CMD( - getpci, 1, 1, do_getpci, - "getpci - Print own pci configuration registers\n", - NULL -); - -int do_setpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int addr; - unsigned int val; - - addr = simple_strtol (argv[1], NULL, 16); - val = simple_strtol (argv[2], NULL, 16); - - printf("\nWriting %08x to PCI reg %08x.\n", val, addr); - pci_write_config_dword(PCIDEVID_405GP, addr, val); - - return 0; -} -U_BOOT_CMD( - setpci, 3, 1, do_setpci, - "setpci - Set one pci configuration lword\n", - " \n" - " - Write pci configuration lword to .\n" -); - -int do_dumpdcr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int i; - - printf("\nDevice Configuration Registers (DCR's) for PPC405GP:"); - for (i=0; i<=0x1e0; i++) { - if (!(i % 0x8)) { - printf("\n%04x ", i); - } - printf("%08lx ", get_dcr(i)); - } - printf("\n"); - - return 0; -} -U_BOOT_CMD( - dumpdcr, 1, 1, do_dumpdcr, - "dumpdcr - Dump all DCR registers\n", - NULL -); - - -int do_dumpspr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - printf("\nSpecial Purpose Registers (SPR's) for PPC405GP:"); - printf("\n%04x %08x ", 947, mfspr(947)); - printf("\n%04x %08x ", 9, mfspr(9)); - printf("\n%04x %08x ", 1014, mfspr(1014)); - printf("\n%04x %08x ", 1015, mfspr(1015)); - printf("\n%04x %08x ", 1010, mfspr(1010)); - printf("\n%04x %08x ", 957, mfspr(957)); - printf("\n%04x %08x ", 1008, mfspr(1008)); - printf("\n%04x %08x ", 1018, mfspr(1018)); - printf("\n%04x %08x ", 954, mfspr(954)); - printf("\n%04x %08x ", 950, mfspr(950)); - printf("\n%04x %08x ", 951, mfspr(951)); - printf("\n%04x %08x ", 981, mfspr(981)); - printf("\n%04x %08x ", 980, mfspr(980)); - printf("\n%04x %08x ", 982, mfspr(982)); - printf("\n%04x %08x ", 1012, mfspr(1012)); - printf("\n%04x %08x ", 1013, mfspr(1013)); - printf("\n%04x %08x ", 948, mfspr(948)); - printf("\n%04x %08x ", 949, mfspr(949)); - printf("\n%04x %08x ", 1019, mfspr(1019)); - printf("\n%04x %08x ", 979, mfspr(979)); - printf("\n%04x %08x ", 8, mfspr(8)); - printf("\n%04x %08x ", 945, mfspr(945)); - printf("\n%04x %08x ", 987, mfspr(987)); - printf("\n%04x %08x ", 287, mfspr(287)); - printf("\n%04x %08x ", 953, mfspr(953)); - printf("\n%04x %08x ", 955, mfspr(955)); - printf("\n%04x %08x ", 272, mfspr(272)); - printf("\n%04x %08x ", 273, mfspr(273)); - printf("\n%04x %08x ", 274, mfspr(274)); - printf("\n%04x %08x ", 275, mfspr(275)); - printf("\n%04x %08x ", 260, mfspr(260)); - printf("\n%04x %08x ", 276, mfspr(276)); - printf("\n%04x %08x ", 261, mfspr(261)); - printf("\n%04x %08x ", 277, mfspr(277)); - printf("\n%04x %08x ", 262, mfspr(262)); - printf("\n%04x %08x ", 278, mfspr(278)); - printf("\n%04x %08x ", 263, mfspr(263)); - printf("\n%04x %08x ", 279, mfspr(279)); - printf("\n%04x %08x ", 26, mfspr(26)); - printf("\n%04x %08x ", 27, mfspr(27)); - printf("\n%04x %08x ", 990, mfspr(990)); - printf("\n%04x %08x ", 991, mfspr(991)); - printf("\n%04x %08x ", 956, mfspr(956)); - printf("\n%04x %08x ", 284, mfspr(284)); - printf("\n%04x %08x ", 285, mfspr(285)); - printf("\n%04x %08x ", 986, mfspr(986)); - printf("\n%04x %08x ", 984, mfspr(984)); - printf("\n%04x %08x ", 256, mfspr(256)); - printf("\n%04x %08x ", 1, mfspr(1)); - printf("\n%04x %08x ", 944, mfspr(944)); - printf("\n"); - - return 0; -} -U_BOOT_CMD( - dumpspr, 1, 1, do_dumpspr, - "dumpspr - Dump all SPR registers\n", - NULL -); - - -#define PCI0_BRDGOPT1 0x4a -#define plb0_acr 0x87 - -int do_getplb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned short val; - - printf("PLB0_ACR=%08lx\n", get_dcr(0x87)); - pci_read_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, &val); - printf("PCI0_BRDGOPT1=%04x\n", val); - printf("CCR0=%08x\n", mfspr(ccr0)); - - return 0; -} -U_BOOT_CMD( - getplb, 1, 1, do_getplb, - "getplb - Dump all plb arbiter registers\n", - NULL -); - -int do_setplb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int my_acr; - unsigned int my_brdgopt1; - unsigned int my_ccr0; - - my_acr = simple_strtol (argv[1], NULL, 16); - my_brdgopt1 = simple_strtol (argv[2], NULL, 16); - my_ccr0 = simple_strtol (argv[3], NULL, 16); - - mtdcr(plb0_acr, my_acr); - pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, my_brdgopt1); - mtspr(ccr0, my_ccr0); - - return 0; -} -U_BOOT_CMD( - setplb, 4, 1, do_setplb, - "setplb - Set all plb arbiter registers\n", - "PLB0_ACR PCI0_BRDGOPT1 CCR0\n" - " - Set all plb arbiter registers\n" -); - - -/*********************************************************************** - * - * The following code is only for test purposes!!!! - * Please ignore this ugly stuff!!!!!!!!!!!!!!!!!!! - * - ***********************************************************************/ - -#define PCI_ADDR 0xc0000000 - -int do_writepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int addr; - unsigned int size; - unsigned int countmax; - int i; - int max; - volatile unsigned long *ptr; - volatile unsigned long val; - int loopcount = 0; - int test_pci_read = 0; - int test_pci_cfg_write = 0; - int test_sync = 0; - int test_pci_pre_read = 0; - - addr = simple_strtol (argv[1], NULL, 16); - size = simple_strtol (argv[2], NULL, 16); - countmax = simple_strtol (argv[3], NULL, 16); - if (countmax == 0) - countmax = 1000; - - do_getplb(NULL, 0, 0, NULL); - -#if 0 - out32r(PMM0LA, 0); - out32r(PMM0PCILA, 0); - out32r(PMM0PCIHA, 0); - out32r(PMM0MA, 0); - out32r(PMM1LA, PCI_ADDR); - out32r(PMM1PCILA, addr & 0xff000000); - out32r(PMM1PCIHA, 0x00000000); - out32r(PMM1MA, 0xff000001); -#endif - - printf("PMM1LA =%08lx\n", in32r(PMM1LA)); - printf("PMM1MA =%08lx\n", in32r(PMM1MA)); - printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); - printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); - - addr = PCI_ADDR | (addr & 0x00ffffff); - printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); - - max = size >> 2; - - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - val = *(ulong *)0x00000000; - if (val & 0x00000008) { - test_pci_pre_read = 1; - printf("Running test with pre pci-memory-read access!\n"); - } - if (val & 0x00000004) { - test_sync = 1; - printf("Running test with sync instruction!\n"); - } - if (val & 0x00000001) { - test_pci_read = 1; - printf("Running test with pci-memory-read access!\n"); - } - if (val & 0x00000002) { - test_pci_cfg_write = 1; - printf("Running test with pci-config-write access!\n"); - } - - while (1) { - - if (test_pci_pre_read) { - /* - * Read one value back - */ - ptr = (volatile unsigned long *)addr; - val = *ptr; - } - - /* - * Write some values to host via pci busmastering - */ - ptr = (volatile unsigned long *)addr; - for (i=0; i countmax) { - /* Abort if ctrl-c was pressed */ - if (ctrlc()) { - puts("\nAbort\n"); - return 0; - } - - putc('.'); - - loopcount = 0; - } - } - - return 0; -} -U_BOOT_CMD( - writepci, 4, 1, do_writepci, - "writepci - Write some data to pcibus\n", - " \n" - " - Write some data to pcibus.\n" -); - -#define PCI_CFGADDR 0xeec00000 -#define PCI_CFGDATA 0xeec00004 - -int ibmPciConfigWrite -( - int offset, /* offset into the configuration space */ - int width, /* data width */ - unsigned int data /* data to be written */ - ) -{ - /* - * Write config register address to the PCI config address register - * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) - */ - out32r(PCI_CFGADDR, 0x80000000 | (offset & 0xFFFFFFFC)); - -#if 0 /* test-only */ - ppcSync(); -#endif - - /* - * Write value to be written to the PCI config data register - */ - switch ( width ) { - case 1: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned char)(data & 0xFF)); - break; - case 2: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned short)(data & 0xFFFF)); - break; - case 4: out32r(PCI_CFGDATA | (offset & 0x3), data); - break; - } - - return (0); -} - -int do_writepci2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int addr; - unsigned int size; - unsigned int countmax; - int max; - volatile unsigned long *ptr; - volatile unsigned long val; - int loopcount = 0; - - addr = simple_strtol (argv[1], NULL, 16); - size = simple_strtol (argv[2], NULL, 16); - countmax = simple_strtol (argv[3], NULL, 16); - if (countmax == 0) - countmax = 1000; - - do_getplb(NULL, 0, 0, NULL); - -#if 0 - out32r(PMM0LA, 0); - out32r(PMM0PCILA, 0); - out32r(PMM0PCIHA, 0); - out32r(PMM0MA, 0); - out32r(PMM1LA, PCI_ADDR); - out32r(PMM1PCILA, addr & 0xff000000); - out32r(PMM1PCIHA, 0x00000000); - out32r(PMM1MA, 0xff000001); -#endif - - printf("PMM1LA =%08lx\n", in32r(PMM1LA)); - printf("PMM1MA =%08lx\n", in32r(PMM1MA)); - printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); - printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); - - addr = PCI_ADDR | (addr & 0x00ffffff); - printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); - - max = size >> 2; - - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - while (1) { - - /* - * Write one values to host via pci busmastering - */ - ptr = (volatile unsigned long *)addr; - *ptr = 0x01234567; - - /* - * Read one value back - */ - ptr = (volatile unsigned long *)addr; - val = *ptr; - - /* - * One pci config write - */ -/* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ -/* ibmPciConfigWrite(0x44, 1, 0x00); */ - ibmPciConfigWrite(0x2e, 2, 0x1234); /* subsystem id */ - - if (loopcount++ > countmax) { - /* Abort if ctrl-c was pressed */ - if (ctrlc()) { - puts("\nAbort\n"); - return 0; - } - - putc('.'); - - loopcount = 0; - } - } - - return 0; -} -U_BOOT_CMD( - writepci2, 4, 1, do_writepci2, - "writepci2- Write some data to pcibus\n", - " \n" - " - Write some data to pcibus.\n" -); - -int do_writepci22(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int addr; - unsigned int size; - unsigned int countmax = 0; - volatile unsigned long *ptr; - volatile unsigned long val; - - addr = simple_strtol (argv[1], NULL, 16); - size = simple_strtol (argv[2], NULL, 16); - - addr = PCI_ADDR | (addr & 0x00ffffff); - printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - while (1) { - - /* - * Write one values to host via pci busmastering - */ - ptr = (volatile unsigned long *)addr; - *ptr = 0x01234567; - - /* - * Read one value back - */ - ptr = (volatile unsigned long *)addr; - val = *ptr; - - /* - * One pci config write - */ - ibmPciConfigWrite(0x2e, 2, 0x1234); /* subsystem id */ - } - - return 0; -} -U_BOOT_CMD( - writepci22, 4, 1, do_writepci22, - "writepci22- Write some data to pcibus\n", - " \n" - " - Write some data to pcibus.\n" -); - -int ibmPciConfigWrite3 -( - int offset, /* offset into the configuration space */ - int width, /* data width */ - unsigned int data /* data to be written */ - ) -{ - /* - * Write config register address to the PCI config address register - * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) - */ - out32r(PCI_CFGADDR, 0x80000000 | (offset & 0xFFFFFFFC)); - -#if 1 /* test-only */ - ppcSync(); -#endif - - /* - * Write value to be written to the PCI config data register - */ - switch ( width ) { - case 1: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned char)(data & 0xFF)); - break; - case 2: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned short)(data & 0xFFFF)); - break; - case 4: out32r(PCI_CFGDATA | (offset & 0x3), data); - break; - } - - return (0); -} - -int do_writepci3(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int addr; - unsigned int size; - unsigned int countmax; - int max; - volatile unsigned long *ptr; - volatile unsigned long val; - int loopcount = 0; - - addr = simple_strtol (argv[1], NULL, 16); - size = simple_strtol (argv[2], NULL, 16); - countmax = simple_strtol (argv[3], NULL, 16); - if (countmax == 0) - countmax = 1000; - - do_getplb(NULL, 0, 0, NULL); - -#if 0 - out32r(PMM0LA, 0); - out32r(PMM0PCILA, 0); - out32r(PMM0PCIHA, 0); - out32r(PMM0MA, 0); - out32r(PMM1LA, PCI_ADDR); - out32r(PMM1PCILA, addr & 0xff000000); - out32r(PMM1PCIHA, 0x00000000); - out32r(PMM1MA, 0xff000001); -#endif - - printf("PMM1LA =%08lx\n", in32r(PMM1LA)); - printf("PMM1MA =%08lx\n", in32r(PMM1MA)); - printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); - printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); - - addr = PCI_ADDR | (addr & 0x00ffffff); - printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); - - max = size >> 2; - - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - while (1) { - - /* - * Write one values to host via pci busmastering - */ - ptr = (volatile unsigned long *)addr; - *ptr = 0x01234567; - - /* - * Read one value back - */ - ptr = (volatile unsigned long *)addr; - val = *ptr; - - /* - * One pci config write - */ -/* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ -/* ibmPciConfigWrite(0x44, 1, 0x00); */ - ibmPciConfigWrite3(0x2e, 2, 0x1234); /* subsystem id */ - - if (loopcount++ > countmax) { - /* Abort if ctrl-c was pressed */ - if (ctrlc()) { - puts("\nAbort\n"); - return 0; - } - - putc('.'); - - loopcount = 0; - } - } - - return 0; -} -U_BOOT_CMD( - writepci3, 4, 1, do_writepci3, - "writepci3- Write some data to pcibus\n", - " \n" - " - Write some data to pcibus.\n" -); - - -#define SECTOR_SIZE 32 /* 32 byte cache line */ -#define SECTOR_MASK 0x1F - -void my_flush_dcache(ulong lcl_addr, ulong count) -{ - unsigned int lcl_target; - - /* promote to nearest cache sector */ - lcl_target = (lcl_addr + count + SECTOR_SIZE - 1) & ~SECTOR_MASK; - lcl_addr &= ~SECTOR_MASK; - while (lcl_addr != lcl_target) - { - /* ppcDcbf((void *)lcl_addr);*/ - __asm__("dcbf 0,%0": :"r" (lcl_addr)); - lcl_addr += SECTOR_SIZE; - } - __asm__("sync"); /* Always flush prefetch queue in any case */ -} - -int do_writepci_cache(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int addr; - unsigned int size; - unsigned int countmax; - int i; - volatile unsigned long *ptr; - volatile unsigned long val; - int loopcount = 0; - - addr = simple_strtol (argv[1], NULL, 16); - size = simple_strtol (argv[2], NULL, 16); - countmax = simple_strtol (argv[3], NULL, 16); - if (countmax == 0) - countmax = 1000; - - do_getplb(NULL, 0, 0, NULL); - -#if 0 - out32r(PMM0LA, 0); - out32r(PMM0PCILA, 0); - out32r(PMM0PCIHA, 0); - out32r(PMM0MA, 0); - out32r(PMM1LA, PCI_ADDR); - out32r(PMM1PCILA, addr & 0xff000000); - out32r(PMM1PCIHA, 0x00000000); - out32r(PMM1MA, 0xff000001); -#endif - - printf("PMM1LA =%08lx\n", in32r(PMM1LA)); - printf("PMM1MA =%08lx\n", in32r(PMM1MA)); - printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); - printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); - - addr = PCI_ADDR | (addr & 0x00ffffff); - printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); - - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - i = 0; - - /* - * Set pci region as cachable - */ - ppcSync(); - __asm__ volatile (" addis 4,0,0x0000 "); - __asm__ volatile (" addi 4,4,0x0080 "); - __asm__ volatile (" mtdccr 4 "); - ppcSync(); - - while (1) { - - /* - * Write one values to host via pci busmastering - */ - ptr = (volatile unsigned long *)addr; - printf("A\n"); /* test-only */ - *ptr++ = i++; - *ptr++ = i++; - *ptr++ = i++; - *ptr++ = i++; - *ptr++ = i++; - *ptr++ = i++; - *ptr++ = i++; - *ptr++ = i++; - printf("B\n"); /* test-only */ - my_flush_dcache(addr, 32); - printf("C\n"); /* test-only */ - - /* - * Read one value back - */ - ptr = (volatile unsigned long *)addr; - val = *ptr; - printf("D\n"); /* test-only */ - - /* - * One pci config write - */ -/* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ -/* ibmPciConfigWrite(0x44, 1, 0x00); */ - ibmPciConfigWrite3(0x2e, 2, 0x1234); /* subsystem id */ - printf("E\n"); /* test-only */ - - if (loopcount++ > countmax) { - /* Abort if ctrl-c was pressed */ - if (ctrlc()) { - puts("\nAbort\n"); - return 0; - } - - putc('.'); - - loopcount = 0; - } - } - - return 0; -} -U_BOOT_CMD( - writepci_cache, 4, 1, do_writepci_cache, - "writepci_cache - Write some data to pcibus\n", - " \n" - " - Write some data to pcibus.\n" -); - -int do_savepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int *ptr; - int i; - - /* - * Save own pci configuration in PRAM - */ - memset((char *)PCI_REGS_ADDR, 0, PCI_REGS_LEN); - ptr = (unsigned int *)PCI_REGS_ADDR + 1; - for (i=0; i<0x40; i+=4) { - pci_read_config_dword(PCIDEVID_405GP, i, ptr++); - } - ptr = (unsigned int *)PCI_REGS_ADDR; - *ptr = crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4); - - printf("\nStoring PCI Configuration Regs...\n"); - - return 0; -} -U_BOOT_CMD( - savepci, 4, 1, do_savepci, - "savepci - Save all pci regs\n", - " \n" - " - Write some data to pcibus.\n" -); - -int do_restorepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - unsigned int *ptr; - int i; - - /* - * Rewrite pci config regs (only after soft-reset with magic set) - */ - ptr = (unsigned int *)PCI_REGS_ADDR; - if (crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) { - puts("Restoring PCI Configurations Regs!\n"); - ptr = (unsigned int *)PCI_REGS_ADDR + 1; - for (i=0; i<0x40; i+=4) { - pci_write_config_dword(PCIDEVID_405GP, i, *ptr++); - } - } - mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ - - return 0; -} -U_BOOT_CMD( - restorepci, 4, 1, do_restorepci, - "restorepci - Restore all pci regs\n", - " \n" - " - Write some data to pcibus.\n" -); - - -extern void write_without_sync(void); -extern void write_with_sync(void); -extern void write_with_less_sync(void); -extern void write_with_more_sync(void); - -/* - * code from IBM-PPCSUPP - */ -int do_writeibm1(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - write_without_sync(); - - return 0; -} -U_BOOT_CMD( - writeibm1, 4, 1, do_writeibm1, - "writeibm1- Write some data to pcibus (without sync)\n", - " \n" - " - Write some data to pcibus.\n" -); - -int do_writeibm2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - write_with_sync(); - - return 0; -} -U_BOOT_CMD( - writeibm2, 4, 1, do_writeibm2, - "writeibm2- Write some data to pcibus (with sync)\n", - " \n" - " - Write some data to pcibus.\n" -); - -int do_writeibm22(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - write_with_less_sync(); - - return 0; -} -U_BOOT_CMD( - writeibm22, 4, 1, do_writeibm22, - "writeibm22- Write some data to pcibus (with less sync)\n", - " \n" - " - Write some data to pcibus.\n" -); - -int do_writeibm3(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ - - write_with_more_sync(); - - return 0; -} -U_BOOT_CMD( - writeibm3, 4, 1, do_writeibm3, - "writeibm3- Write some data to pcibus (with more sync)\n", - " \n" - " - Write some data to pcibus.\n" -); #endif -- cgit v1.1 From 0c2385c3bb51f5d3911fce1ec4720db86b534c2b Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Mon, 24 Nov 2008 15:11:09 +0100 Subject: ppc4xx: Use correct io accessors for PCI405 Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/pci405/pci405.c | 51 +++++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/board/esd/pci405/pci405.c b/board/esd/pci405/pci405.c index 9112788..42774ad 100644 --- a/board/esd/pci405/pci405.c +++ b/board/esd/pci405/pci405.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "pci405.h" @@ -34,7 +35,7 @@ DECLARE_GLOBAL_DATA_PTR; /* Prototypes */ int gunzip(void *, int, unsigned char *, unsigned long *); -int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);/*cmd_boot.c*/ +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); unsigned long fpga_done_state(void); unsigned long fpga_init_state(void); @@ -57,11 +58,11 @@ const unsigned char fpgadata[] = */ #include "../common/fpga.c" -#define FPGA_DONE_STATE_V11 (in32(GPIO0_IR) & CONFIG_SYS_FPGA_DONE) -#define FPGA_DONE_STATE_V12 (in32(GPIO0_IR) & CONFIG_SYS_FPGA_DONE_V12) +#define FPGA_DONE_STATE_V11 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_DONE) +#define FPGA_DONE_STATE_V12 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_DONE_V12) -#define FPGA_INIT_STATE_V11 (in32(GPIO0_IR) & CONFIG_SYS_FPGA_INIT) -#define FPGA_INIT_STATE_V12 (in32(GPIO0_IR) & CONFIG_SYS_FPGA_INIT_V12) +#define FPGA_INIT_STATE_V11 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_INIT) +#define FPGA_INIT_STATE_V12 (in_be32((void*)GPIO0_IR) & CONFIG_SYS_FPGA_INIT_V12) int board_revision(void) @@ -78,10 +79,10 @@ int board_revision(void) */ cntrl0Reg = mfdcr(cntrl0); mtdcr(cntrl0, cntrl0Reg | 0x03000000); - out32(GPIO0_ODR, in32(GPIO0_ODR) & ~0x00100200); - out32(GPIO0_TCR, in32(GPIO0_TCR) & ~0x00100200); + out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x00100200); + out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x00100200); udelay(1000); /* wait some time before reading input */ - value = in32(GPIO0_IR) & 0x00100200; /* get config bits */ + value = in_be32((void*)GPIO0_IR) & 0x00100200; /* get config bits */ /* * Restore GPIO settings @@ -137,10 +138,10 @@ int board_early_init_f (void) /* * First pull fpga-prg pin low, to disable fpga logic (on version 1.2 board) */ - out32(GPIO0_ODR, 0x00000000); /* no open drain pins */ - out32(GPIO0_TCR, CONFIG_SYS_FPGA_PRG); /* setup for output */ - out32(GPIO0_OR, CONFIG_SYS_FPGA_PRG); /* set output pins to high */ - out32(GPIO0_OR, 0); /* pull prg low */ + out_be32((void*)GPIO0_ODR, 0x00000000); /* no open drain pins */ + out_be32((void*)GPIO0_TCR, CONFIG_SYS_FPGA_PRG); /* setup for output */ + out_be32((void*)GPIO0_OR, CONFIG_SYS_FPGA_PRG); /* set output pins to high */ + out_be32((void*)GPIO0_OR, 0); /* pull prg low */ /* * IRQ 0-15 405GP internally generated; active high; level sensitive @@ -181,15 +182,6 @@ int board_early_init_f (void) return 0; } - -/* ------------------------------------------------------------------------- */ - -int misc_init_f (void) -{ - return 0; /* dummy implementation */ -} - - int misc_init_r (void) { unsigned char *dst; @@ -284,13 +276,11 @@ int misc_init_r (void) *magic = 0; /* clear pci reconfig magic again */ } -#if 1 /* test-only */ /* * Decrease PLB latency timeout and reduce priority of the PCI bridge master */ #define PCI0_BRDGOPT1 0x4a pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, 0x3f20); -/* pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, 0x3f60); */ #define plb0_acr 0x87 /* @@ -298,14 +288,6 @@ int misc_init_r (void) */ mtdcr(plb0_acr, 0x98000000); -#if 0 /* test-only */ - printf("CCR0=%08x\n", mfspr(ccr0)); /* test-only */ -/* mtspr(ccr0, (mfspr(ccr0) & 0xff8fffff) | 0x00100000); */ - mtspr(ccr0, (mfspr(ccr0) & 0xff8fffff) | 0x00000000); -#endif -/* printf("CCR0=%08x\n", mfspr(ccr0)); */ /* test-only */ -#endif - free(dst); return (0); } @@ -314,7 +296,6 @@ int misc_init_r (void) /* * Check Board Identity: */ - int checkboard (void) { char str[64]; @@ -340,10 +321,10 @@ int checkboard (void) */ cntrl0Reg = mfdcr(cntrl0); mtdcr(cntrl0, cntrl0Reg & ~0x08000000); - out32(GPIO0_ODR, in32(GPIO0_ODR) & ~0x40000000); - out32(GPIO0_TCR, in32(GPIO0_TCR) & ~0x40000000); + out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x40000000); + out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x40000000); udelay(1000); /* wait some time before reading input */ - value = in32(GPIO0_IR) & 0x40000000; /* get config bits */ + value = in_be32((void*)GPIO0_IR) & 0x40000000; /* get config bits */ if (value) { puts(", 33 MHz PCI"); } else { -- cgit v1.1 From 24eea623d4974a169026a975ba12fb23d48154b1 Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Mon, 24 Nov 2008 15:11:10 +0100 Subject: ppc4xx: Remove unused features This patch disables some unused features from the PCI405 configuration to keep U-Boot image size below 192k. Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- include/configs/PCI405.h | 57 ++++++------------------------------------------ 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/include/configs/PCI405.h b/include/configs/PCI405.h index 0393366..d0a37d7 100644 --- a/include/configs/PCI405.h +++ b/include/configs/PCI405.h @@ -60,39 +60,24 @@ #define CONFIG_PREBOOT /* enable preboot variable */ -#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ -#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ - -#define CONFIG_PPC4xx_EMAC -#define CONFIG_MII 1 /* MII PHY management */ -#define CONFIG_PHY_ADDR 0 /* PHY address */ - -#define CONFIG_RTC_M48T35A 1 /* ST Electronics M48 timekeeper */ - - -/* - * BOOTP options - */ -#define CONFIG_BOOTP_BOOTFILESIZE -#define CONFIG_BOOTP_BOOTPATH -#define CONFIG_BOOTP_GATEWAY -#define CONFIG_BOOTP_HOSTNAME - - /* * Command line configuration. */ #include +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_ITEST +#undef CONFIG_CMD_LOADB +#undef CONFIG_CMD_LOADS +#undef CONFIG_CMD_NET +#undef CONFIG_CMD_NFS + #define CONFIG_CMD_PCI -#define CONFIG_CMD_IRQ #define CONFIG_CMD_ELF -#define CONFIG_CMD_DATE #define CONFIG_CMD_I2C #define CONFIG_CMD_BSP #define CONFIG_CMD_EEPROM - #undef CONFIG_WATCHDOG /* watchdog disabled */ #define CONFIG_SDRAM_BANK0 1 /* init onboard SDRAM bank 0 */ @@ -102,7 +87,6 @@ /* * Miscellaneous configurable options */ -#define CONFIG_SYS_LONGHELP /* undef to save memory */ #define CONFIG_SYS_PROMPT "=> " /* Monitor Command Prompt */ #define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ @@ -166,15 +150,9 @@ #define CONFIG_SYS_PCI_PTM1MS 0xff000001 /* 16MB, enable hard-wired to 1 */ #define CONFIG_SYS_PCI_PTM1PCI 0x00000000 /* Host: use this pci address */ -#if 0 /* test-only */ -#define CONFIG_SYS_PCI_PTM2LA 0xffc00000 /* point to flash */ -#define CONFIG_SYS_PCI_PTM2MS 0xffc00001 /* 4MB, enable */ -#define CONFIG_SYS_PCI_PTM2PCI 0x04000000 /* Host: use this pci address */ -#else #define CONFIG_SYS_PCI_PTM2LA 0xef600000 /* point to internal regs */ #define CONFIG_SYS_PCI_PTM2MS 0xffe00001 /* 2MB, enable */ #define CONFIG_SYS_PCI_PTM2PCI 0x00000000 /* Host: use this pci address */ -#endif /*----------------------------------------------------------------------- * Start addresses for the final memory configuration @@ -215,22 +193,10 @@ #define CONFIG_SYS_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ -#if 0 /* Use NVRAM for environment variables */ -/*----------------------------------------------------------------------- - * NVRAM organization - */ -#define CONFIG_ENV_IS_IN_NVRAM 1 /* use NVRAM for environment vars */ -#define CONFIG_ENV_SIZE 0x0ff8 /* Size of Environment vars */ -#define CONFIG_ENV_ADDR \ - (CONFIG_SYS_NVRAM_BASE_ADDR+CONFIG_SYS_NVRAM_SIZE-(CONFIG_ENV_SIZE+8)) /* Env */ - -#else /* Use EEPROM for environment variables */ - #define CONFIG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ #define CONFIG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ #define CONFIG_ENV_SIZE 0x400 /* 1024 bytes may be used for env vars*/ /* total size of a CAT24WC08 is 1024 bytes */ -#endif #define CONFIG_SYS_NVRAM_BASE_ADDR 0xf0200000 /* NVRAM base address */ #define CONFIG_SYS_NVRAM_SIZE (32*1024) /* NVRAM size */ @@ -327,14 +293,6 @@ /*----------------------------------------------------------------------- * Definitions for initial stack pointer and data area (in data cache) */ -#if 0 /* test-only */ -#define CONFIG_SYS_INIT_DCACHE_CS 7 /* use cs # 7 for data cache memory */ -#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 /* use data cache */ -#define CONFIG_SYS_INIT_RAM_END 0x2000 /* End of used area in RAM */ -#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ -#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET -#else /* use on chip memory ( OCM ) for temperary stack until sdram is tested */ #define CONFIG_SYS_TEMP_STACK_OCM 1 /* On Chip Memory location */ @@ -346,7 +304,6 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET -#endif /* * Internal Definitions -- cgit v1.1 From 89295028e7d8f7a524f485328279d72fdb102385 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 24 Nov 2008 12:09:50 +0100 Subject: ppc4xx: ml300 remove Xilinx BSP from ml300 folder This BSP should be outside u-boot source tree. The second reason is that xilinx ppc405 was moved to generic platform. Signed-off-by: Michal Simek Signed-off-by: Stefan Roese --- .../ml300/sw_services/uboot_v1_00_a/data/Ltypes | 55 ---- .../uboot_v1_00_a/data/uboot_v2_1_0.mld | 52 ---- .../uboot_v1_00_a/data/uboot_v2_1_0.tcl | 325 --------------------- 3 files changed, 432 deletions(-) delete mode 100644 board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes delete mode 100644 board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld delete mode 100644 board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes deleted file mode 100644 index 9daf147..0000000 --- a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -if [ $# -ne 1 ] -then - echo "usage: Ltypes filename" >&2 - exit 2 -fi - -FILE="$1" -#TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1 -TMPFILE=${FILE}.`date "+%s"` -touch $TMPFILE || exit 1 - -# Change all the Xilinx types to Linux types and put the result into a temp file -sed \ - -e 's/\bXTRUE\b/TRUE/g' \ - -e 's/\bXFALSE\b/FALSE/g' \ - -e 's/\bXNULL\b/NULL/g' \ - -e 's/"xenv.h"//g' \ - -e 's/\bXENV_USLEEP\b/udelay/g' \ - -e 's/\bXuint8\b/u8/g' \ - -e 's/\bXuint16\b/u16/g' \ - -e 's/\bXuint32\b/u32/g' \ - -e 's/\bXint8\b/s8/g' \ - -e 's/\bXint16\b/s16/g' \ - -e 's/\bXint32\b/s32/g' \ - -e 's/\bXboolean\b/u32/g' \ - "${FILE}" > "${TMPFILE}" - -# Overlay the original file with the temp file -mv "${TMPFILE}" "${FILE}" - -# Are we doing xbasic_types.h? -if [ "${FILE##*/}" = xbasic_types.h ] -then - # Remember as you're reading this that we've already gone through the prior - # sed script. We need to do some other things to xbasic_types.h: - # 1) Add ifndefs around TRUE and FALSE defines - # 2) Remove definition of NULL as NULL - # 3) Replace most of the primitive types section with a #include - sed \ - -e '/u32 true/,/#define false/Ic\ -#ifndef TRUE\ -#define TRUE 1\ -#endif\ -#ifndef FALSE\ -#define FALSE 0\ -#endif' \ - -e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' \ - -e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\ -#include ' \ - "${FILE}" > "${TMPFILE}" - - mv "${TMPFILE}" "${FILE}" -fi diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld deleted file mode 100644 index 5169241..0000000 --- a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld +++ /dev/null @@ -1,52 +0,0 @@ -# (c) Copyright 2004 Xilinx Inc. -# Author: Xilinx, Inc. -# -# -# This program 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. -# -# -# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A -# COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS -# ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, -# XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE -# FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING -# ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. -# XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO -# THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY -# WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM -# CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS FOR A PARTICULAR PURPOSE. -# -# -# Xilinx hardware products are not intended for use in life support -# appliances, devices, or systems. Use in such applications is -# expressly prohibited. -# -# -# (c) Copyright 2002-2004 Xilinx Inc. -# All rights reserved. -# -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 675 Mass Ave, Cambridge, MA 02139, USA. - -OPTION psf_version = 2.1; - -BEGIN LIBRARY uboot OPTION DRC = uboot_drc; - -BEGIN ARRAY connected_periphs PROPERTY desc = "Peripherals connected to U-Boot"; -PROPERTY size = 0; -PARAM name = periph_name, desc = "Name of Peripheral connected", type = string; -END ARRAY - PARAMETER name = TARGET_DIR, desc = "Target Directory for U-Boot BSP", type = string; - -# location of persistent storage in the IIC EEPROM (defaults are set for ML300) -PARAMETER name = IIC_PERSISTENT_BASEADDR, desc = "Start of persistent storage block in the EEPROM address space", type = int, default = 1024; -PARAMETER name = IIC_PERSISTENT_HIGHADDR, desc = "End of persistent storage block in the EEPROM address space", type = int, default = 2047; -PARAMETER name = IIC_PERSISTENT_EEPROMADDR, desc = "Address of the EEPROM on the IIC bus", type = int, default = 0xA0; - -END LIBRARY diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl deleted file mode 100644 index 9d44f44..0000000 --- a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl +++ /dev/null @@ -1,325 +0,0 @@ -# -# Author: Xilinx, Inc. -# -# -# This program 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. -# -# -# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A -# COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS -# ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, -# XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE -# FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING -# ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. -# XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO -# THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY -# WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM -# CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS FOR A PARTICULAR PURPOSE. -# -# -# Xilinx hardware products are not intended for use in life support -# appliances, devices, or systems. Use in such applications is -# expressly prohibited. -# -# -# (c) Copyright 2002-2004 Xilinx Inc. -# All rights reserved. -# -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 675 Mass Ave, Cambridge, MA 02139, USA. -# -# Globals -lappend drvlist -set ltypes "../../../sw_services/uboot_v1_00_a/data/Ltypes" - -proc uboot_drc {lib_handle} { - puts "U-Boot DRC..." -} - -proc generate {libname} { - - global drvlist - - # Get list of peripherals connected to uboot - set conn_periphs [xget_handle $libname "ARRAY" "connected_periphs"] - #lappend drvlist - if {[string compare -nocase $conn_periphs ""] != 0} { - set conn_periphs_elems [xget_handle $conn_periphs "ELEMENTS" "*"] - # For each periph - foreach periph_elem $conn_periphs_elems { - set periph [xget_value $periph_elem "PARAMETER" "periph_name"] - # 1. Get driver - set drv [xget_swhandle $periph] - set posn [lsearch -exact $drvlist $drv] - if {$posn == -1} { - lappend drvlist $drv - } - } - - set file_handle [xopen_include_file "xparameters.h"] - puts $file_handle "\n/******************************************************************/\n" - puts $file_handle "/* U-Boot Redefines */" - puts $file_handle "\n/******************************************************************/\n" - close $file_handle - - foreach drv $drvlist { - set drvname [xget_value $drv "NAME"] - - #Redefines xparameters.h - if {[string compare -nocase $drvname "uartns550"] == 0} { - xredefine_uartns550 $drv "xparameters.h" - } elseif {[string compare -nocase $drvname "emac"] == 0} { - xredefine_emac $drv "xparameters.h" - } elseif {[string compare -nocase $drvname "iic"] == 0} { - xredefine_iic $drv "xparameters.h" - } - } - } - - # define core_clock - xredefine_params $libname "xparameters.h" "CORE_CLOCK_FREQ_HZ" - - # define the values for the persistent storage in IIC - xredefine_params $libname "xparameters.h" "IIC_PERSISTENT_BASEADDR" "IIC_PERSISTENT_HIGHADDR" "IIC_PERSISTENT_EEPROMADDR" - -} - -proc xget_corefreq {} { - set processor [xget_processor] - set name [xget_value $processor "NAME"] - puts "procname : $name" - set processor_driver [xget_swhandle [xget_value $processor "NAME"]] - puts "procdrv : $processor_driver" - if {[string compare -nocase $processor_driver ""] != 0} { - set arg "CORE_CLOCK_FREQ_HZ" - #set retval [xget_value $processor_driver "PARAMETER" $arg] - set retval [xget_dname [xget_value $processor_driver "NAME"] $arg] - return $retval - } -} - -# procedure that adds # defines to xparameters.h as XPAR_argument -proc xredefine_params {handle file_name args} { - - puts "xredfine ..." - # Open include file - set file_handle [xopen_include_file $file_name] - puts "args : $args" - - foreach arg $args { - if {[string compare -nocase $arg "CORE_CLOCK_FREQ_HZ"] == 0} { - set value [xget_corefreq] - puts "corefreq : $value" - } else { - set value [xget_value $handle "PARAMETER" $arg] - puts "value : $value" - } - - if {$value != ""} { - set value [xformat_addr_string $value $arg] - - if {[string compare -nocase $arg "IIC_PERSISTENT_BASEADDR"] == 0} { - set name "PERSISTENT_0_IIC_0_BASEADDR" - } elseif {[string compare -nocase $arg "IIC_PERSISTENT_HIGHADDR"] == 0} { - set name "PERSISTENT_0_IIC_0_HIGHADDR" - } elseif {[string compare -nocase $arg "IIC_PERSISTENT_EEPROMADDR"] == 0} { - set name "PERSISTENT_0_IIC_0_EEPROMADDR" - } else { - set name [string toupper $arg] - } - set name [format "XPAR_%s" $name] - puts $file_handle "#define $name $value" - } - } - - puts $file_handle "\n/******************************************************************/\n" - close $file_handle -} - -# uart redefines... -proc xredefine_uartns550 {drvhandle file_name} { - - xredefine_include_file $drvhandle $file_name "uartns550" "C_BASEADDR" "C_HIGHADDR" "CLOCK_HZ" "DEVICE_ID" - -} - -proc xredefine_emac {drvhandle file_name} { - - xredefine_include_file $drvhandle $file_name "emac" "C_BASEADDR" "C_HIGHADDR" "C_DMA_PRESENT" "C_MII_EXIST" "C_ERR_COUNT_EXIST" "DEVICE_ID" - -} - -proc xredefine_iic {drvhandle file_name} { - xredefine_include_file $drvhandle $file_name "iic" "C_BASEADDR" "C_HIGHADDR" "C_TEN_BIT_ADR" "DEVICE_ID" - -} - -####################### - -proc xredefine_include_file {drv_handle file_name drv_string args} { - - # Open include file - set file_handle [xopen_include_file $file_name] - - # Get all peripherals connected to this driver - set periphs [xget_periphs $drv_handle] - - set pname [format "XPAR_%s_" [string toupper $drv_string]] - - # Print all parameters for all peripherals - set device_id 0 - set sub_periphs 1 - foreach periph $periphs { - puts "$periph : $drv_string : $sub_periphs" - - for {set i 0} {$i < $sub_periphs} {incr i} { - foreach arg $args { - set name "${pname}${device_id}_" - - if {[string compare -nocase "CLOCK_HZ" $arg] == 0} { - set xdrv_string [format "%s%s" "X" $drv_string] - set value [xget_dname $xdrv_string $arg] - set name "${name}CLOCK_FREQ_HZ" - } else { - if {[string match C_* $arg]} { - set name [format "%s%s" $name [string range $arg 2 end]] - } else { - set name "${name}${arg}" - } - set value [xget_name $periph $arg] - } - - if {[string compare -nocase "uartns550" $drv_string] == 0} { - if {[string compare -nocase "C_BASEADDR" $arg] == 0} { - set value [format "(%s%s%s)" $value "+" "0x1000"] - } - } - - puts $file_handle "#define $name $value" - if {[string compare -nocase "DEVICE_ID" $arg] == 0} { - incr device_id - } - } - } - } - puts $file_handle "\n/******************************************************************/\n" - close $file_handle -} - -################################################## -# procedure post_generate -# This generates the drivers directory for uboot -# and runs the ltypes script -################################################## - -proc post_generate {lib_handle} { - - global drvlist - - # Create U-Boot tree structure - set pwd [pwd] - set common_dir "uboot/board/xilinx/common" - set xilinx_enet_dir "uboot/board/xilinx/xilinx_enet" - set ml300_dir "uboot/board/xilinx/ml300" - - exec bash -c "mkdir -p $common_dir $xilinx_enet_dir $ml300_dir" - - # Copy files for xilinx_ocp - xcopy_commonfiles - - foreach drv $drvlist { - set drvname [xget_value $drv "NAME"] - set ver [xget_value $drv "PARAMETER" "DRIVER_VER"] - set ver [string map {. _} $ver] - set dirname [format "%s_v%s" $drvname $ver] - - if {[string compare -nocase $drvname "emac"] == 0} { - xcopy_emac $drv $dirname - } elseif {[string compare -nocase $drvname "iic"] == 0} { - xcopy_iic $drv $dirname - } - } - - # Call Ltypes Script here - set uboot "uboot" - xltype_file $uboot - - # Move xparameters.h around - exec bash -c "cp ../../include/xparameters.h $ml300_dir" - - # copy the whole U-Boot BSP to its final destination - set value [xget_value $lib_handle "PARAMETER" TARGET_DIR] - puts "TARGET_DIR : $value" - - if {$value != ""} { - if {[file isdirectory $value] == 0} { - exec bash -c "mkdir -p $value" - } - exec bash -c "cp -Rp uboot/* $value" - } -} - -proc xcopy_commonfiles {} { - - global drvlist - - set common_dir "uboot/board/xilinx/common" - - foreach drv $drvlist { - set depends [xget_value $drv "OPTION" "DEPENDS"] - foreach dep $depends { - puts "dep : $dep" - if {[file isdirectory "../$dep"] == 1} { - exec bash -c "cp -f ../$dep/src/*.c $common_dir" - exec bash -c "cp -f ../$dep/src/*.h $common_dir" - } - } - } - -} - -proc xcopy_emac {drv_handle dirname} { - set emac "board/xilinx/xilinx_enet" - xcopy_dir $dirname $emac -} - -proc xcopy_iic {drv_handle dirname} { - set iic "board/xilinx/xilinx_iic" - xcopy_dir $dirname $iic -} - -proc xcopy_dir {srcdir dstdir} { - - set dstdirname [format "%s%s" "uboot/" $dstdir] - if {[file isdirectory "../$srcdir"] == 1} { - # Copy files from src to dst - exec bash -c "mkdir -p $dstdirname" - exec bash -c "cp -f ../$srcdir/src/*.c $dstdirname" - exec bash -c "cp -f ../$srcdir/src/*.h $dstdirname" - } else { - puts "$srcdir does not exist ..." - } -} - - -proc xltype_file {filename} { - - global ltypes - - puts $filename - - if {[file isdirectory $filename]} { - foreach entry [glob -nocomplain [file join $filename *]] { - xltype_file $entry - } - } else { - exec bash -c "$ltypes $filename" - } - -} -- cgit v1.1 From 2077e348c2a84901022ad95311b47b70361e6daa Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 25 Nov 2008 10:47:02 -0600 Subject: NAND: Fix misplaced return statement in nand_{read,write}_skip_bad(). This caused the operation to be needlessly repeated if there were no bad blocks and no errors. Signed-off-by: Valeriy Glushkov Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_util.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 149af83..d86c987 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -487,11 +487,11 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, if (len_incl_bad == *length) { rval = nand_write (nand, offset, length, buffer); - if (rval != 0) { + if (rval != 0) printf ("NAND write to offset %x failed %d\n", offset, rval); - return rval; - } + + return rval; } while (left_to_write > 0) { @@ -557,11 +557,11 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, if (len_incl_bad == *length) { rval = nand_read (nand, offset, length, buffer); - if (rval != 0) { + if (rval != 0) printf ("NAND read from offset %x failed %d\n", offset, rval); - return rval; - } + + return rval; } while (left_to_read > 0) { -- cgit v1.1 From d10c5a87cb8affbb4d35a311370316d4383d598e Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 7 Nov 2008 22:46:21 +0100 Subject: drivers/usb: Move conditional compilation to Makefile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Remy Böhmer --- drivers/usb/Makefile | 19 +++++++++++++------ drivers/usb/isp116x-hcd.c | 4 ---- drivers/usb/sl811_usb.c | 3 --- drivers/usb/usb_ohci.c | 4 ---- drivers/usb/usbdcore_ep0.c | 4 ---- drivers/usb/usbdcore_mpc8xx.c | 4 ---- drivers/usb/usbdcore_omap1510.c | 4 ---- 7 files changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index c67a490..856f51a 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -25,15 +25,22 @@ include $(TOPDIR)/config.mk LIB := $(obj)libusb.a +# core +COBJS-y += usbdcore.o +COBJS-$(CONFIG_USB_OHCI_NEW) += usb_ohci.o + +# host +COBJS-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o COBJS-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o +COBJS-$(CONFIG_USB_SL811HS) += sl811_usb.o -COBJS-y += isp116x-hcd.o -COBJS-y += sl811_usb.o -COBJS-y += usb_ohci.o -COBJS-y += usbdcore.o +# device +ifdef CONFIG_USB_DEVICE COBJS-y += usbdcore_ep0.o -COBJS-y += usbdcore_mpc8xx.o -COBJS-y += usbdcore_omap1510.o +COBJS-$(CONFIG_OMAP1510) += usbdcore_omap1510.o +COBJS-$(CONFIG_OMAP1610) += usbdcore_omap1510.o +COBJS-$(CONFIG_MPC885_FAMILY) += usbdcore_mpc8xx.o +endif COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/usb/isp116x-hcd.c b/drivers/usb/isp116x-hcd.c index cc46dfe..348e404 100644 --- a/drivers/usb/isp116x-hcd.c +++ b/drivers/usb/isp116x-hcd.c @@ -56,8 +56,6 @@ */ #include - -#ifdef CONFIG_USB_ISP116X_HCD #include #include #include @@ -1441,5 +1439,3 @@ int usb_lowlevel_stop(void) return 0; } - -#endif /* CONFIG_USB_ISP116X_HCD */ diff --git a/drivers/usb/sl811_usb.c b/drivers/usb/sl811_usb.c index 48f1ee9..a03e469 100644 --- a/drivers/usb/sl811_usb.c +++ b/drivers/usb/sl811_usb.c @@ -36,7 +36,6 @@ */ #include -#ifdef CONFIG_USB_SL811HS #include #include #include "sl811.h" @@ -733,5 +732,3 @@ static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe, return status == 0 ? len : status; } - -#endif /* CONFIG_USB_SL811HS */ diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c index e03371c..d68fdcf 100644 --- a/drivers/usb/usb_ohci.c +++ b/drivers/usb/usb_ohci.c @@ -46,9 +46,6 @@ */ #include - -#ifdef CONFIG_USB_OHCI_NEW - #include #if defined(CONFIG_PCI_OHCI) @@ -2016,4 +2013,3 @@ int usb_lowlevel_stop(void) ohci_inited = 0; return 0; } -#endif /* CONFIG_USB_OHCI_NEW */ diff --git a/drivers/usb/usbdcore_ep0.c b/drivers/usb/usbdcore_ep0.c index cf3f382..f6e017d 100644 --- a/drivers/usb/usbdcore_ep0.c +++ b/drivers/usb/usbdcore_ep0.c @@ -51,8 +51,6 @@ */ #include - -#if defined(CONFIG_USB_DEVICE) #include "usbdcore.h" #if 0 @@ -597,5 +595,3 @@ int ep0_recv_setup (struct urb *urb) } return -1; } - -#endif diff --git a/drivers/usb/usbdcore_mpc8xx.c b/drivers/usb/usbdcore_mpc8xx.c index 53bde0d..0e311ad 100644 --- a/drivers/usb/usbdcore_mpc8xx.c +++ b/drivers/usb/usbdcore_mpc8xx.c @@ -58,8 +58,6 @@ */ #include #include - -#if defined(CONFIG_MPC885_FAMILY) && defined(CONFIG_USB_DEVICE) #include #include "usbdcore.h" #include "usbdcore_mpc8xx.h" @@ -1398,5 +1396,3 @@ static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment) return retaddr; } - -#endif /* CONFIG_MPC885_FAMILY && CONFIG_USB_DEVICE) */ diff --git a/drivers/usb/usbdcore_omap1510.c b/drivers/usb/usbdcore_omap1510.c index 4e3239f..cb9dc44 100644 --- a/drivers/usb/usbdcore_omap1510.c +++ b/drivers/usb/usbdcore_omap1510.c @@ -27,9 +27,6 @@ */ #include - -#if ((defined(CONFIG_OMAP1510) || defined(CONFIG_OMAP1610)) && defined(CONFIG_USB_DEVICE)) - #include #ifdef CONFIG_OMAP_SX1 #include @@ -1566,4 +1563,3 @@ void udc_unset_nak (int epid) { /* TODO: implement this functionality in omap1510 */ } -#endif -- cgit v1.1 From de39f8c19d7c12017248c49d432dcb81db68f724 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Wed, 26 Nov 2008 17:41:34 +0100 Subject: USB style patch, 80 chars strict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit USB Code style patch Signed-off-by: Michael Trimarchi Signed-off-by: Remy Böhmer --- common/cmd_usb.c | 595 +++++++++++++++++++++++++++++-------------------------- common/usb.c | 40 ++-- include/usb.h | 222 ++++++++++++--------- 3 files changed, 465 insertions(+), 392 deletions(-) diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 99e551f..8a8dca9 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -36,178 +36,210 @@ static int usb_stor_curr_dev = -1; /* current device */ #endif /* some display routines (info command) */ -char * usb_get_class_desc(unsigned char dclass) +char *usb_get_class_desc(unsigned char dclass) { - switch(dclass) { - case USB_CLASS_PER_INTERFACE: - return("See Interface"); - case USB_CLASS_AUDIO: - return("Audio"); - case USB_CLASS_COMM: - return("Communication"); - case USB_CLASS_HID: - return("Human Interface"); - case USB_CLASS_PRINTER: - return("Printer"); - case USB_CLASS_MASS_STORAGE: - return("Mass Storage"); - case USB_CLASS_HUB: - return("Hub"); - case USB_CLASS_DATA: - return("CDC Data"); - case USB_CLASS_VENDOR_SPEC: - return("Vendor specific"); - default : - return(""); + switch (dclass) { + case USB_CLASS_PER_INTERFACE: + return "See Interface"; + case USB_CLASS_AUDIO: + return "Audio"; + case USB_CLASS_COMM: + return "Communication"; + case USB_CLASS_HID: + return "Human Interface"; + case USB_CLASS_PRINTER: + return "Printer"; + case USB_CLASS_MASS_STORAGE: + return "Mass Storage"; + case USB_CLASS_HUB: + return "Hub"; + case USB_CLASS_DATA: + return "CDC Data"; + case USB_CLASS_VENDOR_SPEC: + return "Vendor specific"; + default: + return ""; } } -void usb_display_class_sub(unsigned char dclass,unsigned char subclass,unsigned char proto) +void usb_display_class_sub(unsigned char dclass, unsigned char subclass, + unsigned char proto) { - switch(dclass) { - case USB_CLASS_PER_INTERFACE: - printf("See Interface"); + switch (dclass) { + case USB_CLASS_PER_INTERFACE: + printf("See Interface"); + break; + case USB_CLASS_HID: + printf("Human Interface, Subclass: "); + switch (subclass) { + case USB_SUB_HID_NONE: + printf("None"); break; - case USB_CLASS_HID: - printf("Human Interface, Subclass: "); - switch(subclass) { - case USB_SUB_HID_NONE: - printf("None"); - break; - case USB_SUB_HID_BOOT: - printf("Boot "); - switch(proto) { - case USB_PROT_HID_NONE: - printf("None"); - break; - case USB_PROT_HID_KEYBOARD: - printf("Keyboard"); - break; - case USB_PROT_HID_MOUSE: - printf("Mouse"); - break; - default: - printf("reserved"); - } - break; - default: - printf("reserved"); + case USB_SUB_HID_BOOT: + printf("Boot "); + switch (proto) { + case USB_PROT_HID_NONE: + printf("None"); + break; + case USB_PROT_HID_KEYBOARD: + printf("Keyboard"); + break; + case USB_PROT_HID_MOUSE: + printf("Mouse"); + break; + default: + printf("reserved"); + break; } break; - case USB_CLASS_MASS_STORAGE: - printf("Mass Storage, "); - switch(subclass) { - case US_SC_RBC: - printf("RBC "); - break; - case US_SC_8020: - printf("SFF-8020i (ATAPI)"); - break; - case US_SC_QIC: - printf("QIC-157 (Tape)"); - break; - case US_SC_UFI: - printf("UFI"); - break; - case US_SC_8070: - printf("SFF-8070"); - break; - case US_SC_SCSI: - printf("Transp. SCSI"); - break; - default: - printf("reserved"); - break; - } - printf(", "); - switch(proto) { - case US_PR_CB: - printf("Command/Bulk"); - break; - case US_PR_CBI: - printf("Command/Bulk/Int"); - break; - case US_PR_BULK: - printf("Bulk only"); - break; - default: - printf("reserved"); - } + default: + printf("reserved"); + break; + } + break; + case USB_CLASS_MASS_STORAGE: + printf("Mass Storage, "); + switch (subclass) { + case US_SC_RBC: + printf("RBC "); + break; + case US_SC_8020: + printf("SFF-8020i (ATAPI)"); + break; + case US_SC_QIC: + printf("QIC-157 (Tape)"); + break; + case US_SC_UFI: + printf("UFI"); + break; + case US_SC_8070: + printf("SFF-8070"); + break; + case US_SC_SCSI: + printf("Transp. SCSI"); + break; + default: + printf("reserved"); + break; + } + printf(", "); + switch (proto) { + case US_PR_CB: + printf("Command/Bulk"); + break; + case US_PR_CBI: + printf("Command/Bulk/Int"); + break; + case US_PR_BULK: + printf("Bulk only"); break; default: - printf("%s",usb_get_class_desc(dclass)); + printf("reserved"); + break; + } + break; + default: + printf("%s", usb_get_class_desc(dclass)); + break; } } -void usb_display_string(struct usb_device *dev,int index) +void usb_display_string(struct usb_device *dev, int index) { char buffer[256]; - if (index!=0) { - if (usb_string(dev,index,&buffer[0],256)>0); - printf("String: \"%s\"",buffer); + if (index != 0) { + if (usb_string(dev, index, &buffer[0], 256) > 0) + printf("String: \"%s\"", buffer); } } void usb_display_desc(struct usb_device *dev) { - if (dev->descriptor.bDescriptorType==USB_DT_DEVICE) { - printf("%d: %s, USB Revision %x.%x\n",dev->devnum,usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass), - (dev->descriptor.bcdUSB>>8) & 0xff,dev->descriptor.bcdUSB & 0xff); - if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) - printf(" - %s %s %s\n",dev->mf,dev->prod,dev->serial); + if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) { + printf("%d: %s, USB Revision %x.%x\n", dev->devnum, + usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass), + (dev->descriptor.bcdUSB>>8) & 0xff, + dev->descriptor.bcdUSB & 0xff); + + if (strlen(dev->mf) || strlen(dev->prod) || + strlen(dev->serial)) + printf(" - %s %s %s\n", dev->mf, dev->prod, + dev->serial); if (dev->descriptor.bDeviceClass) { printf(" - Class: "); - usb_display_class_sub(dev->descriptor.bDeviceClass,dev->descriptor.bDeviceSubClass,dev->descriptor.bDeviceProtocol); + usb_display_class_sub(dev->descriptor.bDeviceClass, + dev->descriptor.bDeviceSubClass, + dev->descriptor.bDeviceProtocol); printf("\n"); + } else { + printf(" - Class: (from Interface) %s\n", + usb_get_class_desc( + dev->config.if_desc[0].bInterfaceClass)); } - else { - printf(" - Class: (from Interface) %s\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass)); - } - printf(" - PacketSize: %d Configurations: %d\n",dev->descriptor.bMaxPacketSize0,dev->descriptor.bNumConfigurations); - printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n",dev->descriptor.idVendor,dev->descriptor.idProduct,(dev->descriptor.bcdDevice>>8) & 0xff,dev->descriptor.bcdDevice & 0xff); + printf(" - PacketSize: %d Configurations: %d\n", + dev->descriptor.bMaxPacketSize0, + dev->descriptor.bNumConfigurations); + printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n", + dev->descriptor.idVendor, dev->descriptor.idProduct, + (dev->descriptor.bcdDevice>>8) & 0xff, + dev->descriptor.bcdDevice & 0xff); } } -void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_device *dev) +void usb_display_conf_desc(struct usb_config_descriptor *config, + struct usb_device *dev) { - printf(" Configuration: %d\n",config->bConfigurationValue); - printf(" - Interfaces: %d %s%s%dmA\n",config->bNumInterfaces,(config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ", - (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",config->MaxPower*2); + printf(" Configuration: %d\n", config->bConfigurationValue); + printf(" - Interfaces: %d %s%s%dmA\n", config->bNumInterfaces, + (config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ", + (config->bmAttributes & 0x20) ? "Remote Wakeup " : "", + config->MaxPower*2); if (config->iConfiguration) { printf(" - "); - usb_display_string(dev,config->iConfiguration); + usb_display_string(dev, config->iConfiguration); printf("\n"); } } -void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_device *dev) +void usb_display_if_desc(struct usb_interface_descriptor *ifdesc, + struct usb_device *dev) { - printf(" Interface: %d\n",ifdesc->bInterfaceNumber); - printf(" - Alternate Setting %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints); + printf(" Interface: %d\n", ifdesc->bInterfaceNumber); + printf(" - Alternate Setting %d, Endpoints: %d\n", + ifdesc->bAlternateSetting, ifdesc->bNumEndpoints); printf(" - Class "); - usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol); + usb_display_class_sub(ifdesc->bInterfaceClass, + ifdesc->bInterfaceSubClass, ifdesc->bInterfaceProtocol); printf("\n"); if (ifdesc->iInterface) { printf(" - "); - usb_display_string(dev,ifdesc->iInterface); + usb_display_string(dev, ifdesc->iInterface); printf("\n"); } } void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc) { - printf(" - Endpoint %d %s ",epdesc->bEndpointAddress & 0xf,(epdesc->bEndpointAddress & 0x80) ? "In" : "Out"); - switch((epdesc->bmAttributes & 0x03)) - { - case 0: printf("Control"); break; - case 1: printf("Isochronous"); break; - case 2: printf("Bulk"); break; - case 3: printf("Interrupt"); break; + printf(" - Endpoint %d %s ", epdesc->bEndpointAddress & 0xf, + (epdesc->bEndpointAddress & 0x80) ? "In" : "Out"); + switch ((epdesc->bmAttributes & 0x03)) { + case 0: + printf("Control"); + break; + case 1: + printf("Isochronous"); + break; + case 2: + printf("Bulk"); + break; + case 3: + printf("Interrupt"); + break; } - printf(" MaxPacket %d",epdesc->wMaxPacketSize); - if ((epdesc->bmAttributes & 0x03)==0x3) - printf(" Interval %dms",epdesc->bInterval); + printf(" MaxPacket %d", epdesc->wMaxPacketSize); + if ((epdesc->bmAttributes & 0x03) == 0x3) + printf(" Interval %dms", epdesc->bInterval); printf("\n"); } @@ -217,15 +249,15 @@ void usb_display_config(struct usb_device *dev) struct usb_config_descriptor *config; struct usb_interface_descriptor *ifdesc; struct usb_endpoint_descriptor *epdesc; - int i,ii; - - config= &dev->config; - usb_display_conf_desc(config,dev); - for(i=0;ino_of_if;i++) { - ifdesc= &config->if_desc[i]; - usb_display_if_desc(ifdesc,dev); - for(ii=0;iino_of_ep;ii++) { - epdesc= &ifdesc->ep_desc[ii]; + int i, ii; + + config = &dev->config; + usb_display_conf_desc(config, dev); + for (i = 0; i < config->no_of_if; i++) { + ifdesc = &config->if_desc[i]; + usb_display_if_desc(ifdesc, dev); + for (ii = 0; ii < ifdesc->no_of_ep; ii++) { + epdesc = &ifdesc->ep_desc[ii]; usb_display_ep_desc(epdesc); } } @@ -233,31 +265,33 @@ void usb_display_config(struct usb_device *dev) } /* shows the device tree recursively */ -void usb_show_tree_graph(struct usb_device *dev,char *pre) +void usb_show_tree_graph(struct usb_device *dev, char *pre) { - int i,index; - int has_child,last_child,port; + int i, index; + int has_child, last_child, port; - index=strlen(pre); - printf(" %s",pre); + index = strlen(pre); + printf(" %s", pre); /* check if the device has connected children */ - has_child=0; - for(i=0;imaxchild;i++) { - if (dev->children[i]!=NULL) - has_child=1; + has_child = 0; + for (i = 0; i < dev->maxchild; i++) { + if (dev->children[i] != NULL) + has_child = 1; } /* check if we are the last one */ - last_child=1; - if (dev->parent!=NULL) { - for(i=0;iparent->maxchild;i++) { + last_child = 1; + if (dev->parent != NULL) { + for (i = 0; i < dev->parent->maxchild; i++) { /* search for children */ - if (dev->parent->children[i]==dev) { - /* found our pointer, see if we have a little sister */ - port=i; - while(i++parent->maxchild) { - if (dev->parent->children[i]!=NULL) { + if (dev->parent->children[i] == dev) { + /* found our pointer, see if we have a + * little sister + */ + port = i; + while (i++ < dev->parent->maxchild) { + if (dev->parent->children[i] != NULL) { /* found a sister */ - last_child=0; + last_child = 0; break; } /* if */ } /* while */ @@ -265,28 +299,27 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre) } /* for all children of the parent */ printf("\b+-"); /* correct last child */ - if (last_child) { - pre[index-1]=' '; - } + if (last_child) + pre[index-1] = ' '; } /* if not root hub */ else printf(" "); - printf("%d ",dev->devnum); - pre[index++]=' '; - pre[index++]= has_child ? '|' : ' '; - pre[index]=0; - printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass), - dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2); - if (strlen(dev->mf) || - strlen(dev->prod) || - strlen(dev->serial)) - printf(" %s %s %s %s\n",pre,dev->mf,dev->prod,dev->serial); - printf(" %s\n",pre); - if (dev->maxchild>0) { - for(i=0;imaxchild;i++) { - if (dev->children[i]!=NULL) { - usb_show_tree_graph(dev->children[i],pre); - pre[index]=0; + printf("%d ", dev->devnum); + pre[index++] = ' '; + pre[index++] = has_child ? '|' : ' '; + pre[index] = 0; + printf(" %s (%s, %dmA)\n", usb_get_class_desc( + dev->config.if_desc[0].bInterfaceClass), + dev->slow ? "1.5MBit/s" : "12MBit/s", + dev->config.MaxPower * 2); + if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial)) + printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial); + printf(" %s\n", pre); + if (dev->maxchild > 0) { + for (i = 0; i < dev->maxchild; i++) { + if (dev->children[i] != NULL) { + usb_show_tree_graph(dev->children[i], pre); + pre[index] = 0; } } } @@ -297,8 +330,8 @@ void usb_show_tree(struct usb_device *dev) { char preamble[32]; - memset(preamble,0,32); - usb_show_tree_graph(dev,&preamble[0]); + memset(preamble, 0, 32); + usb_show_tree_graph(dev, &preamble[0]); } @@ -306,11 +339,11 @@ void usb_show_tree(struct usb_device *dev) * usb boot command intepreter. Derived from diskboot */ #ifdef CONFIG_USB_STORAGE -int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; - int dev, part=1, rcode; + int dev, part = 1, rcode; ulong addr, cnt; disk_partition_t info; image_header_t *hdr; @@ -322,95 +355,98 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) switch (argc) { case 1: addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv ("bootdevice"); + boot_device = getenv("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); + boot_device = getenv("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; break; default: - printf ("Usage:\n%s\n", cmdtp->usage); + printf("Usage:\n%s\n", cmdtp->usage); return 1; } if (!boot_device) { - puts ("\n** No boot device **\n"); + puts("\n** No boot device **\n"); return 1; } dev = simple_strtoul(boot_device, &ep, 16); - stor_dev=usb_stor_get_dev(dev); + stor_dev = usb_stor_get_dev(dev); if (stor_dev->type == DEV_TYPE_UNKNOWN) { - printf ("\n** Device %d not available\n", dev); + printf("\n** Device %d not available\n", dev); return 1; } - if (stor_dev->block_read==NULL) { + if (stor_dev->block_read == NULL) { printf("storage device not initialized. Use usb scan\n"); return 1; } if (*ep) { if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); + puts("\n** Invalid boot device, use `dev[:part]' **\n"); return 1; } part = simple_strtoul(++ep, NULL, 16); } - if (get_partition_info (stor_dev, part, &info)) { + if (get_partition_info(stor_dev, part, &info)) { /* try to boot raw .... */ - strncpy((char *)&info.type[0], BOOT_PART_TYPE, sizeof(BOOT_PART_TYPE)); + strncpy((char *)&info.type[0], BOOT_PART_TYPE, + sizeof(BOOT_PART_TYPE)); strncpy((char *)&info.name[0], "Raw", 4); - info.start=0; - info.blksz=0x200; - info.size=2880; + info.start = 0; + info.blksz = 0x200; + info.size = 2880; printf("error reading partinfo...try to boot raw\n"); } - if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { - printf ("\n** Invalid partition type \"%.32s\"" + if ((strncmp((char *)info.type, BOOT_PART_TYPE, + sizeof(info.type)) != 0) && + (strncmp((char *)info.type, BOOT_PART_COMP, + sizeof(info.type)) != 0)) { + printf("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); return 1; } - printf ("\nLoading from USB device %d, partition %d: " + printf("\nLoading from USB device %d, partition %d: " "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); - debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", + debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", info.start, info.size, info.blksz); if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) { - printf ("** Read error on %d:%d\n", dev, part); + printf("** Read error on %d:%d\n", dev, part); return 1; } - switch (genimg_get_format ((void *)addr)) { + switch (genimg_get_format((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); + if (!image_check_hcrc(hdr)) { + puts("\n** Bad Header Checksum **\n"); return 1; } - image_print_contents (hdr); + image_print_contents(hdr); - cnt = image_get_image_size (hdr); + cnt = image_get_image_size(hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; - puts ("Fit image detected...\n"); + puts("Fit image detected...\n"); - cnt = fit_get_size (fit_hdr); + cnt = fit_get_size(fit_hdr); break; #endif default: - puts ("** Unknown image type\n"); + puts("** Unknown image type\n"); return 1; } @@ -418,36 +454,38 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) cnt /= info.blksz; cnt -= 1; - if (stor_dev->block_read (dev, info.start+1, cnt, + if (stor_dev->block_read(dev, info.start+1, cnt, (ulong *)(addr+info.blksz)) != cnt) { - printf ("\n** Read error on %d:%d\n", dev, part); + printf("\n** Read error on %d:%d\n", dev, part); return 1; } #if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM first */ - if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format (fit_hdr)) { - puts ("** Bad FIT image format\n"); + /* This cannot be done earlier, we need complete FIT image in RAM + * first + */ + if (genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) { + if (!fit_check_format(fit_hdr)) { + puts("** Bad FIT image format\n"); return 1; } - fit_print_contents (fit_hdr); + fit_print_contents(fit_hdr); } #endif /* Loading ok, update default load address */ load_addr = addr; - flush_cache (addr, (cnt+1)*info.blksz); + flush_cache(addr, (cnt+1)*info.blksz); /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) { char *local_args[2]; - extern int do_bootm (cmd_tbl_t *, int, int, char *[]); + extern int do_bootm(cmd_tbl_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; - printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); - rcode=do_bootm (cmdtp, 0, 1, local_args); + printf("Automatic boot of image at addr 0x%08lX ...\n", addr); + rcode = do_bootm(cmdtp, 0, 1, local_args); return rcode; } return 0; @@ -455,10 +493,10 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif /* CONFIG_USB_STORAGE */ -/********************************************************************************* +/****************************************************************************** * usb command intepreter */ -int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int i; @@ -469,7 +507,7 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif if ((strncmp(argv[1], "reset", 5) == 0) || - (strncmp(argv[1], "start", 5) == 0)){ + (strncmp(argv[1], "start", 5) == 0)) { usb_stop(); printf("(Re)start USB...\n"); i = usb_init(); @@ -480,16 +518,17 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif return 0; } - if (strncmp(argv[1],"stop",4) == 0) { + if (strncmp(argv[1], "stop", 4) == 0) { #ifdef CONFIG_USB_KEYBOARD - if (argc==2) { - if (usb_kbd_deregister()!=0) { - printf("USB not stopped: usbkbd still using USB\n"); + if (argc == 2) { + if (usb_kbd_deregister() != 0) { + printf("USB not stopped: usbkbd still" + " using USB\n"); return 1; } - } - else { /* forced stop, switch console in to serial */ - console_assign(stdin,"serial"); + } else { + /* forced stop, switch console in to serial */ + console_assign(stdin, "serial"); usb_kbd_deregister(); } #endif @@ -501,40 +540,38 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("USB is stopped. Please issue 'usb start' first.\n"); return 1; } - if (strncmp(argv[1],"tree",4) == 0) { + if (strncmp(argv[1], "tree", 4) == 0) { printf("\nDevice Tree:\n"); usb_show_tree(usb_get_dev_index(0)); return 0; } - if (strncmp(argv[1],"inf",3) == 0) { + if (strncmp(argv[1], "inf", 3) == 0) { int d; - if (argc==2) { - for(d=0;ddevnum==i) + if (dev->devnum == i) break; } - if (dev==NULL) { + if (dev == NULL) { printf("*** NO Device avaiable ***\n"); return 0; - } - else { + } else { usb_display_desc(dev); usb_display_config(dev); } @@ -543,36 +580,36 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #ifdef CONFIG_USB_STORAGE if (strncmp(argv[1], "scan", 4) == 0) { - printf(" NOTE: this command is obsolete and will be phased out\n"); - printf(" please use 'usb storage' for USB storage devices information\n\n"); + printf(" NOTE: this command is obsolete and will be" + " phased out\n"); + printf(" please use 'usb storage' for USB storage devices" + " information\n\n"); usb_stor_info(); return 0; } - if (strncmp(argv[1], "stor", 4) == 0) { + if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); - } - if (strncmp(argv[1],"part",4) == 0) { + if (strncmp(argv[1], "part", 4) == 0) { int devno, ok = 0; - if (argc==2) { - for (devno=0; devnotype!=DEV_TYPE_UNKNOWN) { + if (argc == 2) { + for (devno = 0; devno < USB_MAX_STOR_DEV; ++devno) { + stor_dev = usb_stor_get_dev(devno); + if (stor_dev->type != DEV_TYPE_UNKNOWN) { ok++; if (devno) printf("\n"); - printf("print_part of %x\n",devno); + printf("print_part of %x\n", devno); print_part(stor_dev); } } - } - else { - devno=simple_strtoul(argv[2], NULL, 16); - stor_dev=usb_stor_get_dev(devno); - if (stor_dev->type!=DEV_TYPE_UNKNOWN) { + } else { + devno = simple_strtoul(argv[2], NULL, 16); + stor_dev = usb_stor_get_dev(devno); + if (stor_dev->type != DEV_TYPE_UNKNOWN) { ok++; - printf("print_part of %x\n",devno); + printf("print_part of %x\n", devno); print_part(stor_dev); } } @@ -582,22 +619,24 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } return 0; } - if (strcmp(argv[1],"read") == 0) { - if (usb_stor_curr_dev<0) { + if (strcmp(argv[1], "read") == 0) { + if (usb_stor_curr_dev < 0) { printf("no current device selected\n"); return 1; } - if (argc==5) { + if (argc == 5) { unsigned long addr = simple_strtoul(argv[2], NULL, 16); unsigned long blk = simple_strtoul(argv[3], NULL, 16); unsigned long cnt = simple_strtoul(argv[4], NULL, 16); unsigned long n; - printf ("\nUSB read: device %d block # %ld, count %ld ... ", - usb_stor_curr_dev, blk, cnt); - stor_dev=usb_stor_get_dev(usb_stor_curr_dev); - n = stor_dev->block_read(usb_stor_curr_dev, blk, cnt, (ulong *)addr); - printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); - if (n==cnt) + printf("\nUSB read: device %d block # %ld, count %ld" + " ... ", usb_stor_curr_dev, blk, cnt); + stor_dev = usb_stor_get_dev(usb_stor_curr_dev); + n = stor_dev->block_read(usb_stor_curr_dev, blk, cnt, + (ulong *)addr); + printf("%ld blocks read: %s\n", n, + (n == cnt) ? "OK" : "ERROR"); + if (n == cnt) return 0; return 1; } @@ -605,34 +644,31 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (strncmp(argv[1], "dev", 3) == 0) { if (argc == 3) { int dev = (int)simple_strtoul(argv[2], NULL, 10); - printf ("\nUSB device %d: ", dev); + printf("\nUSB device %d: ", dev); if (dev >= USB_MAX_STOR_DEV) { printf("unknown device\n"); return 1; } - printf ("\n Device %d: ", dev); - stor_dev=usb_stor_get_dev(dev); + printf("\n Device %d: ", dev); + stor_dev = usb_stor_get_dev(dev); dev_print(stor_dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) { + if (stor_dev->type == DEV_TYPE_UNKNOWN) return 1; - } usb_stor_curr_dev = dev; printf("... is now current device\n"); return 0; - } - else { - printf ("\nUSB device %d: ", usb_stor_curr_dev); - stor_dev=usb_stor_get_dev(usb_stor_curr_dev); + } else { + printf("\nUSB device %d: ", usb_stor_curr_dev); + stor_dev = usb_stor_get_dev(usb_stor_curr_dev); dev_print(stor_dev); - if (stor_dev->type == DEV_TYPE_UNKNOWN) { + if (stor_dev->type == DEV_TYPE_UNKNOWN) return 1; - } return 0; } return 0; } #endif /* CONFIG_USB_STORAGE */ - printf ("Usage:\n%s\n", cmdtp->usage); + printf("Usage:\n%s\n", cmdtp->usage); return 1; } @@ -646,7 +682,8 @@ U_BOOT_CMD( "usb info [dev] - show available USB devices\n" "usb storage - show details of USB storage devices\n" "usb dev [dev] - show or set current USB storage device\n" - "usb part [dev] - print partition table of one or all USB storage devices\n" + "usb part [dev] - print partition table of one or all USB storage" + " devices\n" "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" " to memory address `addr'\n" ); diff --git a/common/usb.c b/common/usb.c index 7ab5df6..ee18152 100644 --- a/common/usb.c +++ b/common/usb.c @@ -58,7 +58,7 @@ #undef USB_DEBUG #ifdef USB_DEBUG -#define USB_PRINTF(fmt, args...) printf (fmt , ##args) +#define USB_PRINTF(fmt, args...) printf(fmt , ##args) #else #define USB_PRINTF(fmt, args...) #endif @@ -87,11 +87,12 @@ static int hub_port_reset(struct usb_device *dev, int port, * wait_ms */ -void __inline__ wait_ms(unsigned long ms) +inline void wait_ms(unsigned long ms) { while (ms-- > 0) udelay(1000); } + /*************************************************************************** * Init USB Device */ @@ -245,9 +246,9 @@ int usb_maxpacket(struct usb_device *dev, unsigned long pipe) { /* direction is out -> use emaxpacket out */ if ((pipe & USB_DIR_IN) == 0) - return(dev->epmaxpacketout[((pipe>>15) & 0xf)]); + return dev->epmaxpacketout[((pipe>>15) & 0xf)]; else - return(dev->epmaxpacketin[((pipe>>15) & 0xf)]); + return dev->epmaxpacketin[((pipe>>15) & 0xf)]; } /* The routine usb_set_maxpacket_ep() is extracted from the loop of routine @@ -269,7 +270,7 @@ usb_set_maxpacket_ep(struct usb_device *dev, struct usb_endpoint_descriptor *ep) USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */ dev->epmaxpacketout[b] = ep->wMaxPacketSize; - dev->epmaxpacketin [b] = ep->wMaxPacketSize; + dev->epmaxpacketin[b] = ep->wMaxPacketSize; USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n", b, dev->epmaxpacketin[b]); } else { @@ -779,13 +780,13 @@ int usb_new_device(struct usb_device *dev) * invalid header while reading 8 bytes as device descriptor. */ dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */ dev->maxpacketsize = PACKET_SIZE_8; - dev->epmaxpacketin [0] = 8; + dev->epmaxpacketin[0] = 8; dev->epmaxpacketout[0] = 8; err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8); if (err < 8) { printf("\n USB device not responding, " \ - "giving up (status=%lX)\n",dev->status); + "giving up (status=%lX)\n", dev->status); return 1; } #else @@ -793,7 +794,8 @@ int usb_new_device(struct usb_device *dev) * reset of the device (Linux uses the same sequence) * Some equipment is said to work only with such init sequence; this * patch is based on the work by Alan Stern: - * http://sourceforge.net/mailarchive/forum.php?thread_id=5729457&forum_id=5398 + * http://sourceforge.net/mailarchive/forum.php? + * thread_id=5729457&forum_id=5398 */ struct usb_device_descriptor *desc; int port = -1; @@ -809,7 +811,7 @@ int usb_new_device(struct usb_device *dev) dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */ /* Default to 64 byte max packet size */ dev->maxpacketsize = PACKET_SIZE_64; - dev->epmaxpacketin [0] = 64; + dev->epmaxpacketin[0] = 64; dev->epmaxpacketout[0] = 64; err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64); @@ -844,13 +846,21 @@ int usb_new_device(struct usb_device *dev) } #endif - dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; + dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; switch (dev->descriptor.bMaxPacketSize0) { - case 8: dev->maxpacketsize = PACKET_SIZE_8; break; - case 16: dev->maxpacketsize = PACKET_SIZE_16; break; - case 32: dev->maxpacketsize = PACKET_SIZE_32; break; - case 64: dev->maxpacketsize = PACKET_SIZE_64; break; + case 8: + dev->maxpacketsize = PACKET_SIZE_8; + break; + case 16: + dev->maxpacketsize = PACKET_SIZE_16; + break; + case 32: + dev->maxpacketsize = PACKET_SIZE_32; + break; + case 64: + dev->maxpacketsize = PACKET_SIZE_64; + break; } dev->devnum = addr; @@ -947,7 +957,7 @@ void usb_scan_devices(void) #undef USB_HUB_DEBUG #ifdef USB_HUB_DEBUG -#define USB_HUB_PRINTF(fmt, args...) printf (fmt , ##args) +#define USB_HUB_PRINTF(fmt, args...) printf(fmt , ##args) #else #define USB_HUB_PRINTF(fmt, args...) #endif diff --git a/include/usb.h b/include/usb.h index 9a2e72c..84a77b2 100644 --- a/include/usb.h +++ b/include/usb.h @@ -43,89 +43,88 @@ /* String descriptor */ struct usb_string_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short wData[1]; + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wData[1]; } __attribute__ ((packed)); /* device request (setup) */ struct devrequest { - unsigned char requesttype; - unsigned char request; - unsigned short value; - unsigned short index; - unsigned short length; + unsigned char requesttype; + unsigned char request; + unsigned short value; + unsigned short index; + unsigned short length; } __attribute__ ((packed)); - /* All standard descriptors have these 2 fields in common */ struct usb_descriptor_header { - unsigned char bLength; - unsigned char bDescriptorType; + unsigned char bLength; + unsigned char bDescriptorType; } __attribute__ ((packed)); /* Device descriptor */ struct usb_device_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short bcdUSB; - unsigned char bDeviceClass; - unsigned char bDeviceSubClass; - unsigned char bDeviceProtocol; - unsigned char bMaxPacketSize0; - unsigned short idVendor; - unsigned short idProduct; - unsigned short bcdDevice; - unsigned char iManufacturer; - unsigned char iProduct; - unsigned char iSerialNumber; - unsigned char bNumConfigurations; + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize0; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; } __attribute__ ((packed)); - /* Endpoint descriptor */ struct usb_endpoint_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned char bEndpointAddress; - unsigned char bmAttributes; - unsigned short wMaxPacketSize; - unsigned char bInterval; - unsigned char bRefresh; - unsigned char bSynchAddress; - + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; } __attribute__ ((packed)); + /* Interface descriptor */ struct usb_interface_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned char bInterfaceNumber; - unsigned char bAlternateSetting; - unsigned char bNumEndpoints; - unsigned char bInterfaceClass; - unsigned char bInterfaceSubClass; - unsigned char bInterfaceProtocol; - unsigned char iInterface; - - unsigned char no_of_ep; - unsigned char num_altsetting; - unsigned char act_altsetting; + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; + + unsigned char no_of_ep; + unsigned char num_altsetting; + unsigned char act_altsetting; + struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS]; } __attribute__ ((packed)); /* Configuration descriptor information.. */ struct usb_config_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short wTotalLength; - unsigned char bNumInterfaces; - unsigned char bConfigurationValue; - unsigned char iConfiguration; - unsigned char bmAttributes; - unsigned char MaxPower; - - unsigned char no_of_if; /* number of interfaces */ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char MaxPower; + + unsigned char no_of_if; /* number of interfaces */ struct usb_interface_descriptor if_desc[USB_MAXINTERFACES]; } __attribute__ ((packed)); @@ -138,19 +137,20 @@ enum { }; struct usb_device { - int devnum; /* Device number on USB bus */ - int slow; /* Slow device? */ - char mf[32]; /* manufacturer */ - char prod[32]; /* product */ - char serial[32]; /* serial number */ + int devnum; /* Device number on USB bus */ + int slow; /* Slow device? */ + char mf[32]; /* manufacturer */ + char prod[32]; /* product */ + char serial[32]; /* serial number */ /* Maximum packet size; one of: PACKET_SIZE_* */ int maxpacketsize; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ unsigned int toggle[2]; - /* endpoint halts; one bit per endpoint # & direction; */ + /* endpoint halts; one bit per endpoint # & direction; + * [0] = IN, [1] = OUT + */ unsigned int halted[2]; - /* [0] = IN, [1] = OUT */ int epmaxpacketin[16]; /* INput endpoint specific maximums */ int epmaxpacketout[16]; /* OUTput endpoint specific maximums */ @@ -180,21 +180,22 @@ struct usb_device { */ #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \ - defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \ + defined(CONFIG_USB_OHCI_NEW) || defined(CONFIG_USB_SL811HS) || \ defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_R8A66597_HCD) int usb_lowlevel_init(void); int usb_lowlevel_stop(void); -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len); +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len); int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len,struct devrequest *setup); + int transfer_len, struct devrequest *setup); int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval); void usb_event_poll(void); /* Defines */ -#define USB_UHCI_VEND_ID 0x8086 -#define USB_UHCI_DEV_ID 0x7112 +#define USB_UHCI_VEND_ID 0x8086 +#define USB_UHCI_DEV_ID 0x7112 #else #error USB Lowlevel not defined @@ -221,8 +222,9 @@ int usb_stop(void); /* stop the USB Controller */ int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); -int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id); -struct usb_device * usb_get_dev_index(int index); +int usb_set_idle(struct usb_device *dev, int ifnum, int duration, + int report_id); +struct usb_device *usb_get_dev_index(int index); int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, @@ -230,14 +232,17 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, - void *buffer,int transfer_len, int interval); + void *buffer, int transfer_len, int interval); void usb_disable_asynch(int disable); -int usb_maxpacket(struct usb_device *dev,unsigned long pipe); -void __inline__ wait_ms(unsigned long ms); -int usb_get_configuration_no(struct usb_device *dev,unsigned char *buffer,int cfgno); -int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size); +int usb_maxpacket(struct usb_device *dev, unsigned long pipe); +inline void wait_ms(unsigned long ms); +int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, + int cfgno); +int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size); int usb_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, unsigned char id, void *buf, int size); + unsigned char type, unsigned char id, void *buf, + int size); int usb_clear_halt(struct usb_device *dev, int pipe); int usb_string(struct usb_device *dev, int index, char *buf, size_t size); int usb_set_interface(struct usb_device *dev, int interface, int alternate); @@ -247,7 +252,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); #define __swap_16(x) \ ({ unsigned short x_ = (unsigned short)x; \ (unsigned short)( \ - ((x_ & 0x00FFU) << 8) | ((x_ & 0xFF00U) >> 8) ); \ + ((x_ & 0x00FFU) << 8) | ((x_ & 0xFF00U) >> 8)); \ }) #define __swap_32(x) \ ({ unsigned long x_ = (unsigned long)x; \ @@ -255,7 +260,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); ((x_ & 0x000000FFUL) << 24) | \ ((x_ & 0x0000FF00UL) << 8) | \ ((x_ & 0x00FF0000UL) >> 8) | \ - ((x_ & 0xFF000000UL) >> 24) ); \ + ((x_ & 0xFF000000UL) >> 24)); \ }) #ifdef LITTLEENDIAN @@ -286,12 +291,14 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); * unsigned int. The encoding is: * * - max size: bits 0-1 (00 = 8, 01 = 16, 10 = 32, 11 = 64) - * - direction: bit 7 (0 = Host-to-Device [Out], 1 = Device-to-Host [In]) + * - direction: bit 7 (0 = Host-to-Device [Out], + * (1 = Device-to-Host [In]) * - device: bits 8-14 * - endpoint: bits 15-18 * - Data0/1: bit 19 * - speed: bit 26 (0 = Full, 1 = Low Speed) - * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk) + * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, + * 10 = control, 11 = bulk) * * Why? Because it's arbitrary, and whatever encoding we select is really * up to us. This one happens to share a lot of bit positions with the UHCI @@ -300,24 +307,42 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); */ /* Create various pipes... */ #define create_pipe(dev,endpoint) \ - (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->slow << 26) | (dev)->maxpacketsize) -#define default_pipe(dev) ((dev)->slow <<26) - -#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint)) -#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | create_pipe(dev,endpoint)) -#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | create_pipe(dev,endpoint)) -#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | create_pipe(dev,endpoint)) -#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | create_pipe(dev,endpoint) | USB_DIR_IN) -#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | default_pipe(dev)) -#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | default_pipe(dev) | USB_DIR_IN) + (((dev)->devnum << 8) | (endpoint << 15) | \ + ((dev)->slow << 26) | (dev)->maxpacketsize) +#define default_pipe(dev) ((dev)->slow << 26) + +#define usb_sndctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_sndisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_sndbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_sndintpipe(dev, endpoint) ((PIPE_INTERRUPT << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvintpipe(dev, endpoint) ((PIPE_INTERRUPT << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | \ + default_pipe(dev)) +#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | \ + default_pipe(dev) | \ + USB_DIR_IN) /* The D0/D1 toggle bits */ #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1) #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep)) -#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << ep)) | ((bit) << ep)) +#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = \ + ((dev)->toggle[out] & \ + ~(1 << ep)) | ((bit) << ep)) /* Endpoint halt control/status */ #define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1) @@ -325,7 +350,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); #define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep))) #define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep))) -#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT) +#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : \ + USB_PID_OUT) #define usb_pipeout(pipe) ((((pipe) >> 7) & 1) ^ 1) #define usb_pipein(pipe) (((pipe) >> 7) & 1) @@ -365,7 +391,7 @@ struct usb_hub_descriptor { unsigned char bHubContrCurrent; unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8]; unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8]; - /* DeviceRemovable and PortPwrCtrlMask want to be variable-length + /* DeviceRemovable and PortPwrCtrlMask want to be variable-length bitmaps that hold max 255 entries. (bit0 is ignored) */ } __attribute__ ((packed)); -- cgit v1.1 From bebfc6ef3ec994c8e18783269b1d8d41f8e38afd Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Wed, 26 Nov 2008 17:40:37 +0100 Subject: Remove obsolete command (apply afte USB style patch, 80 chars strict) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove USB obsolete commmand Signed-off-by: Michael Trimarchi Signed-off-by: Remy Böhmer --- common/cmd_usb.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 8a8dca9..8b19240 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -579,15 +579,6 @@ int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 0; } #ifdef CONFIG_USB_STORAGE - if (strncmp(argv[1], "scan", 4) == 0) { - printf(" NOTE: this command is obsolete and will be" - " phased out\n"); - printf(" please use 'usb storage' for USB storage devices" - " information\n\n"); - usb_stor_info(); - return 0; - } - if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); -- cgit v1.1 From f698738e46cb461e28c2d58228bb34a2fcf5a475 Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 20 Nov 2008 14:02:56 -0600 Subject: 86xx: Fix non-64-bit compilation problems. Introducing 64-bit (36-bit) support for the MPC8641HPCN failed to accomodate the other two 86xx boards. Introduce definitions for CONFIG_SYS_CCSRBAR_PHYS_{LOW,HIGH} CONFIG_SYS_CCSR_DEFAULT_DBAT{U,L} and CONFIG_SYS_CCSR_DEFAULT_IBAT{U,L} with nominal 32-bit values. Signed-off-by: Jon Loeliger Acked-by: Becky Bruce --- include/configs/MPC8610HPCD.h | 14 ++++++++++++++ include/configs/sbc8641d.h | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index f2fe4a6..5685027 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -81,6 +81,9 @@ #define CONFIG_SYS_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ #define CONFIG_SYS_IMMR CONFIG_SYS_CCSRBAR /* PQII uses CONFIG_SYS_IMMR */ +#define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR +#define CONFIG_SYS_CCSRBAR_PHYS_HIGH 0x0 + #define CONFIG_SYS_PCI1_ADDR (CONFIG_SYS_CCSRBAR+0x8000) #define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_CCSRBAR+0xa000) #define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_CCSRBAR+0x9000) @@ -388,6 +391,17 @@ #define CONFIG_SYS_IBAT3L (CONFIG_SYS_CCSRBAR | BATL_PP_RW | BATL_CACHEINHIBIT) #define CONFIG_SYS_IBAT3U CONFIG_SYS_DBAT3U +#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) +#define CONFIG_SYS_CCSR_DEFAULT_DBATL (CONFIG_SYS_CCSRBAR_DEFAULT \ + | BATL_PP_RW | BATL_CACHEINHIBIT \ + | BATL_GUARDEDSTORAGE) +#define CONFIG_SYS_CCSR_DEFAULT_DBATU (CONFIG_SYS_CCSRBAR_DEFAULT \ + | BATU_BL_1M | BATU_VS | BATU_VP) +#define CONFIG_SYS_CCSR_DEFAULT_IBATL (CONFIG_SYS_CCSRBAR_DEFAULT \ + | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CONFIG_SYS_CCSR_DEFAULT_IBATU CONFIG_SYS_CCSR_DEFAULT_DBATU +#endif + /* * BAT4 32M Cache-inhibited, guarded * 0xe200_0000 1M PCI-Express 2 I/O diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index 45d8179..fa97827 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -104,6 +104,9 @@ #define CONFIG_SYS_CCSRBAR 0xf8000000 /* relocated CCSRBAR */ #define CONFIG_SYS_IMMR CONFIG_SYS_CCSRBAR /* PQII uses CONFIG_SYS_IMMR */ +#define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_CCSRBAR +#define CONFIG_SYS_CCSRBAR_PHYS_HIGH 0x0 + #define CONFIG_SYS_PCI1_ADDR (CONFIG_SYS_CCSRBAR+0x8000) #define CONFIG_SYS_PCI2_ADDR (CONFIG_SYS_CCSRBAR+0x9000) @@ -433,6 +436,17 @@ #define CONFIG_SYS_IBAT3L (CONFIG_SYS_CCSRBAR | BATL_PP_RW | BATL_CACHEINHIBIT) #define CONFIG_SYS_IBAT3U CONFIG_SYS_DBAT3U +#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) +#define CONFIG_SYS_CCSR_DEFAULT_DBATL (CONFIG_SYS_CCSRBAR_DEFAULT \ + | BATL_PP_RW | BATL_CACHEINHIBIT \ + | BATL_GUARDEDSTORAGE) +#define CONFIG_SYS_CCSR_DEFAULT_DBATU (CONFIG_SYS_CCSRBAR_DEFAULT \ + | BATU_BL_1M | BATU_VS | BATU_VP) +#define CONFIG_SYS_CCSR_DEFAULT_IBATL (CONFIG_SYS_CCSRBAR_DEFAULT \ + | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CONFIG_SYS_CCSR_DEFAULT_IBATU CONFIG_SYS_CCSR_DEFAULT_DBATU +#endif + /* * BAT4 32M Cache-inhibited, guarded * 0xe200_0000 16M PCI-Express 1 I/O -- cgit v1.1 From 801a194616d95e6fc426a176d9615ccbf9876c7f Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 20 Nov 2008 12:01:02 -0600 Subject: Removed unused CONFIG_L1_INIT_RAM symbol. Prevent further viral propogation of the unused symbol CONFIG_L1_INIT_RAM by just removing it. Signed-off-by: Jon Loeliger --- include/configs/MPC8349EMDS.h | 1 - include/configs/MPC8349ITX.h | 1 - include/configs/MPC8536DS.h | 2 -- include/configs/MPC8540ADS.h | 1 - include/configs/MPC8540EVAL.h | 1 - include/configs/MPC8541CDS.h | 1 - include/configs/MPC8544DS.h | 2 -- include/configs/MPC8548CDS.h | 1 - include/configs/MPC8555CDS.h | 1 - include/configs/MPC8560ADS.h | 1 - include/configs/MPC8568MDS.h | 1 - include/configs/MPC8572DS.h | 2 -- include/configs/MPC8610HPCD.h | 1 - include/configs/MPC8641HPCN.h | 1 - include/configs/MVBLM7.h | 1 - include/configs/PM854.h | 1 - include/configs/PM856.h | 1 - include/configs/SBC8540.h | 1 - include/configs/TQM834x.h | 1 - include/configs/TQM85xx.h | 1 - include/configs/sbc8349.h | 1 - include/configs/sbc8548.h | 1 - include/configs/sbc8560.h | 1 - include/configs/sbc8641d.h | 1 - include/configs/socrates.h | 1 - include/configs/stxgp3.h | 1 - include/configs/stxssa.h | 1 - 27 files changed, 30 deletions(-) diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index bbdc211..8e82aac 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -193,7 +193,6 @@ #define CONFIG_SYS_BR1_PRELIM (CONFIG_SYS_BCSR|0x00000801) /* Port-size=8bit, MSEL=GPCM */ #define CONFIG_SYS_OR1_PRELIM 0xFFFFE8F0 /* length 32K */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index f633f24..14cbc45 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -266,7 +266,6 @@ boards, we say we have two, but don't display a message if we find only one. */ #undef CONFIG_SYS_RAMBOOT #endif -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index fff888ab..f3eee23 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -231,8 +231,6 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ #define CONFIG_SYS_PIXIS_VBOOT_MASK 0xc0 -/* define to use L1 as initial stack */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index 79a52d9..0b8fe6a 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -258,7 +258,6 @@ #define CONFIG_SYS_OR4_PRELIM 0xffffe1f1 #define CONFIG_SYS_BCSR (CONFIG_SYS_BR4_PRELIM & 0xffff8000) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8540EVAL.h b/include/configs/MPC8540EVAL.h index 46a141a..21cf965 100644 --- a/include/configs/MPC8540EVAL.h +++ b/include/configs/MPC8540EVAL.h @@ -161,7 +161,6 @@ #define CONFIG_SYS_OR4_PRELIM 0xffffe1f1 #define CONFIG_SYS_BCSR (CONFIG_SYS_BR4_PRELIM & 0xffff8000) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index 7ada8a2..eaa737b 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -281,7 +281,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR3_PRELIM 0xf8000801 #define CONFIG_SYS_OR3_PRELIM 0xfff00ff7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index cdbbea6..ff24fa5 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -207,8 +207,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define PIXIS_VCFGEN1_MASK (PIXIS_VCFGEN1_TSEC1SER|PIXIS_VCFGEN1_TSEC3SER) -/* define to use L1 as initial stack */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xf4010000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 083afba..6295590 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -303,7 +303,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR3_PRELIM 0xf8000801 #define CONFIG_SYS_OR3_PRELIM 0xfff00ff7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index f9419cc..40b40ed 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -279,7 +279,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR3_PRELIM 0xf8000801 #define CONFIG_SYS_OR3_PRELIM 0xfff00ff7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index f67d489..2b5b2c1 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -254,7 +254,6 @@ #define CONFIG_SYS_OR4_PRELIM 0xffffe1f1 #define CONFIG_SYS_BCSR (CONFIG_SYS_BR4_PRELIM & 0xffff8000) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index ab3e6d6..9e16bb4 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -265,7 +265,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR5_PRELIM 0xf8010801 #define CONFIG_SYS_OR5_PRELIM 0xffff69f7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index c3693b8..9f01f9a 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -248,8 +248,6 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); | PIXIS_VCFGEN1_TSEC3SER \ | PIXIS_VCFGEN1_TSEC4SER) -/* define to use L1 as initial stack */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index 5685027..27517e5 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -209,7 +209,6 @@ #undef CONFIG_CLOCKS_IN_MHZ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #ifndef CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 69b4c44..cd98894 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -268,7 +268,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #undef CONFIG_CLOCKS_IN_MHZ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #ifndef CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0x0fd00000 /* Initial RAM address */ diff --git a/include/configs/MVBLM7.h b/include/configs/MVBLM7.h index bc2d825..4ecf806 100644 --- a/include/configs/MVBLM7.h +++ b/include/configs/MVBLM7.h @@ -130,7 +130,6 @@ #define CONFIG_SYS_MONITOR_BASE TEXT_BASE #undef CONFIG_SYS_RAMBOOT -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/PM854.h b/include/configs/PM854.h index c3a7f81..1cc80ad 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -161,7 +161,6 @@ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer prescal*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/PM856.h b/include/configs/PM856.h index b3bcf23..698ad2d 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -164,7 +164,6 @@ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer prescal*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/SBC8540.h b/include/configs/SBC8540.h index 48c9339..2853fba 100644 --- a/include/configs/SBC8540.h +++ b/include/configs/SBC8540.h @@ -186,7 +186,6 @@ #define CONFIG_SYS_BCSR ((CONFIG_SYS_BR5_PRELIM & 0xff000000)|0x00400000) /* the size of CS5 needs to be >= 16M for TLB and LAW setups */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x70000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index 2961a1b..796030d 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -171,7 +171,6 @@ extern int tqm834x_num_flash_banks; #undef CONFIG_SYS_RAMBOOT #endif -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x20000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h index 2d4048a..300f490 100644 --- a/include/configs/TQM85xx.h +++ b/include/configs/TQM85xx.h @@ -234,7 +234,6 @@ #define CONFIG_SYS_LBC_LSRT 0x20000000 /* LB sdram refresh timer */ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer presc.*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR (CONFIG_SYS_CCSRBAR \ + 0x04010000) /* Initial RAM address */ diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 174149b..0603e3c 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -162,7 +162,6 @@ #undef CONFIG_SYS_RAMBOOT #endif -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index aefd30a..5ce4dac 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -280,7 +280,6 @@ | CONFIG_SYS_LBC_LSDMR_RFEN \ ) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/sbc8560.h b/include/configs/sbc8560.h index 4301275..e1d3a52 100644 --- a/include/configs/sbc8560.h +++ b/include/configs/sbc8560.h @@ -180,7 +180,6 @@ #define CONFIG_SYS_BCSR ((CONFIG_SYS_BR5_PRELIM & 0xff000000)|0x00400000) /* the size of CS5 needs to be >= 16M for TLB and LAW setups */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x70000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index fa97827..0012945 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -244,7 +244,6 @@ #undef CONFIG_CLOCKS_IN_MHZ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #ifndef CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0x0fd00000 /* Initial RAM address */ diff --git a/include/configs/socrates.h b/include/configs/socrates.h index c67db8f..e89b5a3 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -167,7 +167,6 @@ #define CONFIG_SYS_LBC_LSRT 0x20000000 /* LB sdram refresh timer */ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer presc.*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End used area in RAM */ diff --git a/include/configs/stxgp3.h b/include/configs/stxgp3.h index 2188e54..a0f2ed0 100644 --- a/include/configs/stxgp3.h +++ b/include/configs/stxgp3.h @@ -151,7 +151,6 @@ #define CONFIG_SYS_LBC_LSDMR_4 0x1861b723 #define CONFIG_SYS_LBC_LSDMR_5 0x4061b723 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x60000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/stxssa.h b/include/configs/stxssa.h index b0bd050..f0990c6 100644 --- a/include/configs/stxssa.h +++ b/include/configs/stxssa.h @@ -164,7 +164,6 @@ #define CONFIG_SYS_LBC_LSDMR_4 0x1861b723 #define CONFIG_SYS_LBC_LSDMR_5 0x4061b723 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x60000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ -- cgit v1.1 From 29382d4064fbaff5daacff4c3209370fa5713966 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Thu, 20 Nov 2008 16:43:52 -0600 Subject: mpc8641: Fix error in README I made some updates to the code that didn't make it into the README - fix this Signed-off-by: Becky Bruce --- doc/README.mpc8641hpcn | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/README.mpc8641hpcn b/doc/README.mpc8641hpcn index 5ac39e6..d8fe0a4 100644 --- a/doc/README.mpc8641hpcn +++ b/doc/README.mpc8641hpcn @@ -134,15 +134,15 @@ For 36-bit-enabled u-boot, the virtual map is the same as for 32-bit. However, the physical map is altered to reside in 36-bit space, as follows. Addresses are no longer mapped with VA == PA. All accesses from software use the VA; the PA is only used for setting up windows -and mappings. Note that the low 32 bits are the same as the VA above; -only the top 4 bits vary: +and mappings. Note that with the exception of PCI MEM and RIO, the low + 32 bits are the same as the VA above; only the top 4 bits vary: Memory Range Device Size ------------ ------ ---- 0x0_0000_0000 0x0_7fff_ffff DDR 2G - 0xc_8000_0000 0xc_9fff_ffff RIO MEM 512M - 0xc_8000_0000 0xc_9fff_ffff PCI1/PEX1 MEM 512M - 0xc_a000_0000 0xc_bfff_ffff PCI2/PEX2 MEM 512M + 0xc_0000_0000 0xc_1fff_ffff RIO MEM 512M + 0xc_0000_0000 0xc_1fff_ffff PCI1/PEX1 MEM 512M + 0xc_2000_0000 0xc_3fff_ffff PCI2/PEX2 MEM 512M 0xf_ffe0_0000 0xf_ffef_ffff CCSR 1M 0xf_ffdf_0000 0xf_ffdf_7fff PIXIS 8K 0xf_ffdf_8000 0xf_ffdf_ffff CF 8K -- cgit v1.1 From 5e46b1e54112f4b7fd5185665e571510132c12a7 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 27 Nov 2008 14:11:37 +0100 Subject: OneNAND: Add missing mtd info struct before calling onenand_erase() Without this patch "saveenv" crashes when MTD partitions are enabled (e.g. for use in UBI) via CONFIG_MTD_PARTITIONS. Signed-off-by: Stefan Roese Signed-off-by: Scott Wood --- common/env_onenand.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/env_onenand.c b/common/env_onenand.c index 3c65b3e..dbccc79 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -97,6 +97,7 @@ int saveenv(void) instr.len = CONFIG_ENV_SIZE; instr.addr = env_addr; + instr.mtd = &onenand_mtd; if (onenand_erase(&onenand_mtd, &instr)) { printf("OneNAND: erase failed at 0x%08lx\n", env_addr); return 1; -- cgit v1.1 From 03f797793b124dccaae145b977d15d6cb9e74504 Mon Sep 17 00:00:00 2001 From: Ilko Iliev Date: Tue, 2 Dec 2008 17:20:17 +0100 Subject: fix some coding style violations. This patch fix some coding style violations. Signed-off-by: Ilko Iliev --- drivers/mtd/dataflash.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/dataflash.c b/drivers/mtd/dataflash.c index 201e518..58be182 100644 --- a/drivers/mtd/dataflash.c +++ b/drivers/mtd/dataflash.c @@ -131,14 +131,14 @@ int AT91F_DataflashInit (void) break; } /* set the last area end to the dataflash size*/ - area_list[NB_DATAFLASH_AREA -1].end = + area_list[NB_DATAFLASH_AREA - 1].end = (dataflash_info[i].Device.pages_number * - dataflash_info[i].Device.pages_size)-1; + dataflash_info[i].Device.pages_size) - 1; part = 0; last_part = 0; /* set the area addresses */ - for(j = 0; j= pdataFlash->pDevice->area_list[area].start) && (addr < pdataFlash->pDevice->area_list[area].end)) break; @@ -360,13 +359,13 @@ int dataflash_real_protect (int flag, unsigned long start_addr, return -1; } /* find start area */ - for (area1=0; area1 < NB_DATAFLASH_AREA; area1++) { + for (area1 = 0; area1 < NB_DATAFLASH_AREA; area1++) { if (start_addr == dataflash_info[i].Device.area_list[area1].start) break; } if (area1 == NB_DATAFLASH_AREA) return -1; /* find end area */ - for (area2=0; area2 < NB_DATAFLASH_AREA; area2++) { + for (area2 = 0; area2 < NB_DATAFLASH_AREA; area2++) { if (end_addr == dataflash_info[i].Device.area_list[area2].end) break; } @@ -374,7 +373,7 @@ int dataflash_real_protect (int flag, unsigned long start_addr, return -1; /*set protection value*/ - for(j = area1; j < area2+1 ; j++) + for(j = area1; j < area2 + 1 ; j++) if(dataflash_info[i].Device.area_list[j].protected != FLAG_PROTECT_INVALID) { if (flag == 0) { @@ -386,7 +385,7 @@ int dataflash_real_protect (int flag, unsigned long start_addr, } } - return (area2-area1+1); + return (area2 - area1 + 1); } /*---------------------------------------------------------------------------*/ -- cgit v1.1 From bd876772ee04095e5dd943d97515a1f14bad4b1c Mon Sep 17 00:00:00 2001 From: Ilko Iliev Date: Tue, 2 Dec 2008 17:27:54 +0100 Subject: mtd/dataflash.c: fix a problem with the last partition This patch fix the problem that only the [NB_DATAFLASH_AREA - 1] dataflash partition can be defined to use the area to the end of dataflash size. Now it is possible to have only one dataflash partition from 0 to the end of of dataflash size. Signed-off-by: Ilko Iliev --- drivers/mtd/dataflash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/dataflash.c b/drivers/mtd/dataflash.c index 58be182..96cd395 100644 --- a/drivers/mtd/dataflash.c +++ b/drivers/mtd/dataflash.c @@ -131,7 +131,7 @@ int AT91F_DataflashInit (void) break; } /* set the last area end to the dataflash size*/ - area_list[NB_DATAFLASH_AREA - 1].end = + dataflash_info[i].end_address = (dataflash_info[i].Device.pages_number * dataflash_info[i].Device.pages_size) - 1; -- cgit v1.1 From ed3b18e05c9a8ffa5fb643da9bcec7452e5d5e01 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 30 Nov 2008 19:36:50 +0100 Subject: AT91: remove non supported board AT91RM9200DF macro Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- cpu/arm920t/start.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S index 5143cfc..fbcfe6d 100644 --- a/cpu/arm920t/start.S +++ b/cpu/arm920t/start.S @@ -118,7 +118,7 @@ start_code: bl coloured_LED_init bl red_LED_on -#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF) +#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) /* * relocate exception table */ @@ -258,7 +258,7 @@ cpu_init_crit: * find a lowlevel_init.S in your board directory. */ mov ip, lr -#if defined(CONFIG_AT91RM9200EK) || defined(CONFIG_AT91RM9200DF) +#if defined(CONFIG_AT91RM9200EK) #else bl lowlevel_init -- cgit v1.1 From 4a129a57d923f7c15aa1f567028a80a32d66a100 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 30 Nov 2008 19:36:53 +0100 Subject: at91rm9200dk: Fix typo Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- include/configs/at91rm9200dk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/at91rm9200dk.h b/include/configs/at91rm9200dk.h index 5c239d7..746f0ef 100644 --- a/include/configs/at91rm9200dk.h +++ b/include/configs/at91rm9200dk.h @@ -1,7 +1,7 @@ /* * Rick Bronson * - * Configuation settings for the AT91RM9200DK board. + * Configuration settings for the AT91RM9200DK board. * * See file CREDITS for list of people who contributed to this * project. -- cgit v1.1 From 9b0ad1b1c7a15ff674978705c7c52264978dc5d8 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Tue, 28 Oct 2008 17:53:38 +0800 Subject: 85xx: remove the unused ddr_enable_ecc in the board file The DDR controller of 8548/8544/8568/8572/8536 processors have the ECC data init feature, and the new DDR code is using the feature, and we don't need the way with DMA to init memory any more. Signed-off-by: Dave Liu Acked-by: Andy Fleming --- board/atum8548/atum8548.c | 10 ---------- board/freescale/mpc8536ds/mpc8536ds.c | 10 ---------- board/freescale/mpc8544ds/mpc8544ds.c | 10 ---------- board/freescale/mpc8548cds/mpc8548cds.c | 11 ----------- board/freescale/mpc8568mds/mpc8568mds.c | 12 ------------ board/freescale/mpc8572ds/mpc8572ds.c | 10 ---------- board/sbc8548/sbc8548.c | 10 ---------- include/configs/MPC8536DS.h | 2 +- include/configs/MPC8544DS.h | 2 +- include/configs/MPC8548CDS.h | 2 +- include/configs/MPC8568MDS.h | 2 +- include/configs/MPC8572DS.h | 1 + 12 files changed, 5 insertions(+), 77 deletions(-) diff --git a/board/atum8548/atum8548.c b/board/atum8548/atum8548.c index 226ef57..6ef663e 100644 --- a/board/atum8548/atum8548.c +++ b/board/atum8548/atum8548.c @@ -37,10 +37,6 @@ #include #include -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - long int fixed_sdram(void); int board_early_init_f (void) @@ -117,12 +113,6 @@ initdram(int board_type) dram_size = fixed_sdram (); #endif -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif puts(" DDR: "); return dram_size; } diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c index 6fed4ea..2538483 100644 --- a/board/freescale/mpc8536ds/mpc8536ds.c +++ b/board/freescale/mpc8536ds/mpc8536ds.c @@ -41,10 +41,6 @@ #include "../common/pixis.h" #include "../common/sgmii_riser.h" -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - phys_size_t fixed_sdram(void); int checkboard (void) @@ -73,12 +69,6 @@ initdram(int board_type) dram_size = fixed_sdram(); #endif -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif puts(" DDR: "); return dram_size; } diff --git a/board/freescale/mpc8544ds/mpc8544ds.c b/board/freescale/mpc8544ds/mpc8544ds.c index 545d869..14581ab 100644 --- a/board/freescale/mpc8544ds/mpc8544ds.c +++ b/board/freescale/mpc8544ds/mpc8544ds.c @@ -38,10 +38,6 @@ #include "../common/pixis.h" #include "../common/sgmii_riser.h" -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - int checkboard (void) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -77,12 +73,6 @@ initdram(int board_type) dram_size *= 0x100000; -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif puts(" DDR: "); return dram_size; } diff --git a/board/freescale/mpc8548cds/mpc8548cds.c b/board/freescale/mpc8548cds/mpc8548cds.c index af5ff42..8698605 100644 --- a/board/freescale/mpc8548cds/mpc8548cds.c +++ b/board/freescale/mpc8548cds/mpc8548cds.c @@ -38,10 +38,6 @@ #include "../common/eeprom.h" #include "../common/via.h" -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - DECLARE_GLOBAL_DATA_PTR; void local_bus_init(void); @@ -118,13 +114,6 @@ initdram(int board_type) dram_size = setup_ddr_tlbs(dram_size / 0x100000); dram_size *= 0x100000; -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif - /* * SDRAM Initialization */ diff --git a/board/freescale/mpc8568mds/mpc8568mds.c b/board/freescale/mpc8568mds/mpc8568mds.c index 688d8c3..bc93be8 100644 --- a/board/freescale/mpc8568mds/mpc8568mds.c +++ b/board/freescale/mpc8568mds/mpc8568mds.c @@ -99,11 +99,6 @@ const qe_iop_conf_t qe_iop_conf_tab[] = { {0, 0, 0, 0, QE_IOP_TAB_END}, /* END of table */ }; - -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - void local_bus_init(void); void sdram_init(void); @@ -170,13 +165,6 @@ initdram(int board_type) dram_size = setup_ddr_tlbs(dram_size / 0x100000); dram_size *= 0x100000; -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif - /* * SDRAM Initialization */ diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index 3a78c98..242af86 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -38,10 +38,6 @@ #include "../common/pixis.h" #include "../common/sgmii_riser.h" -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - long int fixed_sdram(void); int checkboard (void) @@ -69,12 +65,6 @@ phys_size_t initdram(int board_type) dram_size = fixed_sdram(); #endif -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif puts(" DDR: "); return dram_size; } diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 9548ac6..cfb9ce5 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -36,10 +36,6 @@ #include #include -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) -extern void ddr_enable_ecc(unsigned int dram_size); -#endif - DECLARE_GLOBAL_DATA_PTR; void local_bus_init(void); @@ -114,12 +110,6 @@ initdram(int board_type) dram_size = fixed_sdram (); #endif -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(dram_size); -#endif /* * SDRAM Initialization */ diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index fff888ab..7c94c81 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -99,7 +99,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_DDR_SPD #undef CONFIG_DDR_DLL -#undef CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef #define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index cdbbea6..a2d12ae 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -97,7 +97,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ #define CONFIG_DDR_SPD -#undef CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef #define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 083afba..df26f10 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -100,7 +100,7 @@ extern unsigned long get_clock_freq(void); #define CONFIG_DDR_SPD #define CONFIG_DDR_DLL /* possible DLL fix needed */ -#undef CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef #define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory*/ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index ab3e6d6..60e6041 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -92,7 +92,7 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup*/ #define CONFIG_DDR_SPD #define CONFIG_DDR_DLL /* possible DLL fix needed */ -#undef CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER /* DDR controller or DMA? */ #define CONFIG_MEM_INIT_VALUE 0xDeadBeef diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index c3693b8..ed25c99 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -99,6 +99,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_DDR_SPD #undef CONFIG_DDR_DLL +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER #define CONFIG_MEM_INIT_VALUE 0xDeadBeef #define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 -- cgit v1.1 From e57f0fa1333cdf3ca36110aac2900712a5f82976 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Tue, 28 Oct 2008 17:53:45 +0800 Subject: 85xx: the DDR tlb is missed for the !CONFIG_SPD_EEPROM case we need TLB entry for DDR at !SPD case. Signed-off-by: Dave Liu Acked-by: Andy Fleming --- board/freescale/mpc8536ds/mpc8536ds.c | 6 ++---- board/freescale/mpc8572ds/mpc8572ds.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c index 2538483..2b17612 100644 --- a/board/freescale/mpc8536ds/mpc8536ds.c +++ b/board/freescale/mpc8536ds/mpc8536ds.c @@ -61,13 +61,11 @@ initdram(int board_type) #ifdef CONFIG_SPD_EEPROM dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - - dram_size *= 0x100000; #else dram_size = fixed_sdram(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; puts(" DDR: "); return dram_size; diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index 242af86..a14db5a 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -57,13 +57,11 @@ phys_size_t initdram(int board_type) #ifdef CONFIG_SPD_EEPROM dram_size = fsl_ddr_sdram(); - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - - dram_size *= 0x100000; #else dram_size = fixed_sdram(); #endif + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; puts(" DDR: "); return dram_size; -- cgit v1.1 From a2cd50ed6ef0ac6b127b3d6db756979a8336718d Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 11 Nov 2008 10:17:10 -0600 Subject: 85xx: Add CPU 2 errata workaround to all 8548 boards All mpc8548-based boards should implement the suggested workaround to CPU 2 errata. Without the workaround, its possible for the 8548's core to hang while executing a msync or mbar 0 instruction and a snoopable transaction from an I/O master tagged to make quick forward progress is present. Signed-off-by: Peter Tyser Acked-by: Andy Fleming --- board/freescale/mpc8548cds/mpc8548cds.c | 12 ------------ board/sbc8548/sbc8548.c | 7 ------- cpu/mpc85xx/cpu_init.c | 13 +++++++++++++ 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/board/freescale/mpc8548cds/mpc8548cds.c b/board/freescale/mpc8548cds/mpc8548cds.c index 8698605..ba6bff5 100644 --- a/board/freescale/mpc8548cds/mpc8548cds.c +++ b/board/freescale/mpc8548cds/mpc8548cds.c @@ -52,7 +52,6 @@ int checkboard (void) uint pci_slot = get_pci_slot (); uint cpu_board_rev = get_cpu_board_revision (); - uint svr; printf ("Board: CDS Version 0x%02x, PCI Slot %d\n", get_board_version (), pci_slot); @@ -65,17 +64,6 @@ int checkboard (void) */ local_bus_init (); - svr = get_svr(); - - /* - * Fix CPU2 errata: A core hang possible while executing a - * msync instruction and a snoopable transaction from an I/O - * master tagged to make quick forward progress is present. - * Fixed in Silicon Rev.2.1 - */ - if (!(SVR_MAJ(svr) >= 2 && SVR_MIN(svr) >= 1)) - ecm->eebpcr |= (1 << 16); - /* * Hack TSEC 3 and 4 IO voltages. */ diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index cfb9ce5..017f6b3 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -62,13 +62,6 @@ int checkboard (void) local_bus_init (); /* - * Fix CPU2 errata: A core hang possible while executing a - * msync instruction and a snoopable transaction from an I/O - * master tagged to make quick forward progress is present. - */ - ecm->eebpcr |= (1 << 16); - - /* * Hack TSEC 3 and 4 IO voltages. */ gur->tsec34ioovcr = 0xe7e0; /* 1110 0111 1110 0xxx */ diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 3a8aef2..5862bd6 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -174,6 +174,19 @@ void cpu_init_f (void) { volatile ccsr_lbc_t *memctl = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); extern void m8560_cpm_reset (void); +#ifdef CONFIG_MPC8548 + ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); + uint svr = get_svr(); + + /* + * CPU2 errata workaround: A core hang possible while executing + * a msync instruction and a snoopable transaction from an I/O + * master tagged to make quick forward progress is present. + * Fixed in silicon rev 2.1. + */ + if ((SVR_MAJ(svr) == 1) || ((SVR_MAJ(svr) == 2 && SVR_MIN(svr) == 0x0))) + out_be32(&ecm->eebpcr, in_be32(&ecm->eebpcr) | (1 << 16)); +#endif disable_tlb(14); disable_tlb(15); -- cgit v1.1 From dd332e18d082de75eca3fc2c7c778f5d4571a096 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 13 Nov 2008 18:08:57 +0100 Subject: 85xx: socrates: fix DDR SDRAM tlb entry configuration since commit be0bd8234b9777ecd63c4c686f72af070d886517 tlb entry for socrates DDR SDRAM will be reconfigured by setup_ddr_tlbs() from initdram() causing an inconsistency with previously configured DDR SDRAM tlb entry from tlb_table: socrates>l2cam 7 9 IDX PID EPN SIZE V TS RPN U0-U3 WIMGE UUUSSS 7 : 00 00000000 256MB V 0 -> 0_00000000 0000 -I-G- ---RWX 8 : 00 00000000 256MB V 0 -> 0_00000000 0000 ----- ---RWX 9 : 00 10000000 256MB V 0 -> 0_10000000 0000 ----- ---RWX This patch makes the presence of the DDR SDRAM tlb entry in the tlb_table dependent on CONFIG_SPD_EEPROM to avoid this inconsistency. Signed-off-by: Anatolij Gustschin Acked-by: Andy Fleming --- board/socrates/tlb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/socrates/tlb.c b/board/socrates/tlb.c index b91b1ea..4591e46 100644 --- a/board/socrates/tlb.c +++ b/board/socrates/tlb.c @@ -100,6 +100,7 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_64M, 1), +#if !defined(CONFIG_SPD_EEPROM) /* * TLB 7+8: 512M DDR, cache disabled (needed for memory test) * 0x00000000 512M DDR System memory @@ -114,6 +115,7 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000, CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 8, BOOKE_PAGESZ_256M, 1), +#endif }; int num_tlb_entries = ARRAY_SIZE(tlb_table); -- cgit v1.1 From 7008d26a40a76f90cae5824c812cfed449fb97b8 Mon Sep 17 00:00:00 2001 From: Ed Swarthout Date: Wed, 29 Oct 2008 09:21:44 -0500 Subject: fsl ddr skip interleaving if not supported. Removed while(1) hang if memctl_intlv_ctl is set wrong. Remove embedded tabs from strings. Signed-off-by: Ed Swarthout Acked-by: Kumar Gala Acked-by: Andy Fleming --- cpu/mpc8xxx/ddr/main.c | 9 +++++++-- cpu/mpc8xxx/ddr/options.c | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/cpu/mpc8xxx/ddr/main.c b/cpu/mpc8xxx/ddr/main.c index 21a16d9..f1ad132 100644 --- a/cpu/mpc8xxx/ddr/main.c +++ b/cpu/mpc8xxx/ddr/main.c @@ -475,9 +475,14 @@ phys_size_t fsl_ddr_sdram(void) */ memctl_interleaved = 1; } else { - printf("Error: memctl interleaving not " + printf("Warning: memctl interleaving not " "properly configured on all controllers\n"); - while (1); + memctl_interleaved = 0; + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) + info.memctl_opts[i].memctl_interleaving = 0; + debug("Recomputing with memctl_interleaving off.\n"); + total_memory = fsl_ddr_compute(&info, + STEP_ASSIGN_ADDRESSES); } } diff --git a/cpu/mpc8xxx/ddr/options.c b/cpu/mpc8xxx/ddr/options.c index 714e88d..af7f73a 100644 --- a/cpu/mpc8xxx/ddr/options.c +++ b/cpu/mpc8xxx/ddr/options.c @@ -197,10 +197,10 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, */ if ((p = getenv("memctl_intlv_ctl")) != NULL) { if (pdimm[0].n_ranks == 0) { - printf("There is no rank on CS0. Because only rank on \ - CS0 and ranks chip-select interleaved with CS0\ - are controller interleaved, force non memory \ - controller interleaving\n"); + printf("There is no rank on CS0. Because only rank on " + "CS0 and ranks chip-select interleaved with CS0" + " are controller interleaved, force non memory " + "controller interleaving\n"); popts->memctl_interleaving = 0; } else { popts->memctl_interleaving = 1; @@ -239,22 +239,22 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, case FSL_DDR_CS0_CS1: if (pdimm[0].n_ranks != 2) { popts->ba_intlv_ctl = 0; - printf("No enough bank(chip-select) for \ - CS0+CS1, force non-interleaving!\n"); + printf("Not enough bank(chip-select) for " + "CS0+CS1, force non-interleaving!\n"); } break; case FSL_DDR_CS2_CS3: if (pdimm[1].n_ranks !=2){ popts->ba_intlv_ctl = 0; - printf("No enough bank(CS) for CS2+CS3, \ - force non-interleaving!\n"); + printf("Not enough bank(CS) for CS2+CS3, " + "force non-interleaving!\n"); } break; case FSL_DDR_CS0_CS1_AND_CS2_CS3: if ((pdimm[0].n_ranks != 2)||(pdimm[1].n_ranks != 2)) { popts->ba_intlv_ctl = 0; - printf("No enough bank(CS) for CS0+CS1 or \ - CS2+CS3, force non-interleaving!\n"); + printf("Not enough bank(CS) for CS0+CS1 or " + "CS2+CS3, force non-interleaving!\n"); } break; default: -- cgit v1.1 From 5a105a333dab6a23e92d763ce76d6f31d57f45df Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 20 Nov 2008 15:36:48 -0600 Subject: Removed unused CONFIG_L1_INIT_RAM symbol. Prevent further viral propogation of the unused symbol CONFIG_L1_INIT_RAM by just removing it. Signed-off-by: Jon Loeliger Acked-by: Andy Fleming --- include/configs/MPC8349EMDS.h | 1 - include/configs/MPC8349ITX.h | 1 - include/configs/MPC8536DS.h | 2 -- include/configs/MPC8540ADS.h | 1 - include/configs/MPC8540EVAL.h | 1 - include/configs/MPC8541CDS.h | 1 - include/configs/MPC8544DS.h | 2 -- include/configs/MPC8548CDS.h | 1 - include/configs/MPC8555CDS.h | 1 - include/configs/MPC8560ADS.h | 1 - include/configs/MPC8568MDS.h | 1 - include/configs/MPC8572DS.h | 2 -- include/configs/MPC8610HPCD.h | 1 - include/configs/MPC8641HPCN.h | 1 - include/configs/MVBLM7.h | 1 - include/configs/PM854.h | 1 - include/configs/PM856.h | 1 - include/configs/SBC8540.h | 1 - include/configs/TQM834x.h | 1 - include/configs/TQM85xx.h | 1 - include/configs/sbc8349.h | 1 - include/configs/sbc8548.h | 1 - include/configs/sbc8560.h | 1 - include/configs/sbc8641d.h | 1 - include/configs/socrates.h | 1 - include/configs/stxgp3.h | 1 - include/configs/stxssa.h | 1 - 27 files changed, 30 deletions(-) diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index bbdc211..8e82aac 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -193,7 +193,6 @@ #define CONFIG_SYS_BR1_PRELIM (CONFIG_SYS_BCSR|0x00000801) /* Port-size=8bit, MSEL=GPCM */ #define CONFIG_SYS_OR1_PRELIM 0xFFFFE8F0 /* length 32K */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index f633f24..14cbc45 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -266,7 +266,6 @@ boards, we say we have two, but don't display a message if we find only one. */ #undef CONFIG_SYS_RAMBOOT #endif -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index 7c94c81..5a99d5f 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -231,8 +231,6 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ #define CONFIG_SYS_PIXIS_VBOOT_MASK 0xc0 -/* define to use L1 as initial stack */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index 79a52d9..0b8fe6a 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -258,7 +258,6 @@ #define CONFIG_SYS_OR4_PRELIM 0xffffe1f1 #define CONFIG_SYS_BCSR (CONFIG_SYS_BR4_PRELIM & 0xffff8000) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8540EVAL.h b/include/configs/MPC8540EVAL.h index 46a141a..21cf965 100644 --- a/include/configs/MPC8540EVAL.h +++ b/include/configs/MPC8540EVAL.h @@ -161,7 +161,6 @@ #define CONFIG_SYS_OR4_PRELIM 0xffffe1f1 #define CONFIG_SYS_BCSR (CONFIG_SYS_BR4_PRELIM & 0xffff8000) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index 7ada8a2..eaa737b 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -281,7 +281,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR3_PRELIM 0xf8000801 #define CONFIG_SYS_OR3_PRELIM 0xfff00ff7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index a2d12ae..b31c2bb 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -207,8 +207,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define PIXIS_VCFGEN1_MASK (PIXIS_VCFGEN1_TSEC1SER|PIXIS_VCFGEN1_TSEC3SER) -/* define to use L1 as initial stack */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xf4010000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index df26f10..7a7e5a1 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -303,7 +303,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR3_PRELIM 0xf8000801 #define CONFIG_SYS_OR3_PRELIM 0xfff00ff7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index f9419cc..40b40ed 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -279,7 +279,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR3_PRELIM 0xf8000801 #define CONFIG_SYS_OR3_PRELIM 0xfff00ff7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index f67d489..2b5b2c1 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -254,7 +254,6 @@ #define CONFIG_SYS_OR4_PRELIM 0xffffe1f1 #define CONFIG_SYS_BCSR (CONFIG_SYS_BR4_PRELIM & 0xffff8000) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index 60e6041..8bdec65 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -265,7 +265,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_SYS_BR5_PRELIM 0xf8010801 #define CONFIG_SYS_OR5_PRELIM 0xffff69f7 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index ed25c99..f17639a 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -249,8 +249,6 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); | PIXIS_VCFGEN1_TSEC3SER \ | PIXIS_VCFGEN1_TSEC4SER) -/* define to use L1 as initial stack */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index f2fe4a6..7d57c1c 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -206,7 +206,6 @@ #undef CONFIG_CLOCKS_IN_MHZ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #ifndef CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index 69b4c44..cd98894 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -268,7 +268,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #undef CONFIG_CLOCKS_IN_MHZ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #ifndef CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0x0fd00000 /* Initial RAM address */ diff --git a/include/configs/MVBLM7.h b/include/configs/MVBLM7.h index bc2d825..4ecf806 100644 --- a/include/configs/MVBLM7.h +++ b/include/configs/MVBLM7.h @@ -130,7 +130,6 @@ #define CONFIG_SYS_MONITOR_BASE TEXT_BASE #undef CONFIG_SYS_RAMBOOT -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/PM854.h b/include/configs/PM854.h index c3a7f81..1cc80ad 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -161,7 +161,6 @@ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer prescal*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/PM856.h b/include/configs/PM856.h index b3bcf23..698ad2d 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -164,7 +164,6 @@ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer prescal*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/SBC8540.h b/include/configs/SBC8540.h index 48c9339..2853fba 100644 --- a/include/configs/SBC8540.h +++ b/include/configs/SBC8540.h @@ -186,7 +186,6 @@ #define CONFIG_SYS_BCSR ((CONFIG_SYS_BR5_PRELIM & 0xff000000)|0x00400000) /* the size of CS5 needs to be >= 16M for TLB and LAW setups */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x70000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index 2961a1b..796030d 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -171,7 +171,6 @@ extern int tqm834x_num_flash_banks; #undef CONFIG_SYS_RAMBOOT #endif -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x20000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h index 2d4048a..300f490 100644 --- a/include/configs/TQM85xx.h +++ b/include/configs/TQM85xx.h @@ -234,7 +234,6 @@ #define CONFIG_SYS_LBC_LSRT 0x20000000 /* LB sdram refresh timer */ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer presc.*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR (CONFIG_SYS_CCSRBAR \ + 0x04010000) /* Initial RAM address */ diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 174149b..0603e3c 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -162,7 +162,6 @@ #undef CONFIG_SYS_RAMBOOT #endif -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xFD000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x1000 /* End of used area in RAM*/ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index aefd30a..5ce4dac 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -280,7 +280,6 @@ | CONFIG_SYS_LBC_LSDMR_RFEN \ ) -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/sbc8560.h b/include/configs/sbc8560.h index 4301275..e1d3a52 100644 --- a/include/configs/sbc8560.h +++ b/include/configs/sbc8560.h @@ -180,7 +180,6 @@ #define CONFIG_SYS_BCSR ((CONFIG_SYS_BR5_PRELIM & 0xff000000)|0x00400000) /* the size of CS5 needs to be >= 16M for TLB and LAW setups */ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x70000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index 45d8179..752a905 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -241,7 +241,6 @@ #undef CONFIG_CLOCKS_IN_MHZ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #ifndef CONFIG_SYS_INIT_RAM_LOCK #define CONFIG_SYS_INIT_RAM_ADDR 0x0fd00000 /* Initial RAM address */ diff --git a/include/configs/socrates.h b/include/configs/socrates.h index c67db8f..e89b5a3 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -167,7 +167,6 @@ #define CONFIG_SYS_LBC_LSRT 0x20000000 /* LB sdram refresh timer */ #define CONFIG_SYS_LBC_MRTPR 0x20000000 /* LB refresh timer presc.*/ -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xe4010000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End used area in RAM */ diff --git a/include/configs/stxgp3.h b/include/configs/stxgp3.h index 2188e54..a0f2ed0 100644 --- a/include/configs/stxgp3.h +++ b/include/configs/stxgp3.h @@ -151,7 +151,6 @@ #define CONFIG_SYS_LBC_LSDMR_4 0x1861b723 #define CONFIG_SYS_LBC_LSDMR_5 0x4061b723 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x60000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ diff --git a/include/configs/stxssa.h b/include/configs/stxssa.h index b0bd050..f0990c6 100644 --- a/include/configs/stxssa.h +++ b/include/configs/stxssa.h @@ -164,7 +164,6 @@ #define CONFIG_SYS_LBC_LSDMR_4 0x1861b723 #define CONFIG_SYS_LBC_LSDMR_5 0x4061b723 -#define CONFIG_L1_INIT_RAM #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0x60000000 /* Initial RAM address */ #define CONFIG_SYS_INIT_RAM_END 0x4000 /* End of used area in RAM */ -- cgit v1.1 From 35db1c6d34b57ae15e99cf03c8e8f8a6148d74f3 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Fri, 21 Nov 2008 19:24:22 -0600 Subject: drivers/fsl_pci_init: Fix inbound window mapping bug The current code will cause the creation of a 4GB window starting at 0 if we have more than 4GB of RAM installed, which overlaps with PCI_MEM space and causes pci_bus_to_phys() to return erroneous information. Limit the size to 4GB - 1; which causes the code to create one 2GB and one 1GB window instead. Signed-off-by: Becky Bruce Signed-off-by: Kumar Gala Acked-by: Andy Fleming --- drivers/pci/fsl_pci_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 7625ccc..e57acba 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -58,7 +58,7 @@ void pciauto_config_init(struct pci_controller *hose); int fsl_pci_setup_inbound_windows(struct pci_region *r) { struct pci_region *rgn_base = r; - u64 sz = min((u64)gd->ram_size, 1ull << 32); + u64 sz = min((u64)gd->ram_size, (1ull << 32) - 1); phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS; pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS; -- cgit v1.1 From 9427ccde0355a2ebf47454e8e1be59f5b9864e08 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 1 Dec 2008 13:47:12 -0600 Subject: 85xx: Add PORDEVSR_PCI1 define Add define used to determine if PCI1 interface is in PCI or PCIX mode. Convert users of the old PORDEVSR_PCI constant to use MPC85xx_PORDEVSR_PCI1 Signed-off-by: Peter Tyser Signed-off-by: Andy Fleming --- board/freescale/mpc8548cds/mpc8548cds.c | 2 +- board/sbc8548/sbc8548.c | 2 +- board/tqc/tqm85xx/tqm85xx.c | 2 +- cpu/mpc85xx/pci.c | 2 +- include/asm-ppc/immap_85xx.h | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/board/freescale/mpc8548cds/mpc8548cds.c b/board/freescale/mpc8548cds/mpc8548cds.c index ba6bff5..c562fc9 100644 --- a/board/freescale/mpc8548cds/mpc8548cds.c +++ b/board/freescale/mpc8548cds/mpc8548cds.c @@ -332,7 +332,7 @@ pci_init_board(void) first_free_busno=hose->last_busno+1; printf ("PCI on bus %02x - %02x\n",hose->first_busno,hose->last_busno); #ifdef CONFIG_PCIX_CHECK - if (!(gur->pordevsr & PORDEVSR_PCI)) { + if (!(gur->pordevsr & MPC85xx_PORDEVSR_PCI1)) { /* PCI-X init */ if (CONFIG_SYS_CLK_FREQ < 66000000) printf("PCI-X will only work at 66 MHz\n"); diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 017f6b3..8c073cb 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -412,7 +412,7 @@ pci_init_board(void) first_free_busno=hose->last_busno+1; printf ("PCI on bus %02x - %02x\n",hose->first_busno,hose->last_busno); #ifdef CONFIG_PCIX_CHECK - if (!(gur->pordevsr & PORDEVSR_PCI)) { + if (!(gur->pordevsr & MPC85xx_PORDEVSR_PCI1)) { /* PCI-X init */ if (CONFIG_SYS_CLK_FREQ < 66000000) printf("PCI-X will only work at 66 MHz\n"); diff --git a/board/tqc/tqm85xx/tqm85xx.c b/board/tqc/tqm85xx/tqm85xx.c index 3a828ed..73f1d01 100644 --- a/board/tqc/tqm85xx/tqm85xx.c +++ b/board/tqc/tqm85xx/tqm85xx.c @@ -610,7 +610,7 @@ static inline void init_pci1(void) first_free_busno = hose->last_busno + 1; #ifdef CONFIG_PCIX_CHECK - if (!(gur->pordevsr & PORDEVSR_PCI)) { + if (!(gur->pordevsr & MPC85xx_PORDEVSR_PCI1)) { ushort reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E; diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c index 112f18c..787c6eb 100644 --- a/cpu/mpc85xx/pci.c +++ b/cpu/mpc85xx/pci.c @@ -70,7 +70,7 @@ pci_mpc85xx_init(struct pci_controller *board_hose) */ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); - if (!(gur->pordevsr & PORDEVSR_PCI)) { + if (!(gur->pordevsr & MPC85xx_PORDEVSR_PCI1)) { /* PCI-X init */ if (CONFIG_SYS_CLK_FREQ < 66000000) printf("PCI-X will only work at 66 MHz\n"); diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index 75b451d..e5046be 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -1569,6 +1569,7 @@ typedef struct ccsr_gur { #define MPC85xx_PORDEVSR_SGMII3_DIS 0x08000000 #define MPC85xx_PORDEVSR_SGMII4_DIS 0x04000000 #define MPC85xx_PORDEVSR_SRDS2_IO_SEL 0x38000000 +#define MPC85xx_PORDEVSR_PCI1 0x00800000 #define MPC85xx_PORDEVSR_IO_SEL 0x00780000 #define MPC85xx_PORDEVSR_PCI2_ARB 0x00040000 #define MPC85xx_PORDEVSR_PCI1_ARB 0x00020000 @@ -1647,8 +1648,6 @@ typedef struct ccsr_gur { char res15[61648]; /* 0xe0f30 to 0xefffff */ } ccsr_gur_t; -#define PORDEVSR_PCI (0x00800000) /* PCI Mode */ - #define CONFIG_SYS_MPC85xx_GUTS_OFFSET (0xE0000) #define CONFIG_SYS_MPC85xx_GUTS_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_GUTS_OFFSET) #define CONFIG_SYS_MPC85xx_ECM_OFFSET (0x0000) -- cgit v1.1 From ea154a1781135d822eedee7567cc156089eae93c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 24 Nov 2008 10:25:14 -0600 Subject: FSL: Moved BR_PHYS_ADDR for localbus to common header The BR_PHYS_ADDR macro is useful on all machines that have local bus which is pretty much all 83xx/85xx/86xx chips. Additionally most 85xx & 86xx will need it if they want to support 36-bit physical addresses. Signed-off-by: Kumar Gala Acked-by: Andy Fleming --- include/asm-ppc/fsl_lbc.h | 8 ++++++++ include/configs/MPC8641HPCN.h | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/asm-ppc/fsl_lbc.h b/include/asm-ppc/fsl_lbc.h index cac7bf6..51fc5c1 100644 --- a/include/asm-ppc/fsl_lbc.h +++ b/include/asm-ppc/fsl_lbc.h @@ -69,6 +69,14 @@ #define BR_RES ~(BR_BA | BR_PS | BR_DECC | BR_WP | BR_MSEL | BR_ATOM | BR_V) #endif +/* Convert an address into the right format for the BR registers */ +#ifdef CONFIG_PHYS_64BIT +#define BR_PHYS_ADDR(x) ((unsigned long)((x & 0x0ffff8000ULL) | \ + ((x & 0x300000000ULL) >> 19))) +#else +#define BR_PHYS_ADDR(x) (x & 0xffff8000) +#endif + /* OR - Option Registers */ #define OR0 0x5004 /* Register offset to immr */ diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index cd98894..5a83296 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -186,17 +186,8 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SYS_FLASH_BASE_PHYS (CONFIG_SYS_FLASH_BASE \ | CONFIG_SYS_PHYS_ADDR_HIGH) - #define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE} -/* Convert an address into the right format for the BR registers */ -#ifdef CONFIG_PHYS_64BIT -#define BR_PHYS_ADDR(x) ((unsigned long)((x & 0x0ffff8000ULL) | \ - ((x & 0x300000000ULL) >> 19))) -#else -#define BR_PHYS_ADDR(x) (x & 0xffff8000) -#endif - #define CONFIG_SYS_BR0_PRELIM (BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) \ | 0x00001001) /* port size 16bit */ #define CONFIG_SYS_OR0_PRELIM 0xff806ff7 /* 8MB Boot Flash area*/ -- cgit v1.1 From aed461af81012a398a205e9be67ab37667491838 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 24 Nov 2008 10:29:25 -0600 Subject: 85xx: Fix relocation of CCSRBAR If the virtual address for CCSRBAR is the same after relocation but the physical address is changing we'd end up having two TLB entries with the same VA. Instead we new us the new CCSRBAR virt address + 4k as a temp virt address to access the old CCSRBAR to relocate it. Signed-off-by: Kumar Gala Acked-by: Andy Fleming --- cpu/mpc85xx/cpu_init.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 5862bd6..2d86547 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -140,14 +140,15 @@ void cpu_init_early_f(void) #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) { u32 temp; + volatile u32 *ccsr_virt = + (volatile u32 *)(CONFIG_SYS_CCSRBAR + 0x1000); - set_tlb(0, CONFIG_SYS_CCSRBAR_DEFAULT, CONFIG_SYS_CCSRBAR_DEFAULT, + set_tlb(0, (u32)ccsr_virt, CONFIG_SYS_CCSRBAR_DEFAULT, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 1, 1, BOOKE_PAGESZ_4K, 0); - temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR_DEFAULT); - out_be32((volatile u32 *)CONFIG_SYS_CCSRBAR_DEFAULT, CONFIG_SYS_CCSRBAR_PHYS >> 12); - + temp = in_be32(ccsr_virt); + out_be32(ccsr_virt, CONFIG_SYS_CCSRBAR_PHYS >> 12); temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR); } #endif -- cgit v1.1 From 9df59533f77de2829b4b66e5b7620e04edaa391c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 24 Nov 2008 10:29:26 -0600 Subject: 85xx: init gd as early as possible Moved up the initialization of GD so C code like set_tlb() can use gd->flags to determine if we've relocated or not in the future. Signed-off-by: Kumar Gala Acked-by: Andy Fleming --- cpu/mpc85xx/cpu_init.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 2d86547..0b7c609 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -132,6 +132,12 @@ void config_8560_ioports (volatile ccsr_cpm_t * cpm) /* We run cpu_init_early_f in AS = 1 */ void cpu_init_early_f(void) { + /* Pointer is writable since we allocated a register for it */ + gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); + + /* Clear initial global data */ + memset ((void *) gd, 0, sizeof (gd_t)); + set_tlb(0, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 1, 0, BOOKE_PAGESZ_4K, 0); @@ -153,12 +159,6 @@ void cpu_init_early_f(void) } #endif - /* Pointer is writable since we allocated a register for it */ - gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); - - /* Clear initial global data */ - memset ((void *) gd, 0, sizeof (gd_t)); - init_laws(); invalidate_tlb(0); init_tlbs(); -- cgit v1.1 From dc889e865356497d3e495570118c2245ebce2631 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Fri, 28 Nov 2008 20:16:58 +0800 Subject: 85xx: fix the wrong DDR settings for MPC8572DS The default DDR freq is 400MHz or 800M data rate, the old settings is pure wrong for the default case. Signed-off-by: Dave Liu Acked-by: Andy Fleming --- include/configs/MPC8572DS.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index f17639a..9a66ca8 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -115,22 +115,22 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define SPD_EEPROM_ADDRESS2 0x52 /* CTLR 1 DIMM 0 */ /* These are used when DDR doesn't use SPD. */ -#define CONFIG_SYS_SDRAM_SIZE 256 /* DDR is 256MB */ -#define CONFIG_SYS_DDR_CS0_BNDS 0x0000001F -#define CONFIG_SYS_DDR_CS0_CONFIG 0x80010102 /* Enable, no interleaving */ -#define CONFIG_SYS_DDR_TIMING_3 0x00000000 -#define CONFIG_SYS_DDR_TIMING_0 0x00260802 -#define CONFIG_SYS_DDR_TIMING_1 0x3935d322 -#define CONFIG_SYS_DDR_TIMING_2 0x14904cc8 -#define CONFIG_SYS_DDR_MODE_1 0x00480432 +#define CONFIG_SYS_SDRAM_SIZE 512 /* DDR is 512MB */ +#define CONFIG_SYS_DDR_CS0_BNDS 0x0000001F +#define CONFIG_SYS_DDR_CS0_CONFIG 0x80010202 /* Enable, no interleaving */ +#define CONFIG_SYS_DDR_TIMING_3 0x00020000 +#define CONFIG_SYS_DDR_TIMING_0 0x00260802 +#define CONFIG_SYS_DDR_TIMING_1 0x626b2634 +#define CONFIG_SYS_DDR_TIMING_2 0x062874cf +#define CONFIG_SYS_DDR_MODE_1 0x00440462 #define CONFIG_SYS_DDR_MODE_2 0x00000000 -#define CONFIG_SYS_DDR_INTERVAL 0x06180100 +#define CONFIG_SYS_DDR_INTERVAL 0x0c300100 #define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef -#define CONFIG_SYS_DDR_CLK_CTRL 0x03800000 -#define CONFIG_SYS_DDR_OCD_CTRL 0x00000000 +#define CONFIG_SYS_DDR_CLK_CTRL 0x00800000 +#define CONFIG_SYS_DDR_OCD_CTRL 0x00000000 #define CONFIG_SYS_DDR_OCD_STATUS 0x00000000 -#define CONFIG_SYS_DDR_CONTROL 0xC3008000 /* Type = DDR2 */ -#define CONFIG_SYS_DDR_CONTROL2 0x04400010 +#define CONFIG_SYS_DDR_CONTROL 0xc3000008 /* Type = DDR2 */ +#define CONFIG_SYS_DDR_CONTROL2 0x24400000 #define CONFIG_SYS_DDR_ERR_INT_EN 0x0000000d #define CONFIG_SYS_DDR_ERR_DIS 0x00000000 -- cgit v1.1 From 3c2c2f427905040c1513d0c51d637689cba48346 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Thu, 27 Nov 2008 22:30:27 +0100 Subject: Remove non-ascii characters from fat code This code contains some non-ascii characters in comment lines and code. Most editors do not display those characters properly and editing those files results always in diffs at these places which are usually not required to be changed at all. This is error prone. So, remove those weird characters and replace them by normal C-style equivalents for which the proper defines were already in the header. Signed-off-by: Remy Bohmer --- fs/fat/fat.c | 4 ++-- include/fat.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 2f0bd8c..06eabc3 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -184,7 +184,7 @@ static void get_name (dir_entry *dirent, char *s_name) if (*s_name == DELETED_FLAG) *s_name = '\0'; else if (*s_name == aRING) - *s_name = ''; + *s_name = DELETED_FLAG; downcase (s_name); } @@ -489,7 +489,7 @@ get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, l_name[idx] = '\0'; if (*l_name == DELETED_FLAG) *l_name = '\0'; - else if (*l_name == aRING) *l_name = ''; + else if (*l_name == aRING) *l_name = DELETED_FLAG; downcase(l_name); /* Return the real directory entry */ diff --git a/include/fat.h b/include/fat.h index 59de3fb..c8b9493 100644 --- a/include/fat.h +++ b/include/fat.h @@ -67,7 +67,7 @@ #define ATTR_VFAT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) #define DELETED_FLAG ((char)0xe5) /* Marks deleted files when in name[0] */ -#define aRING 0x05 /* Used to represent '' in name[0] */ +#define aRING 0x05 /* Used as special character in name[0] */ /* Indicates that the entry is the last long entry in a set of long * dir entries -- cgit v1.1 From 2e4970d8109d690adcf615d9e3cac7b5b2e8eaed Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 2 Dec 2008 12:59:51 -0600 Subject: net: Fix download command parsing When CONFIG_SYS_HUSH_PARSER is defined network download commands with 1 argument in the format 'tftp "/path/file"' do not work as expected. The hush command parser strips the quotes from "/path/file" which causes the network commands to interpret "/path/file" as an address instead of the intended filename. The previous check for a leading quote in netboot_common() was replaced with a check which ensures only valid numbers are treated as addresses. Signed-off-by: Peter Tyser Signed-off-by: Ben Warren --- common/cmd_net.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/common/cmd_net.c b/common/cmd_net.c index af691a4..c053d7b 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -154,8 +154,10 @@ static int netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) { char *s; + char *end; int rcode = 0; int size; + ulong addr; /* pre-set load_addr */ if ((s = getenv("loadaddr")) != NULL) { @@ -166,15 +168,17 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) case 1: break; - case 2: /* only one arg - accept two forms: - * just load address, or just boot file name. - * The latter form must be written "filename" here. + case 2: /* + * Only one arg - accept two forms: + * Just load address, or just boot file name. The latter + * form must be written in a format which can not be + * mis-interpreted as a valid number. */ - if (argv[1][0] == '"') { /* just boot filename */ - copy_filename (BootFile, argv[1], sizeof(BootFile)); - } else { /* load address */ - load_addr = simple_strtoul(argv[1], NULL, 16); - } + addr = simple_strtoul(argv[1], &end, 16); + if (end == (argv[1] + strlen(argv[1]))) + load_addr = addr; + else + copy_filename(BootFile, argv[1], sizeof(BootFile)); break; case 3: load_addr = simple_strtoul(argv[1], NULL, 16); -- cgit v1.1 From 23afaba65ec5206757e589ef334a8b38168c045f Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 2 Dec 2008 10:31:04 +0100 Subject: net: tsec: Fix Marvell 88E1121R phy init This patch tries to ensure that phy interrupt pin won't be asserted after booting. We experienced following issues with current 88E1121R phy init: Marvell 88E1121R phy can be hardware-configured to share MDC/MDIO and interrupt pins for both ports P0 and P1 (e.g. as configured on socrates board). Port 0 interrupt pin will be shared by both ports in such configuration. After booting Linux and configuring eth0 interface, port 0 phy interrupts are enabled. After rebooting without proper eth0 interface shutdown port 0 phy interrupts remain enabled so any change on port 0 (link status, etc.) cause assertion of the interrupt. Now booting Linux and configuring eth1 interface will cause permanent phy interrupt storm as the registered phy 1 interrupt handler doesn't acknowledge phy 0 interrupts. This of course should be fixed in Linux driver too. Signed-off-by: Anatolij Gustschin Acked-by: Andy Fleming Signed-off-by: Ben Warren --- drivers/net/tsec.c | 3 +++ include/tsec.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index d7da081..fbc9a6d 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -1196,6 +1196,9 @@ struct phy_info phy_info_M88E1121R = { {MIIM_88E1121_PHY_LED_CTRL, miim_read, &mii_88E1121_set_led}, {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, + /* Disable IRQs and de-assert interrupt */ + {MIIM_88E1121_PHY_IRQ_EN, 0, NULL}, + {MIIM_88E1121_PHY_IRQ_STATUS, miim_read, NULL}, {miim_end,} }, (struct phy_cmd[]){ /* startup */ diff --git a/include/tsec.h b/include/tsec.h index d2951f6..7b52e06 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -226,6 +226,10 @@ #define MIIM_88E1121_PHY_LED_PAGE 3 #define MIIM_88E1121_PHY_LED_DEF 0x0030 +/* 88E1121 PHY IRQ Enable/Status Register */ +#define MIIM_88E1121_PHY_IRQ_EN 18 +#define MIIM_88E1121_PHY_IRQ_STATUS 19 + #define MIIM_88E1121_PHY_PAGE 22 /* 88E1145 Extended PHY Specific Control Register */ -- cgit v1.1 From e0c07b868cab405ab4b5335a0247899bfc5ea0b6 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 1 Dec 2008 16:26:20 -0600 Subject: net: Define IP flag field values These defines were pulled from the "Add simple IP/UDP fragmentation support" patch from Frank Haverkamp . Signed-off-by: Peter Tyser Signed-off-by: Ben Warren --- include/net.h | 6 ++++++ net/net.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/net.h b/include/net.h index a5a256b..d2d394f 100644 --- a/include/net.h +++ b/include/net.h @@ -200,6 +200,12 @@ typedef struct { ushort udp_xsum; /* Checksum */ } IP_t; +#define IP_OFFS 0x1fff /* ip offset *= 8 */ +#define IP_FLAGS 0xe000 /* first 3 bits */ +#define IP_FLAGS_RES 0x8000 /* reserved */ +#define IP_FLAGS_DFRAG 0x4000 /* don't fragments */ +#define IP_FLAGS_MFRAG 0x2000 /* more fragments */ + #define IP_HDR_SIZE_NO_UDP (sizeof (IP_t) - 8) #define IP_HDR_SIZE (sizeof (IP_t)) diff --git a/net/net.c b/net/net.c index 77e83b5..cf1f4fa 100644 --- a/net/net.c +++ b/net/net.c @@ -735,7 +735,7 @@ int PingSend(void) ip->ip_tos = 0; ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); ip->ip_id = htons(NetIPID++); - ip->ip_off = htons(0x4000); /* No fragmentation */ + ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */ ip->ip_ttl = 255; ip->ip_p = 0x01; /* ICMP */ ip->ip_sum = 0; @@ -1399,7 +1399,7 @@ NetReceive(volatile uchar * inpkt, int len) if ((ip->ip_hl_v & 0xf0) != 0x40) { return; } - if (ip->ip_off & htons(0x1fff)) { /* Can't deal w/ fragments */ + if (ip->ip_off & htons(IP_OFFS)) { /* Can't deal w/ fragments */ return; } /* can't deal with headers > 20 bytes */ @@ -1698,7 +1698,7 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len) ip->ip_tos = 0; ip->ip_len = htons(IP_HDR_SIZE + len); ip->ip_id = htons(NetIPID++); - ip->ip_off = htons(0x4000); /* No fragmentation */ + ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */ ip->ip_ttl = 255; ip->ip_p = 17; /* UDP */ ip->ip_sum = 0; -- cgit v1.1 From d32c5be50bf0600bfdc54223ef341ee9c63db445 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 1 Dec 2008 16:26:21 -0600 Subject: net: Add additional IP fragmentation check Ignore IP packets which have the "more fragments" flag bit set. This flag indicates the IP packet is fragmented and must be ignored by U-Boot. Signed-off-by: Peter Tyser Signed-off-by: Ben Warren --- net/net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/net.c b/net/net.c index cf1f4fa..7354f2c 100644 --- a/net/net.c +++ b/net/net.c @@ -1399,7 +1399,8 @@ NetReceive(volatile uchar * inpkt, int len) if ((ip->ip_hl_v & 0xf0) != 0x40) { return; } - if (ip->ip_off & htons(IP_OFFS)) { /* Can't deal w/ fragments */ + /* Can't deal with fragments */ + if (ip->ip_off & htons(IP_OFFS | IP_FLAGS_MFRAG)) { return; } /* can't deal with headers > 20 bytes */ -- cgit v1.1 From 6a86bb6c25376f0358478219fa28d7c84dd01ed0 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 1 Dec 2008 16:29:38 -0600 Subject: net: Fix TftpStart() ip:filename bug The TftpStart() function modifies the 'BootFile' string when 'BootFile' contains both an IP address and filename (eg 1.2.3.4:/path/file). This causes subsequent calls to TftpStart to incorrectly parse the TFTP filename and server IP address to use. For example: => tftp 0x100000 10.52.0.62:/home/ptyser/non_existant Speed: 100, half duplex Using eTSEC1 device TFTP from server 10.52.0.62; our IP address is 10.52.253.79 ^^^^^^^^^^ CORRECT Filename '/home/ptyser/non_existant'. ^^^^^^^^^^^^^^^^^^^^^^^^^ CORRECT Load address: 0x100000 Loading: * TFTP error: 'File not found' (1) Starting again eTSEC2: No link. Speed: 100, half duplex Using eTSEC1 device TFTP from server 10.52.0.33; our IP address is 10.52.253.79 ^^^^^^^^^^ WRONG Filename '10.52.0.62'. ^^^^^^^^^^ WRONG Load address: 0x100000 Loading: * TFTP error: 'File not found' (1) Starting again TftpStart() was modified to not modify the 'BootFile' string. Signed-off-by: Peter Tyser Signed-off-by: Ben Warren --- net/tftp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index ce6ea3d..3dac3d8 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -499,9 +499,8 @@ TftpStart (void) strncpy(tftp_filename, BootFile, MAX_LEN); tftp_filename[MAX_LEN-1] = 0; } else { - *p++ = '\0'; TftpServerIP = string_to_ip (BootFile); - strncpy(tftp_filename, p, MAX_LEN); + strncpy(tftp_filename, p + 1, MAX_LEN); tftp_filename[MAX_LEN-1] = 0; } } -- cgit v1.1 From c8aa7dfc18f7cc90d0aea6c7becbb67dfc5bba4b Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 31 Oct 2008 12:26:55 +0100 Subject: FPGA: move fpga drivers to drivers/fpga Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- Makefile | 1 + common/ACEX1K.c | 362 ------------------------- common/Makefile | 11 - common/altera.c | 283 -------------------- common/cyclon2.c | 301 --------------------- common/fpga.c | 335 ------------------------ common/spartan2.c | 663 ---------------------------------------------- common/spartan3.c | 668 ----------------------------------------------- common/stratixII.c | 231 ---------------- common/virtex2.c | 554 --------------------------------------- common/xilinx.c | 307 ---------------------- drivers/fpga/ACEX1K.c | 362 +++++++++++++++++++++++++ drivers/fpga/Makefile | 58 ++++ drivers/fpga/altera.c | 283 ++++++++++++++++++++ drivers/fpga/cyclon2.c | 301 +++++++++++++++++++++ drivers/fpga/fpga.c | 335 ++++++++++++++++++++++++ drivers/fpga/spartan2.c | 663 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/fpga/spartan3.c | 668 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/fpga/stratixII.c | 231 ++++++++++++++++ drivers/fpga/virtex2.c | 554 +++++++++++++++++++++++++++++++++++++++ drivers/fpga/xilinx.c | 307 ++++++++++++++++++++++ 21 files changed, 3763 insertions(+), 3715 deletions(-) delete mode 100644 common/ACEX1K.c delete mode 100644 common/altera.c delete mode 100644 common/cyclon2.c delete mode 100644 common/fpga.c delete mode 100644 common/spartan2.c delete mode 100644 common/spartan3.c delete mode 100644 common/stratixII.c delete mode 100644 common/virtex2.c delete mode 100644 common/xilinx.c create mode 100644 drivers/fpga/ACEX1K.c create mode 100644 drivers/fpga/Makefile create mode 100644 drivers/fpga/altera.c create mode 100644 drivers/fpga/cyclon2.c create mode 100644 drivers/fpga/fpga.c create mode 100644 drivers/fpga/spartan2.c create mode 100644 drivers/fpga/spartan3.c create mode 100644 drivers/fpga/stratixII.c create mode 100644 drivers/fpga/virtex2.c create mode 100644 drivers/fpga/xilinx.c diff --git a/Makefile b/Makefile index befb608..4eff1b5 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,7 @@ LIBS += disk/libdisk.a LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/block/libblock.a LIBS += drivers/dma/libdma.a +LIBS += drivers/fpga/libfpga.a LIBS += drivers/hwmon/libhwmon.a LIBS += drivers/i2c/libi2c.a LIBS += drivers/input/libinput.a diff --git a/common/ACEX1K.c b/common/ACEX1K.c deleted file mode 100644 index 3f79677..0000000 --- a/common/ACEX1K.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * (C) Copyright 2003 - * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de - * - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include /* core U-Boot definitions */ -#include /* ACEX device family */ - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CONFIG_SYS_FPGA_WAIT -#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */ -#endif - -static int ACEX1K_ps_load( Altera_desc *desc, void *buf, size_t bsize ); -static int ACEX1K_ps_dump( Altera_desc *desc, void *buf, size_t bsize ); -/* static int ACEX1K_ps_info( Altera_desc *desc ); */ -static int ACEX1K_ps_reloc( Altera_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* ACEX1K Generic Implementation */ -int ACEX1K_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); - ret_val = ACEX1K_ps_load (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int ACEX1K_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); - ret_val = ACEX1K_ps_dump (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int ACEX1K_info( Altera_desc *desc ) -{ - return FPGA_SUCCESS; -} - - -int ACEX1K_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Altera_ACEX1K) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case passive_serial: - ret_val = ACEX1K_ps_reloc (desc, reloc_offset); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ -/* ACEX1K Passive Serial Generic Implementation */ - -static int ACEX1K_ps_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns; - int i; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "config:\t0x%p\n" - "status:\t0x%p\n" - "clk:\t0x%p\n" - "data:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->config, fn->status, - fn->clk, fn->data, fn->done); -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */ - - udelay(2); /* T_cfg > 2us */ - - /* nSTATUS should be asserted now */ - (*fn->done) (cookie); - if ( !(*fn->status) (cookie) ) { - puts ("** nSTATUS is not asserted.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - - (*fn->config) (FALSE, TRUE, cookie); /* Deassert nCONFIG */ - udelay(2); /* T_cf2st1 < 4us */ - - /* Wait for nSTATUS to be released (i.e. deasserted) */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for STATUS to go high.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - (*fn->done) (cookie); - } while ((*fn->status) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - - /* Load the data */ - while (bytecount < bsize) { - unsigned char val=0; -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - /* Altera detects an error if INIT goes low (active) - while DONE is low (inactive) */ -#if 0 /* not yet implemented */ - if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { - puts ("** CRC error during FPGA load.\n"); - (*fn->abort) (cookie); - return (FPGA_FAIL); - } -#endif - val = data [bytecount ++ ]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->data) ( (val & 0x01), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val >>= 1; - i --; - } while (i > 0); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc (' '); /* terminate the dotted line */ -#endif - - /* - * Checking FPGA's CONF_DONE signal - correctly booted ? - */ - - if ( ! (*fn->done) (cookie) ) { - puts ("** Booting failed! CONF_DONE is still deasserted.\n"); - (*fn->abort) (cookie); - return (FPGA_FAIL); - } - - /* - * "DCLK must be clocked an additional 10 times fpr ACEX 1K..." - */ - - for (i = 0; i < 12; i++) { - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - } - - ret_val = FPGA_SUCCESS; - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - (*fn->post) (cookie); - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int ACEX1K_ps_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Passive Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int ACEX1K_ps_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_ACEX1K_Passive_Serial_fns *fn_r, *fn = - (Altera_ACEX1K_Passive_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Altera_ACEX1K_Passive_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Altera_ACEX1K_Passive_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Altera_pre_fn) addr; - - addr = (ulong) (fn->config) + reloc_offset; - fn_r->config = (Altera_config_fn) addr; - - addr = (ulong) (fn->status) + reloc_offset; - fn_r->status = (Altera_status_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Altera_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Altera_clk_fn) addr; - - addr = (ulong) (fn->data) + reloc_offset; - fn_r->data = (Altera_data_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Altera_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Altera_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} diff --git a/common/Makefile b/common/Makefile index 9dec4ec..596fef3 100644 --- a/common/Makefile +++ b/common/Makefile @@ -90,18 +90,7 @@ COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o COBJS-$(CONFIG_CMD_FDOS) += cmd_fdos.o COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o ifdef CONFIG_FPGA -COBJS-y += fpga.o COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o -COBJS-$(CONFIG_FPGA_SPARTAN2) += spartan2.o -COBJS-$(CONFIG_FPGA_SPARTAN3) += spartan3.o -COBJS-$(CONFIG_FPGA_VIRTEX2) += virtex2.o -COBJS-$(CONFIG_FPGA_XILINX) += xilinx.o -ifdef CONFIG_FPGA_ALTERA -COBJS-y += altera.o -COBJS-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o -COBJS-$(CONFIG_FPGA_CYCLON2) += cyclon2.o -COBJS-$(CONFIG_FPGA_STRATIX_II) += stratixII.o -endif endif COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o diff --git a/common/altera.c b/common/altera.c deleted file mode 100644 index 09dc0b2..0000000 --- a/common/altera.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * (C) Copyright 2003 - * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de - * - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Altera FPGA support - */ -#include -#include -#include - -/* Define FPGA_DEBUG to get debug printf's */ -/* #define FPGA_DEBUG */ - -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Local Static Functions */ -static int altera_validate (Altera_desc * desc, const char *fn); - -/* ------------------------------------------------------------------------- */ -int altera_load( Altera_desc *desc, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else { - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: -#if defined(CONFIG_FPGA_ACEX1K) - PRINTF ("%s: Launching the ACEX1K Loader...\n", - __FUNCTION__); - ret_val = ACEX1K_load (desc, buf, bsize); -#elif defined(CONFIG_FPGA_CYCLON2) - PRINTF ("%s: Launching the CYCLON II Loader...\n", - __FUNCTION__); - ret_val = CYC2_load (desc, buf, bsize); -#else - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); -#endif - break; - -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - PRINTF ("%s: Launching the Stratix II Loader...\n", - __FUNCTION__); - ret_val = StratixII_load (desc, buf, bsize); - break; -#endif - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - } - - return ret_val; -} - -int altera_dump( Altera_desc *desc, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else { - switch (desc->family) { - case Altera_ACEX1K: -#if defined(CONFIG_FPGA_ACEX) - PRINTF ("%s: Launching the ACEX1K Reader...\n", - __FUNCTION__); - ret_val = ACEX1K_dump (desc, buf, bsize); -#else - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); -#endif - break; - -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - PRINTF ("%s: Launching the Stratix II Reader...\n", - __FUNCTION__); - ret_val = StratixII_dump (desc, buf, bsize); - break; -#endif - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - } - - return ret_val; -} - -int altera_info( Altera_desc *desc ) -{ - int ret_val = FPGA_FAIL; - - if (altera_validate (desc, (char *)__FUNCTION__)) { - printf ("Family: \t"); - switch (desc->family) { - case Altera_ACEX1K: - printf ("ACEX1K\n"); - break; - case Altera_CYC2: - printf ("CYCLON II\n"); - break; - case Altera_StratixII: - printf ("Stratix II\n"); - break; - /* Add new family types here */ - default: - printf ("Unknown family type, %d\n", desc->family); - } - - printf ("Interface type:\t"); - switch (desc->iface) { - case passive_serial: - printf ("Passive Serial (PS)\n"); - break; - case passive_parallel_synchronous: - printf ("Passive Parallel Synchronous (PPS)\n"); - break; - case passive_parallel_asynchronous: - printf ("Passive Parallel Asynchronous (PPA)\n"); - break; - case passive_serial_asynchronous: - printf ("Passive Serial Asynchronous (PSA)\n"); - break; - case altera_jtag_mode: /* Not used */ - printf ("JTAG Mode\n"); - break; - case fast_passive_parallel: - printf ("Fast Passive Parallel (FPP)\n"); - break; - case fast_passive_parallel_security: - printf - ("Fast Passive Parallel with Security (FPPS) \n"); - break; - /* Add new interface types here */ - default: - printf ("Unsupported interface type, %d\n", desc->iface); - } - - printf ("Device Size: \t%d bytes\n" - "Cookie: \t0x%x (%d)\n", - desc->size, desc->cookie, desc->cookie); - - if (desc->iface_fns) { - printf ("Device Function Table @ 0x%p\n", desc->iface_fns); - switch (desc->family) { - case Altera_ACEX1K: - case Altera_CYC2: -#if defined(CONFIG_FPGA_ACEX1K) - ACEX1K_info (desc); -#elif defined(CONFIG_FPGA_CYCLON2) - CYC2_info (desc); -#else - /* just in case */ - printf ("%s: No support for ACEX1K devices.\n", - __FUNCTION__); -#endif - break; -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - StratixII_info (desc); - break; -#endif - /* Add new family types here */ - default: - /* we don't need a message here - we give one up above */ - break; - } - } else { - printf ("No Device Function Table.\n"); - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } - - return ret_val; -} - -int altera_reloc( Altera_desc *desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!altera_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else { - switch (desc->family) { - case Altera_ACEX1K: -#if defined(CONFIG_FPGA_ACEX1K) - ret_val = ACEX1K_reloc (desc, reloc_offset); -#else - printf ("%s: No support for ACEX devices.\n", - __FUNCTION__); -#endif - break; -#if defined(CONFIG_FPGA_STRATIX_II) - case Altera_StratixII: - ret_val = StratixII_reloc (desc, reloc_offset); - break; -#endif - case Altera_CYC2: -#if defined(CONFIG_FPGA_CYCLON2) - ret_val = CYC2_reloc (desc, reloc_offset); -#else - printf ("%s: No support for CYCLON II devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ - -static int altera_validate (Altera_desc * desc, const char *fn) -{ - int ret_val = FALSE; - - if (desc) { - if ((desc->family > min_altera_type) && - (desc->family < max_altera_type)) { - if ((desc->iface > min_altera_iface_type) && - (desc->iface < max_altera_iface_type)) { - if (desc->size) { - ret_val = TRUE; - } else { - printf ("%s: NULL part size\n", fn); - } - } else { - printf ("%s: Invalid Interface type, %d\n", - fn, desc->iface); - } - } else { - printf ("%s: Invalid family type, %d\n", fn, desc->family); - } - } else { - printf ("%s: NULL descriptor!\n", fn); - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ diff --git a/common/cyclon2.c b/common/cyclon2.c deleted file mode 100644 index 3ed64b2..0000000 --- a/common/cyclon2.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * (C) Copyright 2006 - * Heiko Schocher, hs@denx.de - * Based on ACE1XK.c - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include /* core U-Boot definitions */ -#include -#include /* ACEX device family */ - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CONFIG_SYS_FPGA_WAIT -#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */ -#endif - -static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize ); -static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize ); -/* static int CYC2_ps_info( Altera_desc *desc ); */ -static int CYC2_ps_reloc( Altera_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* CYCLON2 Generic Implementation */ -int CYC2_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); - ret_val = CYC2_ps_load (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); - ret_val = CYC2_ps_dump (desc, buf, bsize); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int CYC2_info( Altera_desc *desc ) -{ - return FPGA_SUCCESS; -} - -int CYC2_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Altera_CYC2) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case passive_serial: - ret_val = CYC2_ps_reloc (desc, reloc_offset); - break; - - /* Add new interface types here */ - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ -/* CYCLON2 Passive Serial Generic Implementation */ -static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns; - int ret = 0; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "config:\t0x%p\n" - "status:\t0x%p\n" - "write:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->config, fn->status, - fn->write, fn->done); -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */ - - udelay(2); /* T_cfg > 2us */ - - /* Wait for nSTATUS to be asserted */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for STATUS to go high.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } while (!(*fn->status) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - - ret = (*fn->write) (buf, bsize, TRUE, cookie); - if (ret) { - puts ("** Write failed.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts(" OK? ..."); -#endif - - CONFIG_FPGA_DELAY (); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc (' '); /* terminate the dotted line */ -#endif - - /* - * Checking FPGA's CONF_DONE signal - correctly booted ? - */ - - if ( ! (*fn->done) (cookie) ) { - puts ("** Booting failed! CONF_DONE is still deasserted.\n"); - (*fn->abort) (cookie); - return (FPGA_FAIL); - } -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts(" OK\n"); -#endif - - ret_val = FPGA_SUCCESS; - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - (*fn->post) (cookie); - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Passive Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int CYC2_ps_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Altera_CYC2_Passive_Serial_fns *fn_r, *fn = - (Altera_CYC2_Passive_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Altera_CYC2_Passive_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Altera_CYC2_Passive_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Altera_pre_fn) addr; - - addr = (ulong) (fn->config) + reloc_offset; - fn_r->config = (Altera_config_fn) addr; - - addr = (ulong) (fn->status) + reloc_offset; - fn_r->status = (Altera_status_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Altera_done_fn) addr; - - addr = (ulong) (fn->write) + reloc_offset; - fn_r->write = (Altera_write_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Altera_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Altera_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} diff --git a/common/fpga.c b/common/fpga.c deleted file mode 100644 index 67a6c30..0000000 --- a/common/fpga.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Generic FPGA support - */ -#include /* core U-Boot definitions */ -#include /* xilinx specific definitions */ -#include /* altera specific definitions */ - -#if 0 -#define FPGA_DEBUG /* define FPGA_DEBUG to get debug messages */ -#endif - -/* Local definitions */ -#ifndef CONFIG_MAX_FPGA_DEVICES -#define CONFIG_MAX_FPGA_DEVICES 5 -#endif - -/* Enable/Disable debug console messages */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Local static data */ -static ulong relocation_offset = 0; -static int next_desc = FPGA_INVALID_DEVICE; -static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES]; - -/* Local static functions */ -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ); -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, - size_t bsize, char *fn ); -static int fpga_dev_info( int devnum ); - - -/* ------------------------------------------------------------------------- */ - -/* fpga_no_sup - * 'no support' message function - */ -static void fpga_no_sup( char *fn, char *msg ) -{ - if ( fn && msg ) { - printf( "%s: No support for %s.\n", fn, msg); - } else if ( msg ) { - printf( "No support for %s.\n", msg); - } else { - printf( "No FPGA suport!\n"); - } -} - - -/* fpga_get_desc - * map a device number to a descriptor - */ -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ) -{ - fpga_desc *desc = (fpga_desc * )NULL; - - if (( devnum >= 0 ) && (devnum < next_desc )) { - desc = &desc_table[devnum]; - PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n", - __FUNCTION__, devnum, desc ); - } - - return desc; -} - - -/* fpga_validate - * generic parameter checking code - */ -static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, - size_t bsize, char *fn ) -{ - fpga_desc * desc = fpga_get_desc( devnum ); - - if ( !desc ) { - printf( "%s: Invalid device number %d\n", fn, devnum ); - } - - if ( !buf ) { - printf( "%s: Null buffer.\n", fn ); - return (fpga_desc * const)NULL; - } - return desc; -} - - -/* fpga_dev_info - * generic multiplexing code - */ -static int fpga_dev_info( int devnum ) -{ - int ret_val = FPGA_FAIL; /* assume failure */ - const fpga_desc * const desc = fpga_get_desc( devnum ); - - if ( desc ) { - PRINTF( "%s: Device Descriptor @ 0x%p\n", - __FUNCTION__, desc->devdesc ); - - switch ( desc->devtype ) { - case fpga_xilinx: -#if defined(CONFIG_FPGA_XILINX) - printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc ); - ret_val = xilinx_info( desc->devdesc ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if defined(CONFIG_FPGA_ALTERA) - printf( "Altera Device\nDescriptor @ 0x%p\n", desc ); - ret_val = altera_info( desc->devdesc ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, desc->devtype ); - } - } else { - printf( "%s: Invalid device number %d\n", - __FUNCTION__, devnum ); - } - - return ret_val; -} - - -/* fpga_reloc - * generic multiplexing code - */ -int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off ) -{ - int ret_val = FPGA_FAIL; - - PRINTF( "%s: Relocating Device of type %d @ 0x%p with offset %lx\n", - __FUNCTION__, devtype, desc, reloc_off ); - - switch ( devtype ) { - case fpga_xilinx: -#if defined(CONFIG_FPGA_XILINX) - ret_val = xilinx_reloc( desc, reloc_off ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if defined(CONFIG_FPGA_ALTERA) - ret_val = altera_reloc( desc, reloc_off ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, devtype ); - } - - return ret_val; -} - -/* ------------------------------------------------------------------------- */ -/* fgpa_init is usually called from misc_init_r() and MUST be called - * before any of the other fpga functions are used. - */ -void fpga_init( ulong reloc_off ) -{ - relocation_offset = reloc_off; - next_desc = 0; - memset( desc_table, 0, sizeof(desc_table)); - - PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA ); -} - -/* fpga_count - * Basic interface function to get the current number of devices available. - */ -int fpga_count( void ) -{ - return next_desc; -} - -/* fpga_add - * Attempts to relocate the device/board specific interface code - * to the proper RAM locations and adds the device descriptor to - * the device table. - */ -int fpga_add( fpga_type devtype, void *desc ) -{ - int devnum = FPGA_INVALID_DEVICE; - - if ( next_desc < 0 ) { - printf( "%s: FPGA support not initialized!\n", __FUNCTION__ ); - } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) { - if ( desc ) { - if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) { - if ( fpga_reloc( devtype, desc, relocation_offset ) - == FPGA_SUCCESS ) { - devnum = next_desc; - desc_table[next_desc].devtype = devtype; - desc_table[next_desc++].devdesc = desc; - } else { - printf( "%s: Unable to relocate device interface table!\n", - __FUNCTION__ ); - } - } else { - printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ ); - } - } else { - printf( "%s: NULL device descriptor\n", __FUNCTION__ ); - } - } else { - printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype ); - } - - return devnum; -} - -/* - * Generic multiplexing code - */ -int fpga_load( int devnum, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume failure */ - fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); - - if ( desc ) { - switch ( desc->devtype ) { - case fpga_xilinx: -#if defined(CONFIG_FPGA_XILINX) - ret_val = xilinx_load( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if defined(CONFIG_FPGA_ALTERA) - ret_val = altera_load( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, desc->devtype ); - } - } - - return ret_val; -} - -/* fpga_dump - * generic multiplexing code - */ -int fpga_dump( int devnum, void *buf, size_t bsize ) -{ - int ret_val = FPGA_FAIL; /* assume failure */ - fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); - - if ( desc ) { - switch ( desc->devtype ) { - case fpga_xilinx: -#if defined(CONFIG_FPGA_XILINX) - ret_val = xilinx_dump( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); -#endif - break; - case fpga_altera: -#if defined(CONFIG_FPGA_ALTERA) - ret_val = altera_dump( desc->devdesc, buf, bsize ); -#else - fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); -#endif - break; - default: - printf( "%s: Invalid or unsupported device type %d\n", - __FUNCTION__, desc->devtype ); - } - } - - return ret_val; -} - - -/* fpga_info - * front end to fpga_dev_info. If devnum is invalid, report on all - * available devices. - */ -int fpga_info( int devnum ) -{ - if ( devnum == FPGA_INVALID_DEVICE ) { - if ( next_desc > 0 ) { - int dev; - - for ( dev = 0; dev < next_desc; dev++ ) { - fpga_dev_info( dev ); - } - return FPGA_SUCCESS; - } else { - printf( "%s: No FPGA devices available.\n", __FUNCTION__ ); - return FPGA_FAIL; - } - } - else return fpga_dev_info( devnum ); -} - -/* ------------------------------------------------------------------------- */ diff --git a/common/spartan2.c b/common/spartan2.c deleted file mode 100644 index f5ba7fc..0000000 --- a/common/spartan2.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include /* core U-Boot definitions */ -#include /* Spartan-II device family */ - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#undef CONFIG_SYS_FPGA_CHECK_BUSY -#undef CONFIG_SYS_FPGA_PROG_FEEDBACK - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CONFIG_SYS_FPGA_WAIT -#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ -#endif - -static int Spartan2_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan2_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan2_sp_info( Xilinx_desc *desc ); */ -static int Spartan2_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -static int Spartan2_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan2_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan2_ss_info( Xilinx_desc *desc ); */ -static int Spartan2_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Generic Implementation */ -int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); - ret_val = Spartan2_ss_load (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); - ret_val = Spartan2_sp_load (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan2_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); - ret_val = Spartan2_ss_dump (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); - ret_val = Spartan2_sp_dump (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan2_info( Xilinx_desc *desc ) -{ - return FPGA_SUCCESS; -} - - -int Spartan2_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Xilinx_Spartan2) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case slave_serial: - ret_val = Spartan2_ss_reloc (desc, reloc_offset); - break; - - case slave_parallel: - ret_val = Spartan2_sp_reloc (desc, reloc_offset); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Slave Parallel Generic Implementation */ - -static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pre: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "err:\t0x%p\n" - "clk:\t0x%p\n" - "cs:\t0x%p\n" - "wr:\t0x%p\n" - "read data:\t0x%p\n" - "write data:\t0x%p\n" - "busy:\t0x%p\n" - "abort:\t0x%p\n", - "post:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, - fn->abort, fn->post); - - /* - * This code is designed to emulate the "Express Style" - * Continuous Data Loading in Slave Parallel Mode for - * the Spartan-II Family. - */ -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT and BUSY to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); - - (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* Load the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - /* XXX - Check the error bit? */ - - (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CONFIG_SYS_FPGA_CHECK_BUSY - ts = get_timer (0); /* get current time */ - while ((*fn->busy) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for BUSY to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } -#endif - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ - (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - while ((*fn->done) (cookie) == FPGA_FAIL) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts ("Done.\n"); -#endif - } - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - - else { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts ("Fail.\n"); -#endif - } - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; - - if (fn) { - unsigned char *data = (unsigned char *) buf; - size_t bytecount = 0; - int cookie = desc->cookie; /* make a local copy */ - - printf ("Starting Dump of FPGA Device %d...\n", cookie); - - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* dump the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - puts ("Done.\n"); - - /* XXX - checksum the data? */ - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - - -static int Spartan2_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Parallel_fns *fn_r, *fn = - (Xilinx_Spartan2_Slave_Parallel_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan2_Slave_Parallel_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan2_Slave_Parallel_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->err) + reloc_offset; - fn_r->err = (Xilinx_err_fn) addr; - - addr = (ulong) (fn->cs) + reloc_offset; - fn_r->cs = (Xilinx_cs_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - addr = (ulong) (fn->rdata) + reloc_offset; - fn_r->rdata = (Xilinx_rdata_fn) addr; - - addr = (ulong) (fn->wdata) + reloc_offset; - fn_r->wdata = (Xilinx_wdata_fn) addr; - - addr = (ulong) (fn->busy) + reloc_offset; - fn_r->busy = (Xilinx_busy_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Xilinx_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -/* ------------------------------------------------------------------------- */ - -static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Serial_fns *fn = desc->iface_fns; - int i; - unsigned char val; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "clk:\t0x%p\n" - "wr:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pgm, fn->init, - fn->clk, fn->wr, fn->done); -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Wait for INIT state (init low) */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to start.\n"); - return FPGA_FAIL; - } - } while (!(*fn->init) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - return FPGA_FAIL; - } - } while ((*fn->init) (cookie)); - - /* Load the data */ - while (bytecount < bsize) { - - /* Xilinx detects an error if INIT goes low (active) - while DONE is low (inactive) */ - if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { - puts ("** CRC error during FPGA load.\n"); - return (FPGA_FAIL); - } - val = data [bytecount ++]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->wr) ((val & 0x80), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val <<= 1; - i --; - } while (i > 0); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - (*fn->wr) (TRUE, TRUE, cookie); - - while (! (*fn->done) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - putc ('*'); - - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - ret_val = FPGA_FAIL; - break; - } - } - putc ('\n'); /* terminate the dotted line */ - - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Slave Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int Spartan2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan2_Slave_Serial_fns *fn_r, *fn = - (Xilinx_Spartan2_Slave_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan2_Slave_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan2_Slave_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - if (fn->pre) { - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - } - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - if (fn->post) { - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - } - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} diff --git a/common/spartan3.c b/common/spartan3.c deleted file mode 100644 index 9ce41f1..0000000 --- a/common/spartan3.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Configuration support for Xilinx Spartan3 devices. Based - * on spartan2.c (Rich Ireland, rireland@enterasys.com). - */ - -#include /* core U-Boot definitions */ -#include /* Spartan-II device family */ - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#undef CONFIG_SYS_FPGA_CHECK_BUSY -#undef CONFIG_SYS_FPGA_PROG_FEEDBACK - -/* Note: The assumption is that we cannot possibly run fast enough to - * overrun the device (the Slave Parallel mode can free run at 50MHz). - * If there is a need to operate slower, define CONFIG_FPGA_DELAY in - * the board config file to slow things down. - */ -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CONFIG_SYS_FPGA_WAIT -#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ -#endif - -static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan3_sp_info( Xilinx_desc *desc ); */ -static int Spartan3_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); -static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); -/* static int Spartan3_ss_info( Xilinx_desc *desc ); */ -static int Spartan3_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Generic Implementation */ -int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); - ret_val = Spartan3_ss_load (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); - ret_val = Spartan3_sp_load (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); - ret_val = Spartan3_ss_dump (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); - ret_val = Spartan3_sp_dump (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - -int Spartan3_info( Xilinx_desc *desc ) -{ - return FPGA_SUCCESS; -} - - -int Spartan3_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (desc->family != Xilinx_Spartan3) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case slave_serial: - ret_val = Spartan3_ss_reloc (desc, reloc_offset); - break; - - case slave_parallel: - ret_val = Spartan3_sp_reloc (desc, reloc_offset); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ -/* Spartan-II Slave Parallel Generic Implementation */ - -static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pre: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "err:\t0x%p\n" - "clk:\t0x%p\n" - "cs:\t0x%p\n" - "wr:\t0x%p\n" - "read data:\t0x%p\n" - "write data:\t0x%p\n" - "busy:\t0x%p\n" - "abort:\t0x%p\n", - "post:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, - fn->abort, fn->post); - - /* - * This code is designed to emulate the "Express Style" - * Continuous Data Loading in Slave Parallel Mode for - * the Spartan-II Family. - */ -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT and BUSY to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); - - (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* Load the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - /* XXX - Check the error bit? */ - - (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CONFIG_SYS_FPGA_CHECK_BUSY - ts = get_timer (0); /* get current time */ - while ((*fn->busy) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for BUSY to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - return FPGA_FAIL; - } - } -#endif - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ - (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - while ((*fn->done) (cookie) == FPGA_FAIL) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - (*fn->abort) (cookie); /* abort the burn */ - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts ("Done.\n"); -#endif - } - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - - else { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts ("Fail.\n"); -#endif - } - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; - - if (fn) { - unsigned char *data = (unsigned char *) buf; - size_t bytecount = 0; - int cookie = desc->cookie; /* make a local copy */ - - printf ("Starting Dump of FPGA Device %d...\n", cookie); - - (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - /* dump the data */ - while (bytecount < bsize) { - /* XXX - do we check for an Ctrl-C press in here ??? */ - - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - puts ("Done.\n"); - - /* XXX - checksum the data? */ - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - - -static int Spartan3_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Parallel_fns *fn_r, *fn = - (Xilinx_Spartan3_Slave_Parallel_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan3_Slave_Parallel_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan3_Slave_Parallel_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->err) + reloc_offset; - fn_r->err = (Xilinx_err_fn) addr; - - addr = (ulong) (fn->cs) + reloc_offset; - fn_r->cs = (Xilinx_cs_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - addr = (ulong) (fn->rdata) + reloc_offset; - fn_r->rdata = (Xilinx_rdata_fn) addr; - - addr = (ulong) (fn->wdata) + reloc_offset; - fn_r->wdata = (Xilinx_wdata_fn) addr; - - addr = (ulong) (fn->busy) + reloc_offset; - fn_r->busy = (Xilinx_busy_fn) addr; - - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Xilinx_abort_fn) addr; - - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} - -/* ------------------------------------------------------------------------- */ - -static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns; - int i; - unsigned char val; - - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; /* make a local copy */ - unsigned long ts; /* timestamp */ - - PRINTF ("%s: Function Table:\n" - "ptr:\t0x%p\n" - "struct: 0x%p\n" - "pgm:\t0x%p\n" - "init:\t0x%p\n" - "clk:\t0x%p\n" - "wr:\t0x%p\n" - "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->pgm, fn->init, - fn->clk, fn->wr, fn->done); -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...\n", cookie); -#endif - - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* Establish the initial state */ - (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ - - /* Wait for INIT state (init low) */ - ts = get_timer (0); /* get current time */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to start.\n"); - return FPGA_FAIL; - } - } while (!(*fn->init) (cookie)); - - /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); - (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ - - ts = get_timer (0); /* get current time */ - /* Now wait for INIT to go high */ - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for INIT to clear.\n"); - return FPGA_FAIL; - } - } while ((*fn->init) (cookie)); - - /* Load the data */ - while (bytecount < bsize) { - - /* Xilinx detects an error if INIT goes low (active) - while DONE is low (inactive) */ - if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { - puts ("** CRC error during FPGA load.\n"); - return (FPGA_FAIL); - } - val = data [bytecount ++]; - i = 8; - do { - /* Deassert the clock */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Write data */ - (*fn->wr) ((val & 0x80), TRUE, cookie); - CONFIG_FPGA_DELAY (); - /* Assert the clock */ - (*fn->clk) (TRUE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - val <<= 1; - i --; - } while (i > 0); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); /* let them know we are alive */ -#endif - } - - CONFIG_FPGA_DELAY (); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); /* terminate the dotted line */ -#endif - - /* now check for done signal */ - ts = get_timer (0); /* get current time */ - ret_val = FPGA_SUCCESS; - (*fn->wr) (TRUE, TRUE, cookie); - - while (! (*fn->done) (cookie)) { - /* XXX - we should have a check in here somewhere to - * make sure we aren't busy forever... */ - - CONFIG_FPGA_DELAY (); - (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ - - putc ('*'); - - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for DONE to clear.\n"); - ret_val = FPGA_FAIL; - break; - } - } - putc ('\n'); /* terminate the dotted line */ - - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } -#endif - - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; -} - -static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - /* Readback is only available through the Slave Parallel and */ - /* boundary-scan interfaces. */ - printf ("%s: Slave Serial Dumping is unavailable\n", - __FUNCTION__); - return FPGA_FAIL; -} - -static int Spartan3_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume the worst */ - Xilinx_Spartan3_Slave_Serial_fns *fn_r, *fn = - (Xilinx_Spartan3_Slave_Serial_fns *) (desc->iface_fns); - - if (fn) { - ulong addr; - - /* Get the relocated table address */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Spartan3_Slave_Serial_fns *) addr; - - if (!fn_r->relocated) { - - if (memcmp (fn_r, fn, - sizeof (Xilinx_Spartan3_Slave_Serial_fns)) - == 0) { - /* good copy of the table, fix the descriptor pointer */ - desc->iface_fns = fn_r; - } else { - PRINTF ("%s: Invalid function table at 0x%p\n", - __FUNCTION__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, - desc); - - if (fn->pre) { - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - } - - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - - if (fn->post) { - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - } - - fn_r->relocated = TRUE; - - } else { - /* this table has already been moved */ - /* XXX - should check to see if the descriptor is correct */ - desc->iface_fns = fn_r; - } - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - - return ret_val; - -} diff --git a/common/stratixII.c b/common/stratixII.c deleted file mode 100644 index 7556dbf..0000000 --- a/common/stratixII.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * (C) Copyright 2007 - * Eran Liberty, Extricom , eran.liberty@gmail.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include /* core U-Boot definitions */ -#include - -int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize, - int isSerial, int isSecure); -int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize); - -/****************************************************************/ -/* Stratix II Generic Implementation */ -int StratixII_load (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 1, 0); - break; - case fast_passive_parallel: - ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 0); - break; - case fast_passive_parallel_security: - ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 1); - break; - - /* Add new interface types here */ - default: - printf ("%s: Unsupported interface type, %d\n", __FUNCTION__, - desc->iface); - } - return ret_val; -} - -int StratixII_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case passive_serial: - case fast_passive_parallel: - case fast_passive_parallel_security: - ret_val = StratixII_ps_fpp_dump (desc, buf, bsize); - break; - /* Add new interface types here */ - default: - printf ("%s: Unsupported interface type, %d\n", __FUNCTION__, - desc->iface); - } - return ret_val; -} - -int StratixII_info (Altera_desc * desc) -{ - return FPGA_SUCCESS; -} - -int StratixII_reloc (Altera_desc * desc, ulong reloc_offset) -{ - int i; - uint32_t dest = (uint32_t) desc & 0xff000000; - - /* we assume a relocated code and non relocated code has different upper 8 bits */ - if (dest != ((uint32_t) desc->iface_fns & 0xff000000)) { - desc->iface_fns = - (void *)((uint32_t) (desc->iface_fns) + reloc_offset); - } - for (i = 0; i < sizeof (altera_board_specific_func) / sizeof (void *); - i++) { - if (dest != - ((uint32_t) (((void **)(desc->iface_fns))[i]) & 0xff000000)) - { - ((void **)(desc->iface_fns))[i] = - (void - *)(((uint32_t) (((void **)(desc->iface_fns))[i])) + - reloc_offset); - } - } - return FPGA_SUCCESS; -} - -int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize) -{ - printf ("Stratix II Fast Passive Parallel dump is not implemented\n"); - return FPGA_FAIL; -} - -int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize, - int isSerial, int isSecure) -{ - altera_board_specific_func *fns; - int cookie; - int ret_val = FPGA_FAIL; - int bytecount; - char *buff = buf; - int i; - - if (!desc) { - printf ("%s(%d) Altera_desc missing\n", __FUNCTION__, __LINE__); - return FPGA_FAIL; - } - if (!buff) { - printf ("%s(%d) buffer is missing\n", __FUNCTION__, __LINE__); - return FPGA_FAIL; - } - if (!bsize) { - printf ("%s(%d) size is zero\n", __FUNCTION__, __LINE__); - return FPGA_FAIL; - } - if (!desc->iface_fns) { - printf - ("%s(%d) Altera_desc function interface table is missing\n", - __FUNCTION__, __LINE__); - return FPGA_FAIL; - } - fns = (altera_board_specific_func *) (desc->iface_fns); - cookie = desc->cookie; - - if (! - (fns->config && fns->status && fns->done && fns->data - && fns->abort)) { - printf - ("%s(%d) Missing some function in the function interface table\n", - __FUNCTION__, __LINE__); - return FPGA_FAIL; - } - - /* 1. give board specific a chance to do anything before we start */ - if (fns->pre) { - if ((ret_val = fns->pre (cookie)) < 0) { - return ret_val; - } - } - - /* from this point on we must fail gracfully by calling lower layer abort */ - - /* 2. Strat burn cycle by deasserting config for t_CFG and waiting t_CF2CK after reaserted */ - fns->config (0, 1, cookie); - udelay (5); /* nCONFIG low pulse width 2usec */ - fns->config (1, 1, cookie); - udelay (100); /* nCONFIG high to first rising edge on DCLK */ - - /* 3. Start the Data cycle with clk deasserted */ - bytecount = 0; - fns->clk (0, 1, cookie); - - printf ("loading to fpga "); - while (bytecount < bsize) { - /* 3.1 check stratix has not signaled us an error */ - if (fns->status (cookie) != 1) { - printf - ("\n%s(%d) Stratix failed (byte transfered till failure 0x%x)\n", - __FUNCTION__, __LINE__, bytecount); - fns->abort (cookie); - return FPGA_FAIL; - } - if (isSerial) { - int i; - uint8_t data = buff[bytecount++]; - for (i = 0; i < 8; i++) { - /* 3.2(ps) put data on the bus */ - fns->data ((data >> i) & 1, 1, cookie); - - /* 3.3(ps) clock once */ - fns->clk (1, 1, cookie); - fns->clk (0, 1, cookie); - } - } else { - /* 3.2(fpp) put data on the bus */ - fns->data (buff[bytecount++], 1, cookie); - - /* 3.3(fpp) clock once */ - fns->clk (1, 1, cookie); - fns->clk (0, 1, cookie); - - /* 3.4(fpp) for secure cycle push 3 more clocks */ - for (i = 0; isSecure && i < 3; i++) { - fns->clk (1, 1, cookie); - fns->clk (0, 1, cookie); - } - } - - /* 3.5 while clk is deasserted it is safe to print some progress indication */ - if ((bytecount % (bsize / 100)) == 0) { - printf ("\b\b\b%02d\%", bytecount * 100 / bsize); - } - } - - /* 4. Set one last clock and check conf done signal */ - fns->clk (1, 1, cookie); - udelay (100); - if (!fns->done (cookie)) { - printf (" error!.\n"); - fns->abort (cookie); - return FPGA_FAIL; - } else { - printf ("\b\b\b done.\n"); - } - - /* 5. call lower layer post configuration */ - if (fns->post) { - if ((ret_val = fns->post (cookie)) < 0) { - fns->abort (cookie); - return ret_val; - } - } - - return FPGA_SUCCESS; -} diff --git a/common/virtex2.c b/common/virtex2.c deleted file mode 100644 index 50d0921..0000000 --- a/common/virtex2.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * Keith Outwater, keith_outwater@mvis.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Configuration support for Xilinx Virtex2 devices. Based - * on spartan2.c (Rich Ireland, rireland@enterasys.com). - */ - -#include -#include - -#if 0 -#define FPGA_DEBUG -#endif - -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* - * If the SelectMap interface can be overrun by the processor, define - * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration - * file and add board-specific support for checking BUSY status. By default, - * assume that the SelectMap interface cannot be overrun. - */ -#ifndef CONFIG_SYS_FPGA_CHECK_BUSY -#undef CONFIG_SYS_FPGA_CHECK_BUSY -#endif - -#ifndef CONFIG_FPGA_DELAY -#define CONFIG_FPGA_DELAY() -#endif - -#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK -#define CONFIG_SYS_FPGA_PROG_FEEDBACK -#endif - -/* - * Don't allow config cycle to be interrupted - */ -#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC -#undef CONFIG_SYS_FPGA_CHECK_CTRLC -#endif - -/* - * Check for errors during configuration by default - */ -#ifndef CONFIG_SYS_FPGA_CHECK_ERROR -#define CONFIG_SYS_FPGA_CHECK_ERROR -#endif - -/* - * The default timeout in mS for INIT_B to deassert after PROG_B has - * been deasserted. Per the latest Virtex II Handbook (page 347), the - * max time from PORG_B deassertion to INIT_B deassertion is 4uS per - * data frame for the XC2V8000. The XC2V8000 has 2860 data frames - * which yields 11.44 mS. So let's make it bigger in order to handle - * an XC2V1000, if anyone can ever get ahold of one. - */ -#ifndef CONFIG_SYS_FPGA_WAIT_INIT -#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */ -#endif - -/* - * The default timeout for waiting for BUSY to deassert during configuration. - * This is normally not necessary since for most reasonable configuration - * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. - */ -#ifndef CONFIG_SYS_FPGA_WAIT_BUSY -#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/ -#endif - -/* Default timeout for waiting for FPGA to enter operational mode after - * configuration data has been written. - */ -#ifndef CONFIG_SYS_FPGA_WAIT_CONFIG -#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */ -#endif - -static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset); - -static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize); -static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset); - -int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); - ret_val = Virtex2_ss_load (desc, buf, bsize); - break; - - case slave_selectmap: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); - ret_val = Virtex2_ssm_load (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - return ret_val; -} - -int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - - switch (desc->iface) { - case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); - ret_val = Virtex2_ss_dump (desc, buf, bsize); - break; - - case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); - ret_val = Virtex2_ssm_dump (desc, buf, bsize); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - return ret_val; -} - -int Virtex2_info (Xilinx_desc * desc) -{ - return FPGA_SUCCESS; -} - -int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; - - if (desc->family != Xilinx_Virtex2) { - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - return FPGA_FAIL; - } else - switch (desc->iface) { - case slave_serial: - ret_val = Virtex2_ss_reloc (desc, reloc_offset); - break; - - case slave_selectmap: - ret_val = Virtex2_ssm_reloc (desc, reloc_offset); - break; - - default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); - } - return ret_val; -} - -/* - * Virtex-II Slave SelectMap configuration loader. Configuration via - * SelectMap is as follows: - * 1. Set the FPGA's PROG_B line low. - * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. - * 3. Write data to the SelectMap port. If INIT_B goes low at any time - * this process, a configuration error (most likely CRC failure) has - * ocurred. At this point a status word may be read from the - * SelectMap interface to determine the source of the problem (You - * could, for instance, put this in your 'abort' function handler). - * 4. After all data has been written, test the state of the FPGA - * INIT_B and DONE lines. If both are high, configuration has - * succeeded. Congratulations! - */ -static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; - - PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", - __FUNCTION__, __LINE__, fn); - - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; - int cookie = desc->cookie; - unsigned long ts; - - /* Gotta split this one up (so the stack won't blow??) */ - PRINTF ("%s:%d: Function Table:\n" - " base 0x%p\n" - " struct 0x%p\n" - " pre 0x%p\n" - " prog 0x%p\n" - " init 0x%p\n" - " error 0x%p\n", - __FUNCTION__, __LINE__, - &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); - PRINTF (" clock 0x%p\n" - " cs 0x%p\n" - " write 0x%p\n" - " rdata 0x%p\n" - " wdata 0x%p\n" - " busy 0x%p\n" - " abort 0x%p\n" - " post 0x%p\n\n", - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, - fn->busy, fn->abort, fn->post); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Initializing FPGA Device %d...\n", cookie); -#endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) { - (*fn->pre) (cookie); - } - - /* - * Assert the program line. The minimum pulse width for - * Virtex II devices is 300 nS (Tprogram parameter in datasheet). - * There is no maximum value for the pulse width. Check to make - * sure that INIT_B goes low after assertion of PROG_B - */ - (*fn->pgm) (TRUE, TRUE, cookie); - udelay (10); - ts = get_timer (0); - do { - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" - " to assert.\n", __FUNCTION__, __LINE__, - CONFIG_SYS_FPGA_WAIT_INIT); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } while (!(*fn->init) (cookie)); - - (*fn->pgm) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); - - /* - * Start a timer and wait for INIT_B to go high - */ - ts = get_timer (0); - do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" - " to deassert.\n", __FUNCTION__, __LINE__, - CONFIG_SYS_FPGA_WAIT_INIT); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); - - (*fn->wr) (TRUE, TRUE, cookie); - (*fn->cs) (TRUE, TRUE, cookie); - - udelay (10000); - - /* - * Load the data byte by byte - */ - while (bytecount < bsize) { -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - - if ((*fn->done) (cookie) == FPGA_SUCCESS) { - PRINTF ("%s:%d:done went active early, bytecount = %d\n", - __FUNCTION__, __LINE__, bytecount); - break; - } - -#ifdef CONFIG_SYS_FPGA_CHECK_ERROR - if ((*fn->init) (cookie)) { - printf ("\n%s:%d: ** Error: INIT asserted during" - " configuration\n", __FUNCTION__, __LINE__); - printf ("%d = buffer offset, %d = buffer size\n", - bytecount, bsize); - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - - (*fn->wdata) (data[bytecount++], TRUE, cookie); - CONFIG_FPGA_DELAY (); - - /* - * Cycle the clock pin - */ - (*fn->clk) (FALSE, TRUE, cookie); - CONFIG_FPGA_DELAY (); - (*fn->clk) (TRUE, TRUE, cookie); - -#ifdef CONFIG_SYS_FPGA_CHECK_BUSY - ts = get_timer (0); - while ((*fn->busy) (cookie)) { - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { - printf ("%s:%d: ** Timeout after %d ticks waiting for" - " BUSY to deassert\n", - __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY); - (*fn->abort) (cookie); - return FPGA_FAIL; - } - } -#endif - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); -#endif - } - - /* - * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. - */ - CONFIG_FPGA_DELAY (); - (*fn->cs) (FALSE, TRUE, cookie); - (*fn->wr) (FALSE, TRUE, cookie); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); -#endif - - /* - * Check for successful configuration. FPGA INIT_B and DONE should - * both be high upon successful configuration. - */ - ts = get_timer (0); - ret_val = FPGA_SUCCESS; - while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { - printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" - "assert and INIT to deassert\n", - __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); - (*fn->abort) (cookie); - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Initialization of FPGA device %d complete\n", cookie); -#endif - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) { - (*fn->post) (cookie); - } - } else { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("** Initialization of FPGA device %d FAILED\n", - cookie); -#endif - } - } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); - } - return ret_val; -} - -/* - * Read the FPGA configuration data - */ -static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; - - if (fn) { - unsigned char *data = (unsigned char *) buf; - size_t bytecount = 0; - int cookie = desc->cookie; - - printf ("Starting Dump of FPGA Device %d...\n", cookie); - - (*fn->cs) (TRUE, TRUE, cookie); - (*fn->clk) (TRUE, TRUE, cookie); - - while (bytecount < bsize) { -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); - return FPGA_FAIL; - } -#endif - /* - * Cycle the clock and read the data - */ - (*fn->clk) (FALSE, TRUE, cookie); - (*fn->clk) (TRUE, TRUE, cookie); - (*fn->rdata) (&(data[bytecount++]), cookie); -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc ('.'); -#endif - } - - /* - * Deassert CS_B and cycle the clock to deselect the device. - */ - (*fn->cs) (FALSE, FALSE, cookie); - (*fn->clk) (FALSE, TRUE, cookie); - (*fn->clk) (TRUE, TRUE, cookie); - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); -#endif - puts ("Done.\n"); - } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); - } - return ret_val; -} - -/* - * Relocate the addresses in the function table from FLASH (or ROM, - * or whatever) to RAM. - */ -static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - ulong addr; - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn = - (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns); - - if (fn) { - /* - * Get the relocated table address - */ - addr = (ulong) fn + reloc_offset; - fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr; - - /* - * Check to see if the table has already been relocated. If not, do - * a sanity check to make sure there is a faithful copy of the - * FLASH based function table in RAM, then adjust the table. - */ - if (!fn_r->relocated) { - if (memcmp - (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns)) - == 0) { - desc->iface_fns = fn_r; - } else { - PRINTF ("%s:%d: Invalid function table at 0x%p\n", - __FUNCTION__, __LINE__, fn_r); - return FPGA_FAIL; - } - - PRINTF ("%s:%d: Relocating descriptor at 0x%p\n", - __FUNCTION__, __LINE__, desc); - - addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; - addr = (ulong) (fn->pgm) + reloc_offset; - fn_r->pgm = (Xilinx_pgm_fn) addr; - addr = (ulong) (fn->init) + reloc_offset; - fn_r->init = (Xilinx_init_fn) addr; - addr = (ulong) (fn->done) + reloc_offset; - fn_r->done = (Xilinx_done_fn) addr; - addr = (ulong) (fn->err) + reloc_offset; - fn_r->err = (Xilinx_err_fn) addr; - addr = (ulong) (fn->clk) + reloc_offset; - fn_r->clk = (Xilinx_clk_fn) addr; - addr = (ulong) (fn->cs) + reloc_offset; - fn_r->cs = (Xilinx_cs_fn) addr; - addr = (ulong) (fn->wr) + reloc_offset; - fn_r->wr = (Xilinx_wr_fn) addr; - addr = (ulong) (fn->rdata) + reloc_offset; - fn_r->rdata = (Xilinx_rdata_fn) addr; - addr = (ulong) (fn->wdata) + reloc_offset; - fn_r->wdata = (Xilinx_wdata_fn) addr; - addr = (ulong) (fn->busy) + reloc_offset; - fn_r->busy = (Xilinx_busy_fn) addr; - addr = (ulong) (fn->abort) + reloc_offset; - fn_r->abort = (Xilinx_abort_fn) addr; - addr = (ulong) (fn->post) + reloc_offset; - fn_r->post = (Xilinx_post_fn) addr; - fn_r->relocated = TRUE; - } else { - printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r); - desc->iface_fns = fn_r; - } - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); - } - return ret_val; -} - -static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); - return FPGA_FAIL; -} - -static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); - return FPGA_FAIL; -} - -static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; - Xilinx_Virtex2_Slave_Serial_fns *fn = - (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns); - - if (fn) { - printf ("%s:%d: Slave Serial Loading is unsupported\n", - __FUNCTION__, __LINE__); - } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); - } - return ret_val; -} - -/* vim: set ts=4 tw=78: */ diff --git a/common/xilinx.c b/common/xilinx.c deleted file mode 100644 index 7b5e8c5..0000000 --- a/common/xilinx.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * (C) Copyright 2002 - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * Keith Outwater, keith_outwater@mvis.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -/* - * Xilinx FPGA support - */ - -#include -#include -#include -#include - -#if 0 -#define FPGA_DEBUG -#endif - -/* Define FPGA_DEBUG to get debug printf's */ -#ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -/* Local Static Functions */ -static int xilinx_validate (Xilinx_desc * desc, char *fn); - -/* ------------------------------------------------------------------------- */ - -int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else - switch (desc->family) { - case Xilinx_Spartan2: -#if defined(CONFIG_FPGA_SPARTAN2) - PRINTF ("%s: Launching the Spartan-II Loader...\n", - __FUNCTION__); - ret_val = Spartan2_load (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if defined(CONFIG_FPGA_SPARTAN3) - PRINTF ("%s: Launching the Spartan-III Loader...\n", - __FUNCTION__); - ret_val = Spartan3_load (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if defined(CONFIG_FPGA_VIRTEX2) - PRINTF ("%s: Launching the Virtex-II Loader...\n", - __FUNCTION__); - ret_val = Virtex2_load (desc, buf, bsize); -#else - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - - return ret_val; -} - -int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else - switch (desc->family) { - case Xilinx_Spartan2: -#if defined(CONFIG_FPGA_SPARTAN2) - PRINTF ("%s: Launching the Spartan-II Reader...\n", - __FUNCTION__); - ret_val = Spartan2_dump (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if defined(CONFIG_FPGA_SPARTAN3) - PRINTF ("%s: Launching the Spartan-III Reader...\n", - __FUNCTION__); - ret_val = Spartan3_dump (desc, buf, bsize); -#else - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if defined( CONFIG_FPGA_VIRTEX2) - PRINTF ("%s: Launching the Virtex-II Reader...\n", - __FUNCTION__); - ret_val = Virtex2_dump (desc, buf, bsize); -#else - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - - return ret_val; -} - -int xilinx_info (Xilinx_desc * desc) -{ - int ret_val = FPGA_FAIL; - - if (xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("Family: \t"); - switch (desc->family) { - case Xilinx_Spartan2: - printf ("Spartan-II\n"); - break; - case Xilinx_Spartan3: - printf ("Spartan-III\n"); - break; - case Xilinx_Virtex2: - printf ("Virtex-II\n"); - break; - /* Add new family types here */ - default: - printf ("Unknown family type, %d\n", desc->family); - } - - printf ("Interface type:\t"); - switch (desc->iface) { - case slave_serial: - printf ("Slave Serial\n"); - break; - case master_serial: /* Not used */ - printf ("Master Serial\n"); - break; - case slave_parallel: - printf ("Slave Parallel\n"); - break; - case jtag_mode: /* Not used */ - printf ("JTAG Mode\n"); - break; - case slave_selectmap: - printf ("Slave SelectMap Mode\n"); - break; - case master_selectmap: - printf ("Master SelectMap Mode\n"); - break; - /* Add new interface types here */ - default: - printf ("Unsupported interface type, %d\n", desc->iface); - } - - printf ("Device Size: \t%d bytes\n" - "Cookie: \t0x%x (%d)\n", - desc->size, desc->cookie, desc->cookie); - - if (desc->iface_fns) { - printf ("Device Function Table @ 0x%p\n", desc->iface_fns); - switch (desc->family) { - case Xilinx_Spartan2: -#if defined(CONFIG_FPGA_SPARTAN2) - Spartan2_info (desc); -#else - /* just in case */ - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if defined(CONFIG_FPGA_SPARTAN3) - Spartan3_info (desc); -#else - /* just in case */ - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if defined(CONFIG_FPGA_VIRTEX2) - Virtex2_info (desc); -#else - /* just in case */ - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - /* we don't need a message here - we give one up above */ - ; - } - } else - printf ("No Device Function Table.\n"); - - ret_val = FPGA_SUCCESS; - } else { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } - - return ret_val; -} - -int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset) -{ - int ret_val = FPGA_FAIL; /* assume a failure */ - - if (!xilinx_validate (desc, (char *)__FUNCTION__)) { - printf ("%s: Invalid device descriptor\n", __FUNCTION__); - } else - switch (desc->family) { - case Xilinx_Spartan2: -#if defined(CONFIG_FPGA_SPARTAN2) - ret_val = Spartan2_reloc (desc, reloc_offset); -#else - printf ("%s: No support for Spartan-II devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Spartan3: -#if defined(CONFIG_FPGA_SPARTAN3) - ret_val = Spartan3_reloc (desc, reloc_offset); -#else - printf ("%s: No support for Spartan-III devices.\n", - __FUNCTION__); -#endif - break; - case Xilinx_Virtex2: -#if defined(CONFIG_FPGA_VIRTEX2) - ret_val = Virtex2_reloc (desc, reloc_offset); -#else - printf ("%s: No support for Virtex-II devices.\n", - __FUNCTION__); -#endif - break; - /* Add new family types here */ - default: - printf ("%s: Unsupported family type, %d\n", - __FUNCTION__, desc->family); - } - - return ret_val; -} - - -/* ------------------------------------------------------------------------- */ - -static int xilinx_validate (Xilinx_desc * desc, char *fn) -{ - int ret_val = FALSE; - - if (desc) { - if ((desc->family > min_xilinx_type) && - (desc->family < max_xilinx_type)) { - if ((desc->iface > min_xilinx_iface_type) && - (desc->iface < max_xilinx_iface_type)) { - if (desc->size) { - ret_val = TRUE; - } else - printf ("%s: NULL part size\n", fn); - } else - printf ("%s: Invalid Interface type, %d\n", - fn, desc->iface); - } else - printf ("%s: Invalid family type, %d\n", fn, desc->family); - } else - printf ("%s: NULL descriptor!\n", fn); - - return ret_val; -} diff --git a/drivers/fpga/ACEX1K.c b/drivers/fpga/ACEX1K.c new file mode 100644 index 0000000..3f79677 --- /dev/null +++ b/drivers/fpga/ACEX1K.c @@ -0,0 +1,362 @@ +/* + * (C) Copyright 2003 + * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de + * + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include /* core U-Boot definitions */ +#include /* ACEX device family */ + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Note: The assumption is that we cannot possibly run fast enough to + * overrun the device (the Slave Parallel mode can free run at 50MHz). + * If there is a need to operate slower, define CONFIG_FPGA_DELAY in + * the board config file to slow things down. + */ +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CONFIG_SYS_FPGA_WAIT +#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */ +#endif + +static int ACEX1K_ps_load( Altera_desc *desc, void *buf, size_t bsize ); +static int ACEX1K_ps_dump( Altera_desc *desc, void *buf, size_t bsize ); +/* static int ACEX1K_ps_info( Altera_desc *desc ); */ +static int ACEX1K_ps_reloc( Altera_desc *desc, ulong reloc_offset ); + +/* ------------------------------------------------------------------------- */ +/* ACEX1K Generic Implementation */ +int ACEX1K_load (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case passive_serial: + PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); + ret_val = ACEX1K_ps_load (desc, buf, bsize); + break; + + /* Add new interface types here */ + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int ACEX1K_dump (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case passive_serial: + PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); + ret_val = ACEX1K_ps_dump (desc, buf, bsize); + break; + + /* Add new interface types here */ + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int ACEX1K_info( Altera_desc *desc ) +{ + return FPGA_SUCCESS; +} + + +int ACEX1K_reloc (Altera_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (desc->family != Altera_ACEX1K) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case passive_serial: + ret_val = ACEX1K_ps_reloc (desc, reloc_offset); + break; + + /* Add new interface types here */ + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ +/* ACEX1K Passive Serial Generic Implementation */ + +static int ACEX1K_ps_load (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns; + int i; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "config:\t0x%p\n" + "status:\t0x%p\n" + "clk:\t0x%p\n" + "data:\t0x%p\n" + "done:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->config, fn->status, + fn->clk, fn->data, fn->done); +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...", cookie); +#endif + + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */ + + udelay(2); /* T_cfg > 2us */ + + /* nSTATUS should be asserted now */ + (*fn->done) (cookie); + if ( !(*fn->status) (cookie) ) { + puts ("** nSTATUS is not asserted.\n"); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + + (*fn->config) (FALSE, TRUE, cookie); /* Deassert nCONFIG */ + udelay(2); /* T_cf2st1 < 4us */ + + /* Wait for nSTATUS to be released (i.e. deasserted) */ + ts = get_timer (0); /* get current time */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for STATUS to go high.\n"); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + (*fn->done) (cookie); + } while ((*fn->status) (cookie)); + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + + /* Load the data */ + while (bytecount < bsize) { + unsigned char val=0; +#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC + if (ctrlc ()) { + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + /* Altera detects an error if INIT goes low (active) + while DONE is low (inactive) */ +#if 0 /* not yet implemented */ + if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { + puts ("** CRC error during FPGA load.\n"); + (*fn->abort) (cookie); + return (FPGA_FAIL); + } +#endif + val = data [bytecount ++ ]; + i = 8; + do { + /* Deassert the clock */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Write data */ + (*fn->data) ( (val & 0x01), TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Assert the clock */ + (*fn->clk) (TRUE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + val >>= 1; + i --; + } while (i > 0); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc (' '); /* terminate the dotted line */ +#endif + + /* + * Checking FPGA's CONF_DONE signal - correctly booted ? + */ + + if ( ! (*fn->done) (cookie) ) { + puts ("** Booting failed! CONF_DONE is still deasserted.\n"); + (*fn->abort) (cookie); + return (FPGA_FAIL); + } + + /* + * "DCLK must be clocked an additional 10 times fpr ACEX 1K..." + */ + + for (i = 0; i < 12; i++) { + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + } + + ret_val = FPGA_SUCCESS; + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (ret_val == FPGA_SUCCESS) { + puts ("Done.\n"); + } + else { + puts ("Fail.\n"); + } +#endif + (*fn->post) (cookie); + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int ACEX1K_ps_dump (Altera_desc * desc, void *buf, size_t bsize) +{ + /* Readback is only available through the Slave Parallel and */ + /* boundary-scan interfaces. */ + printf ("%s: Passive Serial Dumping is unavailable\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int ACEX1K_ps_reloc (Altera_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Altera_ACEX1K_Passive_Serial_fns *fn_r, *fn = + (Altera_ACEX1K_Passive_Serial_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Altera_ACEX1K_Passive_Serial_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Altera_ACEX1K_Passive_Serial_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Altera_pre_fn) addr; + + addr = (ulong) (fn->config) + reloc_offset; + fn_r->config = (Altera_config_fn) addr; + + addr = (ulong) (fn->status) + reloc_offset; + fn_r->status = (Altera_status_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Altera_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Altera_clk_fn) addr; + + addr = (ulong) (fn->data) + reloc_offset; + fn_r->data = (Altera_data_fn) addr; + + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Altera_abort_fn) addr; + + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Altera_post_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile new file mode 100644 index 0000000..52d8e24 --- /dev/null +++ b/drivers/fpga/Makefile @@ -0,0 +1,58 @@ +# +# (C) Copyright 2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libfpga.a + +ifdef CONFIG_FPGA +COBJS-y += fpga.o +COBJS-$(CONFIG_FPGA_SPARTAN2) += spartan2.o +COBJS-$(CONFIG_FPGA_SPARTAN3) += spartan3.o +COBJS-$(CONFIG_FPGA_VIRTEX2) += virtex2.o +COBJS-$(CONFIG_FPGA_XILINX) += xilinx.o +ifdef CONFIG_FPGA_ALTERA +COBJS-y += altera.o +COBJS-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o +COBJS-$(CONFIG_FPGA_CYCLON2) += cyclon2.o +COBJS-$(CONFIG_FPGA_STRATIX_II) += stratixII.o +endif +endif + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c new file mode 100644 index 0000000..09dc0b2 --- /dev/null +++ b/drivers/fpga/altera.c @@ -0,0 +1,283 @@ +/* + * (C) Copyright 2003 + * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de + * + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Altera FPGA support + */ +#include +#include +#include + +/* Define FPGA_DEBUG to get debug printf's */ +/* #define FPGA_DEBUG */ + +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Local Static Functions */ +static int altera_validate (Altera_desc * desc, const char *fn); + +/* ------------------------------------------------------------------------- */ +int altera_load( Altera_desc *desc, void *buf, size_t bsize ) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!altera_validate (desc, (char *)__FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else { + switch (desc->family) { + case Altera_ACEX1K: + case Altera_CYC2: +#if defined(CONFIG_FPGA_ACEX1K) + PRINTF ("%s: Launching the ACEX1K Loader...\n", + __FUNCTION__); + ret_val = ACEX1K_load (desc, buf, bsize); +#elif defined(CONFIG_FPGA_CYCLON2) + PRINTF ("%s: Launching the CYCLON II Loader...\n", + __FUNCTION__); + ret_val = CYC2_load (desc, buf, bsize); +#else + printf ("%s: No support for ACEX1K devices.\n", + __FUNCTION__); +#endif + break; + +#if defined(CONFIG_FPGA_STRATIX_II) + case Altera_StratixII: + PRINTF ("%s: Launching the Stratix II Loader...\n", + __FUNCTION__); + ret_val = StratixII_load (desc, buf, bsize); + break; +#endif + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + } + + return ret_val; +} + +int altera_dump( Altera_desc *desc, void *buf, size_t bsize ) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!altera_validate (desc, (char *)__FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else { + switch (desc->family) { + case Altera_ACEX1K: +#if defined(CONFIG_FPGA_ACEX) + PRINTF ("%s: Launching the ACEX1K Reader...\n", + __FUNCTION__); + ret_val = ACEX1K_dump (desc, buf, bsize); +#else + printf ("%s: No support for ACEX1K devices.\n", + __FUNCTION__); +#endif + break; + +#if defined(CONFIG_FPGA_STRATIX_II) + case Altera_StratixII: + PRINTF ("%s: Launching the Stratix II Reader...\n", + __FUNCTION__); + ret_val = StratixII_dump (desc, buf, bsize); + break; +#endif + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + } + + return ret_val; +} + +int altera_info( Altera_desc *desc ) +{ + int ret_val = FPGA_FAIL; + + if (altera_validate (desc, (char *)__FUNCTION__)) { + printf ("Family: \t"); + switch (desc->family) { + case Altera_ACEX1K: + printf ("ACEX1K\n"); + break; + case Altera_CYC2: + printf ("CYCLON II\n"); + break; + case Altera_StratixII: + printf ("Stratix II\n"); + break; + /* Add new family types here */ + default: + printf ("Unknown family type, %d\n", desc->family); + } + + printf ("Interface type:\t"); + switch (desc->iface) { + case passive_serial: + printf ("Passive Serial (PS)\n"); + break; + case passive_parallel_synchronous: + printf ("Passive Parallel Synchronous (PPS)\n"); + break; + case passive_parallel_asynchronous: + printf ("Passive Parallel Asynchronous (PPA)\n"); + break; + case passive_serial_asynchronous: + printf ("Passive Serial Asynchronous (PSA)\n"); + break; + case altera_jtag_mode: /* Not used */ + printf ("JTAG Mode\n"); + break; + case fast_passive_parallel: + printf ("Fast Passive Parallel (FPP)\n"); + break; + case fast_passive_parallel_security: + printf + ("Fast Passive Parallel with Security (FPPS) \n"); + break; + /* Add new interface types here */ + default: + printf ("Unsupported interface type, %d\n", desc->iface); + } + + printf ("Device Size: \t%d bytes\n" + "Cookie: \t0x%x (%d)\n", + desc->size, desc->cookie, desc->cookie); + + if (desc->iface_fns) { + printf ("Device Function Table @ 0x%p\n", desc->iface_fns); + switch (desc->family) { + case Altera_ACEX1K: + case Altera_CYC2: +#if defined(CONFIG_FPGA_ACEX1K) + ACEX1K_info (desc); +#elif defined(CONFIG_FPGA_CYCLON2) + CYC2_info (desc); +#else + /* just in case */ + printf ("%s: No support for ACEX1K devices.\n", + __FUNCTION__); +#endif + break; +#if defined(CONFIG_FPGA_STRATIX_II) + case Altera_StratixII: + StratixII_info (desc); + break; +#endif + /* Add new family types here */ + default: + /* we don't need a message here - we give one up above */ + break; + } + } else { + printf ("No Device Function Table.\n"); + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } + + return ret_val; +} + +int altera_reloc( Altera_desc *desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!altera_validate (desc, (char *)__FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else { + switch (desc->family) { + case Altera_ACEX1K: +#if defined(CONFIG_FPGA_ACEX1K) + ret_val = ACEX1K_reloc (desc, reloc_offset); +#else + printf ("%s: No support for ACEX devices.\n", + __FUNCTION__); +#endif + break; +#if defined(CONFIG_FPGA_STRATIX_II) + case Altera_StratixII: + ret_val = StratixII_reloc (desc, reloc_offset); + break; +#endif + case Altera_CYC2: +#if defined(CONFIG_FPGA_CYCLON2) + ret_val = CYC2_reloc (desc, reloc_offset); +#else + printf ("%s: No support for CYCLON II devices.\n", + __FUNCTION__); +#endif + break; + /* Add new family types here */ + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + } + + return ret_val; +} + +/* ------------------------------------------------------------------------- */ + +static int altera_validate (Altera_desc * desc, const char *fn) +{ + int ret_val = FALSE; + + if (desc) { + if ((desc->family > min_altera_type) && + (desc->family < max_altera_type)) { + if ((desc->iface > min_altera_iface_type) && + (desc->iface < max_altera_iface_type)) { + if (desc->size) { + ret_val = TRUE; + } else { + printf ("%s: NULL part size\n", fn); + } + } else { + printf ("%s: Invalid Interface type, %d\n", + fn, desc->iface); + } + } else { + printf ("%s: Invalid family type, %d\n", fn, desc->family); + } + } else { + printf ("%s: NULL descriptor!\n", fn); + } + + return ret_val; +} + +/* ------------------------------------------------------------------------- */ diff --git a/drivers/fpga/cyclon2.c b/drivers/fpga/cyclon2.c new file mode 100644 index 0000000..3ed64b2 --- /dev/null +++ b/drivers/fpga/cyclon2.c @@ -0,0 +1,301 @@ +/* + * (C) Copyright 2006 + * Heiko Schocher, hs@denx.de + * Based on ACE1XK.c + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include /* core U-Boot definitions */ +#include +#include /* ACEX device family */ + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Note: The assumption is that we cannot possibly run fast enough to + * overrun the device (the Slave Parallel mode can free run at 50MHz). + * If there is a need to operate slower, define CONFIG_FPGA_DELAY in + * the board config file to slow things down. + */ +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CONFIG_SYS_FPGA_WAIT +#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */ +#endif + +static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize ); +static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize ); +/* static int CYC2_ps_info( Altera_desc *desc ); */ +static int CYC2_ps_reloc( Altera_desc *desc, ulong reloc_offset ); + +/* ------------------------------------------------------------------------- */ +/* CYCLON2 Generic Implementation */ +int CYC2_load (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case passive_serial: + PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); + ret_val = CYC2_ps_load (desc, buf, bsize); + break; + + /* Add new interface types here */ + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case passive_serial: + PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); + ret_val = CYC2_ps_dump (desc, buf, bsize); + break; + + /* Add new interface types here */ + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int CYC2_info( Altera_desc *desc ) +{ + return FPGA_SUCCESS; +} + +int CYC2_reloc (Altera_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (desc->family != Altera_CYC2) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case passive_serial: + ret_val = CYC2_ps_reloc (desc, reloc_offset); + break; + + /* Add new interface types here */ + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +/* ------------------------------------------------------------------------- */ +/* CYCLON2 Passive Serial Generic Implementation */ +static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns; + int ret = 0; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "config:\t0x%p\n" + "status:\t0x%p\n" + "write:\t0x%p\n" + "done:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->config, fn->status, + fn->write, fn->done); +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...", cookie); +#endif + + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->config) (TRUE, TRUE, cookie); /* Assert nCONFIG */ + + udelay(2); /* T_cfg > 2us */ + + /* Wait for nSTATUS to be asserted */ + ts = get_timer (0); /* get current time */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for STATUS to go high.\n"); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } while (!(*fn->status) (cookie)); + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + + ret = (*fn->write) (buf, bsize, TRUE, cookie); + if (ret) { + puts ("** Write failed.\n"); + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + puts(" OK? ..."); +#endif + + CONFIG_FPGA_DELAY (); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc (' '); /* terminate the dotted line */ +#endif + + /* + * Checking FPGA's CONF_DONE signal - correctly booted ? + */ + + if ( ! (*fn->done) (cookie) ) { + puts ("** Booting failed! CONF_DONE is still deasserted.\n"); + (*fn->abort) (cookie); + return (FPGA_FAIL); + } +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + puts(" OK\n"); +#endif + + ret_val = FPGA_SUCCESS; + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (ret_val == FPGA_SUCCESS) { + puts ("Done.\n"); + } + else { + puts ("Fail.\n"); + } +#endif + (*fn->post) (cookie); + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize) +{ + /* Readback is only available through the Slave Parallel and */ + /* boundary-scan interfaces. */ + printf ("%s: Passive Serial Dumping is unavailable\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int CYC2_ps_reloc (Altera_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Altera_CYC2_Passive_Serial_fns *fn_r, *fn = + (Altera_CYC2_Passive_Serial_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Altera_CYC2_Passive_Serial_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Altera_CYC2_Passive_Serial_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Altera_pre_fn) addr; + + addr = (ulong) (fn->config) + reloc_offset; + fn_r->config = (Altera_config_fn) addr; + + addr = (ulong) (fn->status) + reloc_offset; + fn_r->status = (Altera_status_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Altera_done_fn) addr; + + addr = (ulong) (fn->write) + reloc_offset; + fn_r->write = (Altera_write_fn) addr; + + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Altera_abort_fn) addr; + + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Altera_post_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c new file mode 100644 index 0000000..67a6c30 --- /dev/null +++ b/drivers/fpga/fpga.c @@ -0,0 +1,335 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Generic FPGA support + */ +#include /* core U-Boot definitions */ +#include /* xilinx specific definitions */ +#include /* altera specific definitions */ + +#if 0 +#define FPGA_DEBUG /* define FPGA_DEBUG to get debug messages */ +#endif + +/* Local definitions */ +#ifndef CONFIG_MAX_FPGA_DEVICES +#define CONFIG_MAX_FPGA_DEVICES 5 +#endif + +/* Enable/Disable debug console messages */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Local static data */ +static ulong relocation_offset = 0; +static int next_desc = FPGA_INVALID_DEVICE; +static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES]; + +/* Local static functions */ +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ); +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, + size_t bsize, char *fn ); +static int fpga_dev_info( int devnum ); + + +/* ------------------------------------------------------------------------- */ + +/* fpga_no_sup + * 'no support' message function + */ +static void fpga_no_sup( char *fn, char *msg ) +{ + if ( fn && msg ) { + printf( "%s: No support for %s.\n", fn, msg); + } else if ( msg ) { + printf( "No support for %s.\n", msg); + } else { + printf( "No FPGA suport!\n"); + } +} + + +/* fpga_get_desc + * map a device number to a descriptor + */ +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ) +{ + fpga_desc *desc = (fpga_desc * )NULL; + + if (( devnum >= 0 ) && (devnum < next_desc )) { + desc = &desc_table[devnum]; + PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n", + __FUNCTION__, devnum, desc ); + } + + return desc; +} + + +/* fpga_validate + * generic parameter checking code + */ +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, + size_t bsize, char *fn ) +{ + fpga_desc * desc = fpga_get_desc( devnum ); + + if ( !desc ) { + printf( "%s: Invalid device number %d\n", fn, devnum ); + } + + if ( !buf ) { + printf( "%s: Null buffer.\n", fn ); + return (fpga_desc * const)NULL; + } + return desc; +} + + +/* fpga_dev_info + * generic multiplexing code + */ +static int fpga_dev_info( int devnum ) +{ + int ret_val = FPGA_FAIL; /* assume failure */ + const fpga_desc * const desc = fpga_get_desc( devnum ); + + if ( desc ) { + PRINTF( "%s: Device Descriptor @ 0x%p\n", + __FUNCTION__, desc->devdesc ); + + switch ( desc->devtype ) { + case fpga_xilinx: +#if defined(CONFIG_FPGA_XILINX) + printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc ); + ret_val = xilinx_info( desc->devdesc ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if defined(CONFIG_FPGA_ALTERA) + printf( "Altera Device\nDescriptor @ 0x%p\n", desc ); + ret_val = altera_info( desc->devdesc ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, desc->devtype ); + } + } else { + printf( "%s: Invalid device number %d\n", + __FUNCTION__, devnum ); + } + + return ret_val; +} + + +/* fpga_reloc + * generic multiplexing code + */ +int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off ) +{ + int ret_val = FPGA_FAIL; + + PRINTF( "%s: Relocating Device of type %d @ 0x%p with offset %lx\n", + __FUNCTION__, devtype, desc, reloc_off ); + + switch ( devtype ) { + case fpga_xilinx: +#if defined(CONFIG_FPGA_XILINX) + ret_val = xilinx_reloc( desc, reloc_off ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if defined(CONFIG_FPGA_ALTERA) + ret_val = altera_reloc( desc, reloc_off ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, devtype ); + } + + return ret_val; +} + +/* ------------------------------------------------------------------------- */ +/* fgpa_init is usually called from misc_init_r() and MUST be called + * before any of the other fpga functions are used. + */ +void fpga_init( ulong reloc_off ) +{ + relocation_offset = reloc_off; + next_desc = 0; + memset( desc_table, 0, sizeof(desc_table)); + + PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA ); +} + +/* fpga_count + * Basic interface function to get the current number of devices available. + */ +int fpga_count( void ) +{ + return next_desc; +} + +/* fpga_add + * Attempts to relocate the device/board specific interface code + * to the proper RAM locations and adds the device descriptor to + * the device table. + */ +int fpga_add( fpga_type devtype, void *desc ) +{ + int devnum = FPGA_INVALID_DEVICE; + + if ( next_desc < 0 ) { + printf( "%s: FPGA support not initialized!\n", __FUNCTION__ ); + } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) { + if ( desc ) { + if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) { + if ( fpga_reloc( devtype, desc, relocation_offset ) + == FPGA_SUCCESS ) { + devnum = next_desc; + desc_table[next_desc].devtype = devtype; + desc_table[next_desc++].devdesc = desc; + } else { + printf( "%s: Unable to relocate device interface table!\n", + __FUNCTION__ ); + } + } else { + printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ ); + } + } else { + printf( "%s: NULL device descriptor\n", __FUNCTION__ ); + } + } else { + printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype ); + } + + return devnum; +} + +/* + * Generic multiplexing code + */ +int fpga_load( int devnum, void *buf, size_t bsize ) +{ + int ret_val = FPGA_FAIL; /* assume failure */ + fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); + + if ( desc ) { + switch ( desc->devtype ) { + case fpga_xilinx: +#if defined(CONFIG_FPGA_XILINX) + ret_val = xilinx_load( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if defined(CONFIG_FPGA_ALTERA) + ret_val = altera_load( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, desc->devtype ); + } + } + + return ret_val; +} + +/* fpga_dump + * generic multiplexing code + */ +int fpga_dump( int devnum, void *buf, size_t bsize ) +{ + int ret_val = FPGA_FAIL; /* assume failure */ + fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); + + if ( desc ) { + switch ( desc->devtype ) { + case fpga_xilinx: +#if defined(CONFIG_FPGA_XILINX) + ret_val = xilinx_dump( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if defined(CONFIG_FPGA_ALTERA) + ret_val = altera_dump( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, desc->devtype ); + } + } + + return ret_val; +} + + +/* fpga_info + * front end to fpga_dev_info. If devnum is invalid, report on all + * available devices. + */ +int fpga_info( int devnum ) +{ + if ( devnum == FPGA_INVALID_DEVICE ) { + if ( next_desc > 0 ) { + int dev; + + for ( dev = 0; dev < next_desc; dev++ ) { + fpga_dev_info( dev ); + } + return FPGA_SUCCESS; + } else { + printf( "%s: No FPGA devices available.\n", __FUNCTION__ ); + return FPGA_FAIL; + } + } + else return fpga_dev_info( devnum ); +} + +/* ------------------------------------------------------------------------- */ diff --git a/drivers/fpga/spartan2.c b/drivers/fpga/spartan2.c new file mode 100644 index 0000000..f5ba7fc --- /dev/null +++ b/drivers/fpga/spartan2.c @@ -0,0 +1,663 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include /* core U-Boot definitions */ +#include /* Spartan-II device family */ + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#undef CONFIG_SYS_FPGA_CHECK_BUSY +#undef CONFIG_SYS_FPGA_PROG_FEEDBACK + +/* Note: The assumption is that we cannot possibly run fast enough to + * overrun the device (the Slave Parallel mode can free run at 50MHz). + * If there is a need to operate slower, define CONFIG_FPGA_DELAY in + * the board config file to slow things down. + */ +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CONFIG_SYS_FPGA_WAIT +#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ +#endif + +static int Spartan2_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan2_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan2_sp_info( Xilinx_desc *desc ); */ +static int Spartan2_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +static int Spartan2_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan2_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan2_ss_info( Xilinx_desc *desc ); */ +static int Spartan2_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Generic Implementation */ +int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + ret_val = Spartan2_ss_load (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + ret_val = Spartan2_sp_load (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan2_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + ret_val = Spartan2_ss_dump (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + ret_val = Spartan2_sp_dump (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan2_info( Xilinx_desc *desc ) +{ + return FPGA_SUCCESS; +} + + +int Spartan2_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (desc->family != Xilinx_Spartan2) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case slave_serial: + ret_val = Spartan2_ss_reloc (desc, reloc_offset); + break; + + case slave_parallel: + ret_val = Spartan2_sp_reloc (desc, reloc_offset); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Slave Parallel Generic Implementation */ + +static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pre: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "err:\t0x%p\n" + "clk:\t0x%p\n" + "cs:\t0x%p\n" + "wr:\t0x%p\n" + "read data:\t0x%p\n" + "write data:\t0x%p\n" + "busy:\t0x%p\n" + "abort:\t0x%p\n", + "post:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, + fn->abort, fn->post); + + /* + * This code is designed to emulate the "Express Style" + * Continuous Data Loading in Slave Parallel Mode for + * the Spartan-II Family. + */ +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT and BUSY to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + + (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* Load the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + /* XXX - Check the error bit? */ + + (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CONFIG_SYS_FPGA_CHECK_BUSY + ts = get_timer (0); /* get current time */ + while ((*fn->busy) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for BUSY to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } +#endif + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ + (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + while ((*fn->done) (cookie) == FPGA_FAIL) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + puts ("Done.\n"); +#endif + } + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + + else { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + puts ("Fail.\n"); +#endif + } + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; + + if (fn) { + unsigned char *data = (unsigned char *) buf; + size_t bytecount = 0; + int cookie = desc->cookie; /* make a local copy */ + + printf ("Starting Dump of FPGA Device %d...\n", cookie); + + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* dump the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + puts ("Done.\n"); + + /* XXX - checksum the data? */ + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + + +static int Spartan2_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Parallel_fns *fn_r, *fn = + (Xilinx_Spartan2_Slave_Parallel_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan2_Slave_Parallel_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan2_Slave_Parallel_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->err) + reloc_offset; + fn_r->err = (Xilinx_err_fn) addr; + + addr = (ulong) (fn->cs) + reloc_offset; + fn_r->cs = (Xilinx_cs_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + addr = (ulong) (fn->rdata) + reloc_offset; + fn_r->rdata = (Xilinx_rdata_fn) addr; + + addr = (ulong) (fn->wdata) + reloc_offset; + fn_r->wdata = (Xilinx_wdata_fn) addr; + + addr = (ulong) (fn->busy) + reloc_offset; + fn_r->busy = (Xilinx_busy_fn) addr; + + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Xilinx_abort_fn) addr; + + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} + +/* ------------------------------------------------------------------------- */ + +static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Serial_fns *fn = desc->iface_fns; + int i; + unsigned char val; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "clk:\t0x%p\n" + "wr:\t0x%p\n" + "done:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pgm, fn->init, + fn->clk, fn->wr, fn->done); +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Wait for INIT state (init low) */ + ts = get_timer (0); /* get current time */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to start.\n"); + return FPGA_FAIL; + } + } while (!(*fn->init) (cookie)); + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + return FPGA_FAIL; + } + } while ((*fn->init) (cookie)); + + /* Load the data */ + while (bytecount < bsize) { + + /* Xilinx detects an error if INIT goes low (active) + while DONE is low (inactive) */ + if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { + puts ("** CRC error during FPGA load.\n"); + return (FPGA_FAIL); + } + val = data [bytecount ++]; + i = 8; + do { + /* Deassert the clock */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Write data */ + (*fn->wr) ((val & 0x80), TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Assert the clock */ + (*fn->clk) (TRUE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + val <<= 1; + i --; + } while (i > 0); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + (*fn->wr) (TRUE, TRUE, cookie); + + while (! (*fn->done) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + putc ('*'); + + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + ret_val = FPGA_FAIL; + break; + } + } + putc ('\n'); /* terminate the dotted line */ + + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (ret_val == FPGA_SUCCESS) { + puts ("Done.\n"); + } + else { + puts ("Fail.\n"); + } +#endif + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + /* Readback is only available through the Slave Parallel and */ + /* boundary-scan interfaces. */ + printf ("%s: Slave Serial Dumping is unavailable\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int Spartan2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Serial_fns *fn_r, *fn = + (Xilinx_Spartan2_Slave_Serial_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan2_Slave_Serial_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan2_Slave_Serial_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + if (fn->pre) { + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + } + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + if (fn->post) { + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + } + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c new file mode 100644 index 0000000..9ce41f1 --- /dev/null +++ b/drivers/fpga/spartan3.c @@ -0,0 +1,668 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Configuration support for Xilinx Spartan3 devices. Based + * on spartan2.c (Rich Ireland, rireland@enterasys.com). + */ + +#include /* core U-Boot definitions */ +#include /* Spartan-II device family */ + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#undef CONFIG_SYS_FPGA_CHECK_BUSY +#undef CONFIG_SYS_FPGA_PROG_FEEDBACK + +/* Note: The assumption is that we cannot possibly run fast enough to + * overrun the device (the Slave Parallel mode can free run at 50MHz). + * If there is a need to operate slower, define CONFIG_FPGA_DELAY in + * the board config file to slow things down. + */ +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CONFIG_SYS_FPGA_WAIT +#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ +#endif + +static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan3_sp_info( Xilinx_desc *desc ); */ +static int Spartan3_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan3_ss_info( Xilinx_desc *desc ); */ +static int Spartan3_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Generic Implementation */ +int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + ret_val = Spartan3_ss_load (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + ret_val = Spartan3_sp_load (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + ret_val = Spartan3_ss_dump (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + ret_val = Spartan3_sp_dump (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan3_info( Xilinx_desc *desc ) +{ + return FPGA_SUCCESS; +} + + +int Spartan3_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (desc->family != Xilinx_Spartan3) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case slave_serial: + ret_val = Spartan3_ss_reloc (desc, reloc_offset); + break; + + case slave_parallel: + ret_val = Spartan3_sp_reloc (desc, reloc_offset); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Slave Parallel Generic Implementation */ + +static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pre: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "err:\t0x%p\n" + "clk:\t0x%p\n" + "cs:\t0x%p\n" + "wr:\t0x%p\n" + "read data:\t0x%p\n" + "write data:\t0x%p\n" + "busy:\t0x%p\n" + "abort:\t0x%p\n", + "post:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, + fn->abort, fn->post); + + /* + * This code is designed to emulate the "Express Style" + * Continuous Data Loading in Slave Parallel Mode for + * the Spartan-II Family. + */ +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT and BUSY to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + + (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* Load the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + /* XXX - Check the error bit? */ + + (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CONFIG_SYS_FPGA_CHECK_BUSY + ts = get_timer (0); /* get current time */ + while ((*fn->busy) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for BUSY to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } +#endif + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ + (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + while ((*fn->done) (cookie) == FPGA_FAIL) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + puts ("Done.\n"); +#endif + } + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + + else { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + puts ("Fail.\n"); +#endif + } + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; + + if (fn) { + unsigned char *data = (unsigned char *) buf; + size_t bytecount = 0; + int cookie = desc->cookie; /* make a local copy */ + + printf ("Starting Dump of FPGA Device %d...\n", cookie); + + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* dump the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + puts ("Done.\n"); + + /* XXX - checksum the data? */ + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + + +static int Spartan3_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Parallel_fns *fn_r, *fn = + (Xilinx_Spartan3_Slave_Parallel_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan3_Slave_Parallel_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan3_Slave_Parallel_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->err) + reloc_offset; + fn_r->err = (Xilinx_err_fn) addr; + + addr = (ulong) (fn->cs) + reloc_offset; + fn_r->cs = (Xilinx_cs_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + addr = (ulong) (fn->rdata) + reloc_offset; + fn_r->rdata = (Xilinx_rdata_fn) addr; + + addr = (ulong) (fn->wdata) + reloc_offset; + fn_r->wdata = (Xilinx_wdata_fn) addr; + + addr = (ulong) (fn->busy) + reloc_offset; + fn_r->busy = (Xilinx_busy_fn) addr; + + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Xilinx_abort_fn) addr; + + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} + +/* ------------------------------------------------------------------------- */ + +static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns; + int i; + unsigned char val; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "clk:\t0x%p\n" + "wr:\t0x%p\n" + "done:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pgm, fn->init, + fn->clk, fn->wr, fn->done); +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Wait for INIT state (init low) */ + ts = get_timer (0); /* get current time */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to start.\n"); + return FPGA_FAIL; + } + } while (!(*fn->init) (cookie)); + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + return FPGA_FAIL; + } + } while ((*fn->init) (cookie)); + + /* Load the data */ + while (bytecount < bsize) { + + /* Xilinx detects an error if INIT goes low (active) + while DONE is low (inactive) */ + if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { + puts ("** CRC error during FPGA load.\n"); + return (FPGA_FAIL); + } + val = data [bytecount ++]; + i = 8; + do { + /* Deassert the clock */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Write data */ + (*fn->wr) ((val & 0x80), TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Assert the clock */ + (*fn->clk) (TRUE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + val <<= 1; + i --; + } while (i > 0); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + (*fn->wr) (TRUE, TRUE, cookie); + + while (! (*fn->done) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + putc ('*'); + + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + ret_val = FPGA_FAIL; + break; + } + } + putc ('\n'); /* terminate the dotted line */ + + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (ret_val == FPGA_SUCCESS) { + puts ("Done.\n"); + } + else { + puts ("Fail.\n"); + } +#endif + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + /* Readback is only available through the Slave Parallel and */ + /* boundary-scan interfaces. */ + printf ("%s: Slave Serial Dumping is unavailable\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int Spartan3_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Serial_fns *fn_r, *fn = + (Xilinx_Spartan3_Slave_Serial_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan3_Slave_Serial_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan3_Slave_Serial_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + if (fn->pre) { + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + } + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + if (fn->post) { + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + } + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} diff --git a/drivers/fpga/stratixII.c b/drivers/fpga/stratixII.c new file mode 100644 index 0000000..7556dbf --- /dev/null +++ b/drivers/fpga/stratixII.c @@ -0,0 +1,231 @@ +/* + * (C) Copyright 2007 + * Eran Liberty, Extricom , eran.liberty@gmail.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include /* core U-Boot definitions */ +#include + +int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize, + int isSerial, int isSecure); +int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize); + +/****************************************************************/ +/* Stratix II Generic Implementation */ +int StratixII_load (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case passive_serial: + ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 1, 0); + break; + case fast_passive_parallel: + ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 0); + break; + case fast_passive_parallel_security: + ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 1); + break; + + /* Add new interface types here */ + default: + printf ("%s: Unsupported interface type, %d\n", __FUNCTION__, + desc->iface); + } + return ret_val; +} + +int StratixII_dump (Altera_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case passive_serial: + case fast_passive_parallel: + case fast_passive_parallel_security: + ret_val = StratixII_ps_fpp_dump (desc, buf, bsize); + break; + /* Add new interface types here */ + default: + printf ("%s: Unsupported interface type, %d\n", __FUNCTION__, + desc->iface); + } + return ret_val; +} + +int StratixII_info (Altera_desc * desc) +{ + return FPGA_SUCCESS; +} + +int StratixII_reloc (Altera_desc * desc, ulong reloc_offset) +{ + int i; + uint32_t dest = (uint32_t) desc & 0xff000000; + + /* we assume a relocated code and non relocated code has different upper 8 bits */ + if (dest != ((uint32_t) desc->iface_fns & 0xff000000)) { + desc->iface_fns = + (void *)((uint32_t) (desc->iface_fns) + reloc_offset); + } + for (i = 0; i < sizeof (altera_board_specific_func) / sizeof (void *); + i++) { + if (dest != + ((uint32_t) (((void **)(desc->iface_fns))[i]) & 0xff000000)) + { + ((void **)(desc->iface_fns))[i] = + (void + *)(((uint32_t) (((void **)(desc->iface_fns))[i])) + + reloc_offset); + } + } + return FPGA_SUCCESS; +} + +int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize) +{ + printf ("Stratix II Fast Passive Parallel dump is not implemented\n"); + return FPGA_FAIL; +} + +int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize, + int isSerial, int isSecure) +{ + altera_board_specific_func *fns; + int cookie; + int ret_val = FPGA_FAIL; + int bytecount; + char *buff = buf; + int i; + + if (!desc) { + printf ("%s(%d) Altera_desc missing\n", __FUNCTION__, __LINE__); + return FPGA_FAIL; + } + if (!buff) { + printf ("%s(%d) buffer is missing\n", __FUNCTION__, __LINE__); + return FPGA_FAIL; + } + if (!bsize) { + printf ("%s(%d) size is zero\n", __FUNCTION__, __LINE__); + return FPGA_FAIL; + } + if (!desc->iface_fns) { + printf + ("%s(%d) Altera_desc function interface table is missing\n", + __FUNCTION__, __LINE__); + return FPGA_FAIL; + } + fns = (altera_board_specific_func *) (desc->iface_fns); + cookie = desc->cookie; + + if (! + (fns->config && fns->status && fns->done && fns->data + && fns->abort)) { + printf + ("%s(%d) Missing some function in the function interface table\n", + __FUNCTION__, __LINE__); + return FPGA_FAIL; + } + + /* 1. give board specific a chance to do anything before we start */ + if (fns->pre) { + if ((ret_val = fns->pre (cookie)) < 0) { + return ret_val; + } + } + + /* from this point on we must fail gracfully by calling lower layer abort */ + + /* 2. Strat burn cycle by deasserting config for t_CFG and waiting t_CF2CK after reaserted */ + fns->config (0, 1, cookie); + udelay (5); /* nCONFIG low pulse width 2usec */ + fns->config (1, 1, cookie); + udelay (100); /* nCONFIG high to first rising edge on DCLK */ + + /* 3. Start the Data cycle with clk deasserted */ + bytecount = 0; + fns->clk (0, 1, cookie); + + printf ("loading to fpga "); + while (bytecount < bsize) { + /* 3.1 check stratix has not signaled us an error */ + if (fns->status (cookie) != 1) { + printf + ("\n%s(%d) Stratix failed (byte transfered till failure 0x%x)\n", + __FUNCTION__, __LINE__, bytecount); + fns->abort (cookie); + return FPGA_FAIL; + } + if (isSerial) { + int i; + uint8_t data = buff[bytecount++]; + for (i = 0; i < 8; i++) { + /* 3.2(ps) put data on the bus */ + fns->data ((data >> i) & 1, 1, cookie); + + /* 3.3(ps) clock once */ + fns->clk (1, 1, cookie); + fns->clk (0, 1, cookie); + } + } else { + /* 3.2(fpp) put data on the bus */ + fns->data (buff[bytecount++], 1, cookie); + + /* 3.3(fpp) clock once */ + fns->clk (1, 1, cookie); + fns->clk (0, 1, cookie); + + /* 3.4(fpp) for secure cycle push 3 more clocks */ + for (i = 0; isSecure && i < 3; i++) { + fns->clk (1, 1, cookie); + fns->clk (0, 1, cookie); + } + } + + /* 3.5 while clk is deasserted it is safe to print some progress indication */ + if ((bytecount % (bsize / 100)) == 0) { + printf ("\b\b\b%02d\%", bytecount * 100 / bsize); + } + } + + /* 4. Set one last clock and check conf done signal */ + fns->clk (1, 1, cookie); + udelay (100); + if (!fns->done (cookie)) { + printf (" error!.\n"); + fns->abort (cookie); + return FPGA_FAIL; + } else { + printf ("\b\b\b done.\n"); + } + + /* 5. call lower layer post configuration */ + if (fns->post) { + if ((ret_val = fns->post (cookie)) < 0) { + fns->abort (cookie); + return ret_val; + } + } + + return FPGA_SUCCESS; +} diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c new file mode 100644 index 0000000..50d0921 --- /dev/null +++ b/drivers/fpga/virtex2.c @@ -0,0 +1,554 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * Keith Outwater, keith_outwater@mvis.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Configuration support for Xilinx Virtex2 devices. Based + * on spartan2.c (Rich Ireland, rireland@enterasys.com). + */ + +#include +#include + +#if 0 +#define FPGA_DEBUG +#endif + +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* + * If the SelectMap interface can be overrun by the processor, define + * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration + * file and add board-specific support for checking BUSY status. By default, + * assume that the SelectMap interface cannot be overrun. + */ +#ifndef CONFIG_SYS_FPGA_CHECK_BUSY +#undef CONFIG_SYS_FPGA_CHECK_BUSY +#endif + +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK +#define CONFIG_SYS_FPGA_PROG_FEEDBACK +#endif + +/* + * Don't allow config cycle to be interrupted + */ +#ifndef CONFIG_SYS_FPGA_CHECK_CTRLC +#undef CONFIG_SYS_FPGA_CHECK_CTRLC +#endif + +/* + * Check for errors during configuration by default + */ +#ifndef CONFIG_SYS_FPGA_CHECK_ERROR +#define CONFIG_SYS_FPGA_CHECK_ERROR +#endif + +/* + * The default timeout in mS for INIT_B to deassert after PROG_B has + * been deasserted. Per the latest Virtex II Handbook (page 347), the + * max time from PORG_B deassertion to INIT_B deassertion is 4uS per + * data frame for the XC2V8000. The XC2V8000 has 2860 data frames + * which yields 11.44 mS. So let's make it bigger in order to handle + * an XC2V1000, if anyone can ever get ahold of one. + */ +#ifndef CONFIG_SYS_FPGA_WAIT_INIT +#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */ +#endif + +/* + * The default timeout for waiting for BUSY to deassert during configuration. + * This is normally not necessary since for most reasonable configuration + * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. + */ +#ifndef CONFIG_SYS_FPGA_WAIT_BUSY +#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/ +#endif + +/* Default timeout for waiting for FPGA to enter operational mode after + * configuration data has been written. + */ +#ifndef CONFIG_SYS_FPGA_WAIT_CONFIG +#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */ +#endif + +static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset); + +static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset); + +int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + ret_val = Virtex2_ss_load (desc, buf, bsize); + break; + + case slave_selectmap: + PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + ret_val = Virtex2_ssm_load (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + return ret_val; +} + +int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + ret_val = Virtex2_ss_dump (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + ret_val = Virtex2_ssm_dump (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + return ret_val; +} + +int Virtex2_info (Xilinx_desc * desc) +{ + return FPGA_SUCCESS; +} + +int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; + + if (desc->family != Xilinx_Virtex2) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case slave_serial: + ret_val = Virtex2_ss_reloc (desc, reloc_offset); + break; + + case slave_selectmap: + ret_val = Virtex2_ssm_reloc (desc, reloc_offset); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + return ret_val; +} + +/* + * Virtex-II Slave SelectMap configuration loader. Configuration via + * SelectMap is as follows: + * 1. Set the FPGA's PROG_B line low. + * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. + * 3. Write data to the SelectMap port. If INIT_B goes low at any time + * this process, a configuration error (most likely CRC failure) has + * ocurred. At this point a status word may be read from the + * SelectMap interface to determine the source of the problem (You + * could, for instance, put this in your 'abort' function handler). + * 4. After all data has been written, test the state of the FPGA + * INIT_B and DONE lines. If both are high, configuration has + * succeeded. Congratulations! + */ +static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; + + PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", + __FUNCTION__, __LINE__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; + unsigned long ts; + + /* Gotta split this one up (so the stack won't blow??) */ + PRINTF ("%s:%d: Function Table:\n" + " base 0x%p\n" + " struct 0x%p\n" + " pre 0x%p\n" + " prog 0x%p\n" + " init 0x%p\n" + " error 0x%p\n", + __FUNCTION__, __LINE__, + &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); + PRINTF (" clock 0x%p\n" + " cs 0x%p\n" + " write 0x%p\n" + " rdata 0x%p\n" + " wdata 0x%p\n" + " busy 0x%p\n" + " abort 0x%p\n" + " post 0x%p\n\n", + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, + fn->busy, fn->abort, fn->post); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Initializing FPGA Device %d...\n", cookie); +#endif + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* + * Assert the program line. The minimum pulse width for + * Virtex II devices is 300 nS (Tprogram parameter in datasheet). + * There is no maximum value for the pulse width. Check to make + * sure that INIT_B goes low after assertion of PROG_B + */ + (*fn->pgm) (TRUE, TRUE, cookie); + udelay (10); + ts = get_timer (0); + do { + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { + printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" + " to assert.\n", __FUNCTION__, __LINE__, + CONFIG_SYS_FPGA_WAIT_INIT); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } while (!(*fn->init) (cookie)); + + (*fn->pgm) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); + + /* + * Start a timer and wait for INIT_B to go high + */ + ts = get_timer (0); + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { + printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" + " to deassert.\n", __FUNCTION__, __LINE__, + CONFIG_SYS_FPGA_WAIT_INIT); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + + (*fn->wr) (TRUE, TRUE, cookie); + (*fn->cs) (TRUE, TRUE, cookie); + + udelay (10000); + + /* + * Load the data byte by byte + */ + while (bytecount < bsize) { +#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC + if (ctrlc ()) { + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + + if ((*fn->done) (cookie) == FPGA_SUCCESS) { + PRINTF ("%s:%d:done went active early, bytecount = %d\n", + __FUNCTION__, __LINE__, bytecount); + break; + } + +#ifdef CONFIG_SYS_FPGA_CHECK_ERROR + if ((*fn->init) (cookie)) { + printf ("\n%s:%d: ** Error: INIT asserted during" + " configuration\n", __FUNCTION__, __LINE__); + printf ("%d = buffer offset, %d = buffer size\n", + bytecount, bsize); + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + + (*fn->wdata) (data[bytecount++], TRUE, cookie); + CONFIG_FPGA_DELAY (); + + /* + * Cycle the clock pin + */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); + +#ifdef CONFIG_SYS_FPGA_CHECK_BUSY + ts = get_timer (0); + while ((*fn->busy) (cookie)) { + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { + printf ("%s:%d: ** Timeout after %d ticks waiting for" + " BUSY to deassert\n", + __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } +#endif + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); +#endif + } + + /* + * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. + */ + CONFIG_FPGA_DELAY (); + (*fn->cs) (FALSE, TRUE, cookie); + (*fn->wr) (FALSE, TRUE, cookie); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); +#endif + + /* + * Check for successful configuration. FPGA INIT_B and DONE should + * both be high upon successful configuration. + */ + ts = get_timer (0); + ret_val = FPGA_SUCCESS; + while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { + if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { + printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" + "assert and INIT to deassert\n", + __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); + (*fn->abort) (cookie); + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("Initialization of FPGA device %d complete\n", cookie); +#endif + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + } else { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf ("** Initialization of FPGA device %d FAILED\n", + cookie); +#endif + } + } else { + printf ("%s:%d: NULL Interface function table!\n", + __FUNCTION__, __LINE__); + } + return ret_val; +} + +/* + * Read the FPGA configuration data + */ +static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; + + if (fn) { + unsigned char *data = (unsigned char *) buf; + size_t bytecount = 0; + int cookie = desc->cookie; + + printf ("Starting Dump of FPGA Device %d...\n", cookie); + + (*fn->cs) (TRUE, TRUE, cookie); + (*fn->clk) (TRUE, TRUE, cookie); + + while (bytecount < bsize) { +#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC + if (ctrlc ()) { + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + /* + * Cycle the clock and read the data + */ + (*fn->clk) (FALSE, TRUE, cookie); + (*fn->clk) (TRUE, TRUE, cookie); + (*fn->rdata) (&(data[bytecount++]), cookie); +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); +#endif + } + + /* + * Deassert CS_B and cycle the clock to deselect the device. + */ + (*fn->cs) (FALSE, FALSE, cookie); + (*fn->clk) (FALSE, TRUE, cookie); + (*fn->clk) (TRUE, TRUE, cookie); + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + putc ('\n'); +#endif + puts ("Done.\n"); + } else { + printf ("%s:%d: NULL Interface function table!\n", + __FUNCTION__, __LINE__); + } + return ret_val; +} + +/* + * Relocate the addresses in the function table from FLASH (or ROM, + * or whatever) to RAM. + */ +static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + ulong addr; + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn = + (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns); + + if (fn) { + /* + * Get the relocated table address + */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr; + + /* + * Check to see if the table has already been relocated. If not, do + * a sanity check to make sure there is a faithful copy of the + * FLASH based function table in RAM, then adjust the table. + */ + if (!fn_r->relocated) { + if (memcmp + (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns)) + == 0) { + desc->iface_fns = fn_r; + } else { + PRINTF ("%s:%d: Invalid function table at 0x%p\n", + __FUNCTION__, __LINE__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s:%d: Relocating descriptor at 0x%p\n", + __FUNCTION__, __LINE__, desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + addr = (ulong) (fn->err) + reloc_offset; + fn_r->err = (Xilinx_err_fn) addr; + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + addr = (ulong) (fn->cs) + reloc_offset; + fn_r->cs = (Xilinx_cs_fn) addr; + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + addr = (ulong) (fn->rdata) + reloc_offset; + fn_r->rdata = (Xilinx_rdata_fn) addr; + addr = (ulong) (fn->wdata) + reloc_offset; + fn_r->wdata = (Xilinx_wdata_fn) addr; + addr = (ulong) (fn->busy) + reloc_offset; + fn_r->busy = (Xilinx_busy_fn) addr; + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Xilinx_abort_fn) addr; + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + fn_r->relocated = TRUE; + } else { + printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r); + desc->iface_fns = fn_r; + } + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + return ret_val; +} + +static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); + return FPGA_FAIL; +} + +static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); + return FPGA_FAIL; +} + +static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_Serial_fns *fn = + (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns); + + if (fn) { + printf ("%s:%d: Slave Serial Loading is unsupported\n", + __FUNCTION__, __LINE__); + } else { + printf ("%s:%d: NULL Interface function table!\n", + __FUNCTION__, __LINE__); + } + return ret_val; +} + +/* vim: set ts=4 tw=78: */ diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c new file mode 100644 index 0000000..7b5e8c5 --- /dev/null +++ b/drivers/fpga/xilinx.c @@ -0,0 +1,307 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * Keith Outwater, keith_outwater@mvis.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Xilinx FPGA support + */ + +#include +#include +#include +#include + +#if 0 +#define FPGA_DEBUG +#endif + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Local Static Functions */ +static int xilinx_validate (Xilinx_desc * desc, char *fn); + +/* ------------------------------------------------------------------------- */ + +int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!xilinx_validate (desc, (char *)__FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else + switch (desc->family) { + case Xilinx_Spartan2: +#if defined(CONFIG_FPGA_SPARTAN2) + PRINTF ("%s: Launching the Spartan-II Loader...\n", + __FUNCTION__); + ret_val = Spartan2_load (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Spartan3: +#if defined(CONFIG_FPGA_SPARTAN3) + PRINTF ("%s: Launching the Spartan-III Loader...\n", + __FUNCTION__); + ret_val = Spartan3_load (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if defined(CONFIG_FPGA_VIRTEX2) + PRINTF ("%s: Launching the Virtex-II Loader...\n", + __FUNCTION__); + ret_val = Virtex2_load (desc, buf, bsize); +#else + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + + return ret_val; +} + +int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!xilinx_validate (desc, (char *)__FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else + switch (desc->family) { + case Xilinx_Spartan2: +#if defined(CONFIG_FPGA_SPARTAN2) + PRINTF ("%s: Launching the Spartan-II Reader...\n", + __FUNCTION__); + ret_val = Spartan2_dump (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Spartan3: +#if defined(CONFIG_FPGA_SPARTAN3) + PRINTF ("%s: Launching the Spartan-III Reader...\n", + __FUNCTION__); + ret_val = Spartan3_dump (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if defined( CONFIG_FPGA_VIRTEX2) + PRINTF ("%s: Launching the Virtex-II Reader...\n", + __FUNCTION__); + ret_val = Virtex2_dump (desc, buf, bsize); +#else + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + + return ret_val; +} + +int xilinx_info (Xilinx_desc * desc) +{ + int ret_val = FPGA_FAIL; + + if (xilinx_validate (desc, (char *)__FUNCTION__)) { + printf ("Family: \t"); + switch (desc->family) { + case Xilinx_Spartan2: + printf ("Spartan-II\n"); + break; + case Xilinx_Spartan3: + printf ("Spartan-III\n"); + break; + case Xilinx_Virtex2: + printf ("Virtex-II\n"); + break; + /* Add new family types here */ + default: + printf ("Unknown family type, %d\n", desc->family); + } + + printf ("Interface type:\t"); + switch (desc->iface) { + case slave_serial: + printf ("Slave Serial\n"); + break; + case master_serial: /* Not used */ + printf ("Master Serial\n"); + break; + case slave_parallel: + printf ("Slave Parallel\n"); + break; + case jtag_mode: /* Not used */ + printf ("JTAG Mode\n"); + break; + case slave_selectmap: + printf ("Slave SelectMap Mode\n"); + break; + case master_selectmap: + printf ("Master SelectMap Mode\n"); + break; + /* Add new interface types here */ + default: + printf ("Unsupported interface type, %d\n", desc->iface); + } + + printf ("Device Size: \t%d bytes\n" + "Cookie: \t0x%x (%d)\n", + desc->size, desc->cookie, desc->cookie); + + if (desc->iface_fns) { + printf ("Device Function Table @ 0x%p\n", desc->iface_fns); + switch (desc->family) { + case Xilinx_Spartan2: +#if defined(CONFIG_FPGA_SPARTAN2) + Spartan2_info (desc); +#else + /* just in case */ + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Spartan3: +#if defined(CONFIG_FPGA_SPARTAN3) + Spartan3_info (desc); +#else + /* just in case */ + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if defined(CONFIG_FPGA_VIRTEX2) + Virtex2_info (desc); +#else + /* just in case */ + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + /* Add new family types here */ + default: + /* we don't need a message here - we give one up above */ + ; + } + } else + printf ("No Device Function Table.\n"); + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } + + return ret_val; +} + +int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!xilinx_validate (desc, (char *)__FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else + switch (desc->family) { + case Xilinx_Spartan2: +#if defined(CONFIG_FPGA_SPARTAN2) + ret_val = Spartan2_reloc (desc, reloc_offset); +#else + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Spartan3: +#if defined(CONFIG_FPGA_SPARTAN3) + ret_val = Spartan3_reloc (desc, reloc_offset); +#else + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if defined(CONFIG_FPGA_VIRTEX2) + ret_val = Virtex2_reloc (desc, reloc_offset); +#else + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + /* Add new family types here */ + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ + +static int xilinx_validate (Xilinx_desc * desc, char *fn) +{ + int ret_val = FALSE; + + if (desc) { + if ((desc->family > min_xilinx_type) && + (desc->family < max_xilinx_type)) { + if ((desc->iface > min_xilinx_iface_type) && + (desc->iface < max_xilinx_iface_type)) { + if (desc->size) { + ret_val = TRUE; + } else + printf ("%s: NULL part size\n", fn); + } else + printf ("%s: Invalid Interface type, %d\n", + fn, desc->iface); + } else + printf ("%s: Invalid family type, %d\n", fn, desc->family); + } else + printf ("%s: NULL descriptor!\n", fn); + + return ret_val; +} -- cgit v1.1 From bfa0af6b22ff25b0719a8910f9b6d1f975aa6fb0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 2 Nov 2008 01:18:18 -0400 Subject: ignore .gdb_history files When using gdb, history files will often get generated. So ignore them. Signed-off-by: Mike Frysinger --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 9c53f5c..e13fc96 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,9 @@ patches-* patches series +# gdb files +.gdb_history + # cscope files cscope.* -- cgit v1.1 From 1450c4a6682378567030414a9f1198c39b7730c7 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 3 Nov 2008 15:30:34 +0100 Subject: lwmon, tqm8xx: Fix build errors Commit 6b59e03e0237a40a2305ea385defdfd92000978b lcd: Let the board code show board-specific info introduced some bugs which prevent U-Boot building for lwmon board if CONFIG_LCD_INFO_BELOW_LOGO will be defined in the board configuration. Also "LCD enabled" building for TQM823L doesn't work since this commit. This patch fixes above-mentioned issues. Signed-off-by: Anatolij Gustschin --- board/lwmon/lwmon.c | 2 -- board/tqc/tqm8xx/tqm8xx.c | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c index 9e57246..d062466 100644 --- a/board/lwmon/lwmon.c +++ b/board/lwmon/lwmon.c @@ -773,8 +773,6 @@ void lcd_show_board_info(void) #ifdef CONFIG_LCD_INFO_BELOW_LOGO lcd_printf ("MPC823 CPU at %s MHz\n", strmhz(temp, gd->cpu_clk)); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3, - info, strlen(info)); lcd_printf (" %ld MB RAM, %ld MB Flash\n", gd->ram_size >> 20, gd->bd->bi_flashsize >> 20 ); diff --git a/board/tqc/tqm8xx/tqm8xx.c b/board/tqc/tqm8xx/tqm8xx.c index 928afed..d8a19a4 100644 --- a/board/tqc/tqm8xx/tqm8xx.c +++ b/board/tqc/tqm8xx/tqm8xx.c @@ -570,17 +570,18 @@ void ide_led (uchar led, uchar status) #ifdef CONFIG_LCD_INFO #include +#include void lcd_show_board_info(void) { + char temp[32]; + lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, __DATE__, __TIME__); lcd_printf ("(C) 2008 DENX Software Engineering GmbH\n"); lcd_printf (" Wolfgang DENK, wd@denx.de\n"); #ifdef CONFIG_LCD_INFO_BELOW_LOGO lcd_printf ("MPC823 CPU at %s MHz\n", strmhz(temp, gd->cpu_clk)); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3, - info, strlen(info)); lcd_printf (" %ld MB RAM, %ld MB Flash\n", gd->ram_size >> 20, gd->bd->bi_flashsize >> 20 ); -- cgit v1.1 From 89a7a87f084c657f8e32b513a77b50eca07e17ec Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Sat, 6 Dec 2008 13:11:14 +0100 Subject: at91: Choose environment variables location within make config target This patch adds the possiblity to choose the media where the environment will be located. This allow to choose this fundamental configuration without editing config files. Documentation file added. Signed-off-by: Nicolas Ferre Acked-by: Stelian Pop Acked-by: Jean-Christophe PLAGNIOL-VILLARD --- Makefile | 54 +++++++++++++++++++++++-- doc/README.at91 | 88 +++++++++++++++++++++++++++++++++++++++++ include/configs/at91sam9260ek.h | 4 -- include/configs/at91sam9261ek.h | 19 +++++++-- include/configs/at91sam9263ek.h | 3 -- include/configs/at91sam9rlek.h | 3 -- 6 files changed, 153 insertions(+), 18 deletions(-) create mode 100644 doc/README.at91 diff --git a/Makefile b/Makefile index befb608..2ac8141 100644 --- a/Makefile +++ b/Makefile @@ -2582,17 +2582,63 @@ afeb9260_config: unconfig at91cap9adk_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm926ejs at91cap9adk atmel at91 +at91sam9260ek_nandflash_config \ +at91sam9260ek_dataflash_cs0_config \ +at91sam9260ek_dataflash_cs1_config \ at91sam9260ek_config : unconfig - @$(MKCONFIG) $(@:_config=) arm arm926ejs at91sam9260ek atmel at91 + @if [ "$(findstring _nandflash,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in NAND FLASH" ; \ + elif [ "$(findstring dataflash_cs0,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_DATAFLASH_CS0 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \ + else \ + echo "#define CONFIG_SYS_USE_DATAFLASH_CS1 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS1" ; \ + fi; + @$(MKCONFIG) -a at91sam9260ek arm arm926ejs at91sam9260ek atmel at91 +at91sam9261ek_nandflash_config \ +at91sam9261ek_dataflash_cs0_config \ +at91sam9261ek_dataflash_cs3_config \ at91sam9261ek_config : unconfig - @$(MKCONFIG) $(@:_config=) arm arm926ejs at91sam9261ek atmel at91 + @if [ "$(findstring _nandflash,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in NAND FLASH" ; \ + elif [ "$(findstring dataflash_cs3,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_DATAFLASH_CS3 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS3" ; \ + else \ + echo "#define CONFIG_SYS_USE_DATAFLASH_CS0 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \ + fi; + @$(MKCONFIG) -a at91sam9261ek arm arm926ejs at91sam9261ek atmel at91 +at91sam9263ek_nandflash_config \ +at91sam9263ek_dataflash_config \ +at91sam9263ek_dataflash_cs0_config \ at91sam9263ek_config : unconfig - @$(MKCONFIG) $(@:_config=) arm arm926ejs at91sam9263ek atmel at91 + @if [ "$(findstring _nandflash,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in NAND FLASH" ; \ + else \ + echo "#define CONFIG_SYS_USE_DATAFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \ + fi; + @$(MKCONFIG) -a at91sam9263ek arm arm926ejs at91sam9263ek atmel at91 +at91sam9rlek_nandflash_config \ +at91sam9rlek_dataflash_config \ +at91sam9rlek_dataflash_cs0_config \ at91sam9rlek_config : unconfig - @$(MKCONFIG) $(@:_config=) arm arm926ejs at91sam9rlek atmel at91 + @if [ "$(findstring _nandflash,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in NAND FLASH" ; \ + else \ + echo "#define CONFIG_SYS_USE_DATAFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \ + fi; + @$(MKCONFIG) -a at91sam9rlek arm arm926ejs at91sam9rlek atmel at91 ######################################################################## ## ARM Integrator boards - see doc/README-integrator for more info. diff --git a/doc/README.at91 b/doc/README.at91 new file mode 100644 index 0000000..838769a --- /dev/null +++ b/doc/README.at91 @@ -0,0 +1,88 @@ +Atmel AT91 Evaluation kits + +http://atmel.com/dyn/products/tools.asp?family_id=605#1443 + +------------------------------------------------------------------------------ +AT91SAM9260EK +------------------------------------------------------------------------------ + +Memory map + 0x20000000 - 23FFFFFF SDRAM (64 MB) + 0xC0000000 - Cxxxxxxx Atmel Dataflash card (J13) + 0xD0000000 - Dxxxxxxx Soldered Atmel Dataflash + +Environment variables + + U-Boot environment variables can be stored at different places: + - Dataflash on SPI chip select 1 (default) + - Dataflash on SPI chip select 0 (dataflash card) + - Nand flash. + + You can choose your storage location at config step (here for at91sam9260ek) : + make at91sam9260ek_config - use data flash (spi cs1) (default) + make at91sam9260ek_nandflash_config - use nand flash + make at91sam9260ek_dataflash_cs0_config - use data flash (spi cs0) + make at91sam9260ek_dataflash_cs1_config - use data flash (spi cs1) + + +------------------------------------------------------------------------------ +AT91SAM9261EK +------------------------------------------------------------------------------ + +Memory map + 0x20000000 - 23FFFFFF SDRAM (64 MB) + 0xC0000000 - Cxxxxxxx Soldered Atmel Dataflash + 0xD0000000 - Dxxxxxxx Atmel Dataflash card (J22) + +Environment variables + + U-Boot environment variables can be stored at different places: + - Dataflash on SPI chip select 0 (default) + - Dataflash on SPI chip select 3 (dataflash card) + - Nand flash. + + You can choose your storage location at config step (here for at91sam9260ek) : + make at91sam9261ek_config - use data flash (spi cs0) (default) + make at91sam9261ek_nandflash_config - use nand flash + make at91sam9261ek_dataflash_cs0_config - use data flash (spi cs0) + make at91sam9261ek_dataflash_cs3_config - use data flash (spi cs3) + + +------------------------------------------------------------------------------ +AT91SAM9263EK +------------------------------------------------------------------------------ + +Memory map + 0x20000000 - 23FFFFFF SDRAM (64 MB) + 0xC0000000 - Cxxxxxxx Atmel Dataflash card (J9) + +Environment variables + + U-Boot environment variables can be stored at different places: + - Dataflash on SPI chip select 0 (dataflash card) + - Nand flash. + + You can choose your storage location at config step (here for at91sam9260ek) : + make at91sam9263ek_config - use data flash (spi cs0) (default) + make at91sam9263ek_nandflash_config - use nand flash + make at91sam9263ek_dataflash_cs0_config - use data flash (spi cs0) + + +------------------------------------------------------------------------------ +AT91SAM9RLEK +------------------------------------------------------------------------------ + +Memory map + 0x20000000 - 23FFFFFF SDRAM (64 MB) + 0xC0000000 - Cxxxxxxx Soldered Atmel Dataflash + +Environment variables + + U-Boot environment variables can be stored at different places: + - Dataflash on SPI chip select 0 + - Nand flash. + + You can choose your storage location at config step (here for at91sam9260ek) : + make at91sam9263ek_config - use data flash (spi cs0) (default) + make at91sam9263ek_nandflash_config - use nand flash + make at91sam9263ek_dataflash_cs0_config - use data flash (spi cs0) diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index fbc470f..2df8d54 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -131,10 +131,6 @@ #define CONFIG_SYS_MEMTEST_START PHYS_SDRAM #define CONFIG_SYS_MEMTEST_END 0x23e00000 -#undef CONFIG_SYS_USE_DATAFLASH_CS0 -#define CONFIG_SYS_USE_DATAFLASH_CS1 1 -#undef CONFIG_SYS_USE_NANDFLASH - #ifdef CONFIG_SYS_USE_DATAFLASH_CS0 /* bootstrap + u-boot + env + linux in dataflash on CS0 */ diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index bd66823..0016b4f 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -144,15 +144,12 @@ #define CONFIG_SYS_MEMTEST_START PHYS_SDRAM #define CONFIG_SYS_MEMTEST_END 0x23e00000 -#define CONFIG_SYS_USE_DATAFLASH_CS0 1 -#undef CONFIG_SYS_USE_NANDFLASH - #ifdef CONFIG_SYS_USE_DATAFLASH_CS0 /* bootstrap + u-boot + env + linux in dataflash on CS0 */ #define CONFIG_ENV_IS_IN_DATAFLASH 1 #define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS0 + 0x8400) -#define CONFIG_ENV_OFFSET 0x4200 +#define CONFIG_ENV_OFFSET 0x4200 #define CONFIG_ENV_ADDR (CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS0 + CONFIG_ENV_OFFSET) #define CONFIG_ENV_SIZE 0x4200 #define CONFIG_BOOTCOMMAND "cp.b 0xC0042000 0x22000000 0x210000; bootm" @@ -161,6 +158,20 @@ "mtdparts=at91_nand:-(root) " \ "rw rootfstype=jffs2" +#elif CONFIG_SYS_USE_DATAFLASH_CS3 + +/* bootstrap + u-boot + env + linux in dataflash on CS3 */ +#define CONFIG_ENV_IS_IN_DATAFLASH 1 +#define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS3 + 0x8400) +#define CONFIG_ENV_OFFSET 0x4200 +#define CONFIG_ENV_ADDR (CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS3 + CONFIG_ENV_OFFSET) +#define CONFIG_ENV_SIZE 0x4200 +#define CONFIG_BOOTCOMMAND "cp.b 0xD0042000 0x22000000 0x210000; bootm" +#define CONFIG_BOOTARGS "console=ttyS0,115200 " \ + "root=/dev/mtdblock0 " \ + "mtdparts=at91_nand:-(root) " \ + "rw rootfstype=jffs2" + #else /* CONFIG_SYS_USE_NANDFLASH */ /* bootstrap + u-boot + env + linux in nandflash */ diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index a2b09ca..fc7c941 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -151,9 +151,6 @@ #define CONFIG_SYS_MEMTEST_START PHYS_SDRAM #define CONFIG_SYS_MEMTEST_END 0x23e00000 -#define CONFIG_SYS_USE_DATAFLASH 1 -#undef CONFIG_SYS_USE_NANDFLASH - #ifdef CONFIG_SYS_USE_DATAFLASH /* bootstrap + u-boot + env + linux in dataflash on CS0 */ diff --git a/include/configs/at91sam9rlek.h b/include/configs/at91sam9rlek.h index 35dac47..35fefc4 100644 --- a/include/configs/at91sam9rlek.h +++ b/include/configs/at91sam9rlek.h @@ -118,9 +118,6 @@ #define CONFIG_SYS_MEMTEST_START PHYS_SDRAM #define CONFIG_SYS_MEMTEST_END 0x23e00000 -#define CONFIG_SYS_USE_DATAFLASH 1 -#undef CONFIG_SYS_USE_NANDFLASH - #ifdef CONFIG_SYS_USE_DATAFLASH /* bootstrap + u-boot + env + linux in dataflash on CS0 */ -- cgit v1.1 From 83ad179e2f0f625b88adb8ef5696709e46fb9077 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Thu, 4 Dec 2008 22:25:57 +0100 Subject: Remove redundant armv4 flag from arm926ejs compile flags Currently the arm926ejs tree has the armv4 option set during compilation. This flag does not belong here because a arm926 CPU is always a armv5 CPU. Signed-off-by: Remy Bohmer --- cpu/arm926ejs/at91/config.mk | 1 - cpu/arm926ejs/config.mk | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cpu/arm926ejs/at91/config.mk b/cpu/arm926ejs/at91/config.mk index 31491a8..06177e6 100644 --- a/cpu/arm926ejs/at91/config.mk +++ b/cpu/arm926ejs/at91/config.mk @@ -1,3 +1,2 @@ -PLATFORM_CPPFLAGS += -march=armv5te PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,) LDSCRIPT := $(SRCTREE)/cpu/arm926ejs/at91/u-boot.lds diff --git a/cpu/arm926ejs/config.mk b/cpu/arm926ejs/config.mk index 8db4adb..84b68ae 100644 --- a/cpu/arm926ejs/config.mk +++ b/cpu/arm926ejs/config.mk @@ -24,7 +24,7 @@ PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ -msoft-float -PLATFORM_CPPFLAGS += -march=armv4 +PLATFORM_CPPFLAGS += -march=armv5te # ========================================================================= # # Supply options according to compiler version -- cgit v1.1 From 561858ee7d0274c3e89dc98d4d0698cb6fcf6fd9 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 3 Nov 2008 09:30:59 -0600 Subject: Update U-Boot's build timestamp on every compile Use the GNU 'date' command to auto-generate a new U-Boot timestamp on every compile. Signed-off-by: Peter Tyser --- Makefile | 17 +++++++++++------ board/bmw/bmw.c | 4 ++-- board/eXalion/eXalion.c | 3 ++- board/lwmon/lwmon.c | 3 ++- board/mousse/mousse.c | 3 ++- board/netstar/eeprom.c | 3 ++- board/sandburst/karef/karef.c | 6 ++++-- board/sandburst/metrobox/metrobox.c | 6 ++++-- board/tqc/tqm8xx/tqm8xx.c | 3 ++- board/trab/trab_fkt.c | 3 ++- board/voiceblue/eeprom.c | 3 ++- cpu/74xx_7xx/start.S | 3 ++- cpu/leon2/start.S | 3 ++- cpu/leon3/start.S | 3 ++- cpu/mcf5227x/start.S | 3 ++- cpu/mcf523x/start.S | 3 ++- cpu/mcf52x2/start.S | 3 ++- cpu/mcf532x/start.S | 3 ++- cpu/mcf5445x/start.S | 3 ++- cpu/mcf547x_8x/start.S | 3 ++- cpu/mpc512x/start.S | 3 ++- cpu/mpc5xx/start.S | 3 ++- cpu/mpc5xxx/start.S | 3 ++- cpu/mpc8220/start.S | 3 ++- cpu/mpc824x/start.S | 3 ++- cpu/mpc8260/start.S | 3 ++- cpu/mpc83xx/start.S | 3 ++- cpu/mpc85xx/start.S | 3 ++- cpu/mpc86xx/start.S | 3 ++- cpu/mpc8xx/start.S | 3 ++- cpu/mpc8xx/video.c | 6 +++++- cpu/nios/start.S | 3 ++- cpu/nios2/start.S | 3 ++- cpu/ppc4xx/start.S | 3 ++- include/.gitignore | 1 + include/configs/NETPHONE.h | 2 +- include/configs/NETTA.h | 2 +- include/configs/NETTA2.h | 2 +- include/timestamp.h | 30 ++++++++++++++++++++++++++++++ lib_arm/board.c | 3 ++- lib_avr32/board.c | 3 ++- lib_blackfin/board.c | 3 ++- lib_i386/board.c | 3 ++- lib_microblaze/board.c | 3 ++- lib_mips/board.c | 3 ++- lib_sh/board.c | 3 ++- net/net.c | 3 +++ 47 files changed, 135 insertions(+), 52 deletions(-) create mode 100644 include/timestamp.h diff --git a/Makefile b/Makefile index 4eff1b5..11fc3b7 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) else U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION) endif +TIMESTAMP_FILE = $(obj)include/timestamp_autogenerated.h VERSION_FILE = $(obj)include/version_autogenerated.h HOSTARCH := $(shell uname -m | \ @@ -261,7 +262,7 @@ LIBS += api/libapi.a LIBS += post/libpost.a LIBS := $(addprefix $(obj),$(LIBS)) -.PHONY : $(LIBS) $(VERSION_FILE) +.PHONY : $(LIBS) $(TIMESTAMP_FILE) $(VERSION_FILE) LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a LIBBOARD := $(addprefix $(obj),$(LIBBOARD)) @@ -353,13 +354,13 @@ $(SUBDIRS): depend $(obj)include/autoconf.mk $(LDSCRIPT): depend $(obj)include/autoconf.mk $(MAKE) -C $(dir $@) $(notdir $@) -$(NAND_SPL): $(VERSION_FILE) $(obj)include/autoconf.mk +$(NAND_SPL): $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk $(MAKE) -C nand_spl/board/$(BOARDDIR) all $(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin -$(ONENAND_IPL): $(VERSION_FILE) $(obj)include/autoconf.mk +$(ONENAND_IPL): $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all $(U_BOOT_ONENAND): $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk @@ -372,6 +373,10 @@ $(VERSION_FILE): ) > $@.tmp @cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@ +$(TIMESTAMP_FILE): + @date +'#define U_BOOT_DATE "%b %d %C%y"' > $@ + @date +'#define U_BOOT_TIME "%T"' >> $@ + gdbtools: $(MAKE) -C tools/gdb all || exit 1 @@ -381,7 +386,7 @@ updater: env: $(MAKE) -C tools/env all MTD_VERSION=${MTD_VERSION} || exit 1 -depend dep: $(VERSION_FILE) +depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done TAG_SUBDIRS += include @@ -462,7 +467,7 @@ sinclude $(obj)include/autoconf.mk.dep else # !config.mk all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \ $(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \ -$(SUBDIRS) $(VERSION_FILE) gdbtools updater env depend \ +$(SUBDIRS) $(TIMESTAMP_FILE) $(VERSION_FILE) gdbtools updater env depend \ dep tags ctags etags cscope $(obj)System.map: @echo "System not configured - see README" >&2 @ exit 1 @@ -3274,7 +3279,7 @@ clean: @rm -f $(obj)include/bmp_logo.h @rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map} @rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map} - @rm -f $(obj)api_examples/demo $(VERSION_FILE) + @rm -f $(obj)api_examples/demo $(TIMESTAMP_FILE) $(VERSION_FILE) @find $(OBJTREE) -type f \ \( -name 'core' -o -name '*.bak' -o -name '*~' \ -o -name '*.o' -o -name '*.a' \) -print \ diff --git a/board/bmw/bmw.c b/board/bmw/bmw.c index b629c38..41ce14f 100644 --- a/board/bmw/bmw.c +++ b/board/bmw/bmw.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -45,7 +45,7 @@ int checkboard(void) char buf[32]; puts ("Board: BMW MPC8245/KAHLUA2 - CHRP (MAP B)\n"); - printf("Built: %s at %s\n", __DATE__ , __TIME__ ); + printf("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME); /* printf("MPLD: Revision %d\n", SYS_REVID_GET()); */ printf("Local Bus at %s MHz\n", strmhz(buf, busfreq)); return 0; diff --git a/board/eXalion/eXalion.c b/board/eXalion/eXalion.c index 34538c4..c17498f 100644 --- a/board/eXalion/eXalion.c +++ b/board/eXalion/eXalion.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "piix_pci.h" #include "eXalion.h" @@ -40,7 +41,7 @@ int checkboard (void) char buf[32]; printf ("Board: eXalion MPC824x - CHRP (MAP B)\n"); - printf ("Built: %s at %s\n", __DATE__, __TIME__); + printf ("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME); printf ("Local Bus: %s MHz\n", strmhz (buf, busfreq)); return 0; diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c index d062466..878752c 100644 --- a/board/lwmon/lwmon.c +++ b/board/lwmon/lwmon.c @@ -762,12 +762,13 @@ static uchar *key_match (uchar *kbd_data) #ifdef CONFIG_LCD_INFO #include #include +#include void lcd_show_board_info(void) { char temp[32]; - lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, __DATE__, __TIME__); + lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME); lcd_printf ("(C) 2008 DENX Software Engineering GmbH\n"); lcd_printf (" Wolfgang DENK, wd@denx.de\n"); #ifdef CONFIG_LCD_INFO_BELOW_LOGO diff --git a/board/mousse/mousse.c b/board/mousse/mousse.c index 6a12b57..bd8d1c6 100644 --- a/board/mousse/mousse.c +++ b/board/mousse/mousse.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "mousse.h" #include "m48t59y.h" @@ -42,7 +43,7 @@ int checkboard (void) char buf[32]; puts ("Board: MOUSSE MPC8240/KAHLUA - CHRP (MAP B)\n"); - printf ("Built: %s at %s\n", __DATE__, __TIME__); + printf ("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME); printf ("MPLD: Revision %d\n", SYS_REVID_GET ()); printf ("Local Bus: %s MHz\n", strmhz (buf, busfreq)); diff --git a/board/netstar/eeprom.c b/board/netstar/eeprom.c index 0de594b..5806128 100644 --- a/board/netstar/eeprom.c +++ b/board/netstar/eeprom.c @@ -26,6 +26,7 @@ #include #include +#include #include "../drivers/net/smc91111.h" #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE @@ -173,7 +174,7 @@ int eeprom(int argc, char *argv[]) /* Print help message */ if (argv[1][1] == 'h') { printf("VoiceBlue EEPROM writer\n"); - printf("Built: %s at %s\n", __DATE__ , __TIME__ ); + printf("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME); printf("Usage:\n\t [] [<...>]\n"); return 0; } diff --git a/board/sandburst/karef/karef.c b/board/sandburst/karef/karef.c index 7909d34..8d97a9c 100644 --- a/board/sandburst/karef/karef.c +++ b/board/sandburst/karef/karef.c @@ -26,6 +26,7 @@ #include #include "karef.h" #include "karef_version.h" +#include #include #include #include @@ -299,7 +300,7 @@ int checkboard (void) "Serial Number: %d\n", sernum); printf ("%s\n", KAREF_U_BOOT_REL_STR); - printf ("Built %s %s by %s\n", __DATE__, __TIME__, BUILDUSER); + printf ("Built %s %s by %s\n", U_BOOT_DATE, U_BOOT_TIME, BUILDUSER); if (sbcommon_get_master()) { printf("Slot 0 - Master\nSlave board"); if (sbcommon_secondary_present()) @@ -366,7 +367,8 @@ int misc_init_r (void) setenv("ubrelver", KAREF_U_BOOT_REL_STR); memset(envstr, 0, 255); - sprintf (envstr, "Built %s %s by %s", __DATE__, __TIME__, BUILDUSER); + sprintf (envstr, "Built %s %s by %s", + U_BOOT_DATE, U_BOOT_TIME, BUILDUSER); setenv("bldstr", envstr); saveenv(); diff --git a/board/sandburst/metrobox/metrobox.c b/board/sandburst/metrobox/metrobox.c index c3c4459..19302dc 100644 --- a/board/sandburst/metrobox/metrobox.c +++ b/board/sandburst/metrobox/metrobox.c @@ -25,6 +25,7 @@ #include #include "metrobox.h" #include "metrobox_version.h" +#include #include #include #include @@ -270,7 +271,7 @@ int checkboard (void) printf ("Board: Sandburst Corporation MetroBox Serial Number: %d\n", sernum); printf ("%s\n", METROBOX_U_BOOT_REL_STR); - printf ("Built %s %s by %s\n", __DATE__, __TIME__, BUILDUSER); + printf ("Built %s %s by %s\n", U_BOOT_DATE, U_BOOT_TIME, BUILDUSER); if (sbcommon_get_master()) { printf("Slot 0 - Master\nSlave board"); if (sbcommon_secondary_present()) @@ -335,7 +336,8 @@ int misc_init_r (void) setenv("ubrelver", METROBOX_U_BOOT_REL_STR); memset(envstr, 0, 255); - sprintf (envstr, "Built %s %s by %s", __DATE__, __TIME__, BUILDUSER); + sprintf (envstr, "Built %s %s by %s", + U_BOOT_DATE, U_BOOT_TIME, BUILDUSER); setenv("bldstr", envstr); saveenv(); diff --git a/board/tqc/tqm8xx/tqm8xx.c b/board/tqc/tqm8xx/tqm8xx.c index d8a19a4..e065d69 100644 --- a/board/tqc/tqm8xx/tqm8xx.c +++ b/board/tqc/tqm8xx/tqm8xx.c @@ -571,12 +571,13 @@ void ide_led (uchar led, uchar status) #ifdef CONFIG_LCD_INFO #include #include +#include void lcd_show_board_info(void) { char temp[32]; - lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, __DATE__, __TIME__); + lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME); lcd_printf ("(C) 2008 DENX Software Engineering GmbH\n"); lcd_printf (" Wolfgang DENK, wd@denx.de\n"); #ifdef CONFIG_LCD_INFO_BELOW_LOGO diff --git a/board/trab/trab_fkt.c b/board/trab/trab_fkt.c index 7273ef9..93b9490 100644 --- a/board/trab/trab_fkt.c +++ b/board/trab/trab_fkt.c @@ -25,6 +25,7 @@ #include #include +#include #include #include "tsc2000.h" #include "rs485.h" @@ -296,7 +297,7 @@ int trab_fkt (int argc, char *argv[]) int do_info (void) { printf ("Stand-alone application for TRAB board function test\n"); - printf ("Built: %s at %s\n", __DATE__ , __TIME__ ); + printf ("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME); return 0; } diff --git a/board/voiceblue/eeprom.c b/board/voiceblue/eeprom.c index d8ea6e5..f01597a 100644 --- a/board/voiceblue/eeprom.c +++ b/board/voiceblue/eeprom.c @@ -26,6 +26,7 @@ #include #include +#include #include "../drivers/net/smc91111.h" #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE @@ -169,7 +170,7 @@ int eeprom(int argc, char *argv[]) /* Print help message */ if (argv[1][1] == 'h') { printf("VoiceBlue EEPROM writer\n"); - printf("Built: %s at %s\n", __DATE__ , __TIME__ ); + printf("Built: %s at %s\n", U_BOOT_DATE, U_BOOT_TIME); printf("Usage:\n\t [] [<...>]\n"); return 0; } diff --git a/cpu/74xx_7xx/start.S b/cpu/74xx_7xx/start.S index b5484e3..792cd30 100644 --- a/cpu/74xx_7xx/start.S +++ b/cpu/74xx_7xx/start.S @@ -34,6 +34,7 @@ */ #include #include <74xx_7xx.h> +#include #include #include @@ -87,7 +88,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET diff --git a/cpu/leon2/start.S b/cpu/leon2/start.S index 9b5d83e..b1f1eb5 100644 --- a/cpu/leon2/start.S +++ b/cpu/leon2/start.S @@ -27,6 +27,7 @@ #include #include #include +#include #include /* Entry for traps which jump to a programmer-specified trap handler. */ @@ -199,7 +200,7 @@ _trap_table: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .section ".text" diff --git a/cpu/leon3/start.S b/cpu/leon3/start.S index 7afe10e..bd634bd 100644 --- a/cpu/leon3/start.S +++ b/cpu/leon3/start.S @@ -27,6 +27,7 @@ #include #include #include +#include #include /* Entry for traps which jump to a programmer-specified trap handler. */ @@ -200,7 +201,7 @@ _trap_table: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .section ".text" diff --git a/cpu/mcf5227x/start.S b/cpu/mcf5227x/start.S index 9387250..0c9c89c 100644 --- a/cpu/mcf5227x/start.S +++ b/cpu/mcf5227x/start.S @@ -22,6 +22,7 @@ */ #include +#include #include "version.h" #ifndef CONFIG_IDENT_STRING @@ -591,6 +592,6 @@ dcache_status: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mcf523x/start.S b/cpu/mcf523x/start.S index b70b83b..d44da37 100644 --- a/cpu/mcf523x/start.S +++ b/cpu/mcf523x/start.S @@ -22,6 +22,7 @@ */ #include +#include #include "version.h" #ifndef CONFIG_IDENT_STRING @@ -336,6 +337,6 @@ dcache_status: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S index da45bcb..ba6b884 100644 --- a/cpu/mcf52x2/start.S +++ b/cpu/mcf52x2/start.S @@ -22,6 +22,7 @@ */ #include +#include #include "version.h" #ifndef CONFIG_IDENT_STRING @@ -474,6 +475,6 @@ dcache_status: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mcf532x/start.S b/cpu/mcf532x/start.S index 8fa605a..a46c47a 100644 --- a/cpu/mcf532x/start.S +++ b/cpu/mcf532x/start.S @@ -25,6 +25,7 @@ */ #include +#include #include "version.h" #ifndef CONFIG_IDENT_STRING @@ -342,6 +343,6 @@ dcache_status: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mcf5445x/start.S b/cpu/mcf5445x/start.S index 61e43ff..d5a7f93 100644 --- a/cpu/mcf5445x/start.S +++ b/cpu/mcf5445x/start.S @@ -22,6 +22,7 @@ */ #include +#include #include "version.h" #ifndef CONFIG_IDENT_STRING @@ -627,6 +628,6 @@ dcache_status: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mcf547x_8x/start.S b/cpu/mcf547x_8x/start.S index 41fc694..94ef14b 100644 --- a/cpu/mcf547x_8x/start.S +++ b/cpu/mcf547x_8x/start.S @@ -22,6 +22,7 @@ */ #include +#include #include "version.h" #ifndef CONFIG_IDENT_STRING @@ -357,6 +358,6 @@ dcache_status: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mpc512x/start.S b/cpu/mpc512x/start.S index 26f3c52..360682d 100644 --- a/cpu/mpc512x/start.S +++ b/cpu/mpc512x/start.S @@ -31,6 +31,7 @@ #include #include +#include #include #define CONFIG_521X 1 /* needed for Linux kernel header files*/ @@ -85,7 +86,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii " ", CONFIG_IDENT_STRING, "\0" /* diff --git a/cpu/mpc5xx/start.S b/cpu/mpc5xx/start.S index f2ffe84..106935c 100644 --- a/cpu/mpc5xx/start.S +++ b/cpu/mpc5xx/start.S @@ -32,6 +32,7 @@ #include #include +#include #include #define CONFIG_5xx 1 /* needed for Linux kernel header files */ @@ -80,7 +81,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET diff --git a/cpu/mpc5xxx/start.S b/cpu/mpc5xxx/start.S index defe77d..6b1162a 100644 --- a/cpu/mpc5xxx/start.S +++ b/cpu/mpc5xxx/start.S @@ -27,6 +27,7 @@ */ #include #include +#include #include #define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */ @@ -78,7 +79,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" /* diff --git a/cpu/mpc8220/start.S b/cpu/mpc8220/start.S index 373be2c..3abc619 100644 --- a/cpu/mpc8220/start.S +++ b/cpu/mpc8220/start.S @@ -27,6 +27,7 @@ */ #include #include +#include #include #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ @@ -77,7 +78,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" /* diff --git a/cpu/mpc824x/start.S b/cpu/mpc824x/start.S index b5d7eb1..39325cd 100644 --- a/cpu/mpc824x/start.S +++ b/cpu/mpc824x/start.S @@ -39,6 +39,7 @@ */ #include #include +#include #include #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ @@ -90,7 +91,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET diff --git a/cpu/mpc8260/start.S b/cpu/mpc8260/start.S index da0c516..379f2fb 100644 --- a/cpu/mpc8260/start.S +++ b/cpu/mpc8260/start.S @@ -27,6 +27,7 @@ */ #include #include +#include #include #define CONFIG_8260 1 /* needed for Linux kernel header files */ @@ -85,7 +86,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" /* diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index cd566b2..792b2c8 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -29,6 +29,7 @@ #include #include +#include #include #define CONFIG_83XX 1 /* needed for Linux kernel header files*/ @@ -105,7 +106,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii " ", CONFIG_IDENT_STRING, "\0" diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 651ff1c..8fa0ff7 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -30,6 +30,7 @@ #include #include +#include #include #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ @@ -274,7 +275,7 @@ _start: .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" .align 4 diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S index efd654c..6645cb8 100644 --- a/cpu/mpc86xx/start.S +++ b/cpu/mpc86xx/start.S @@ -32,6 +32,7 @@ */ #include #include +#include #include #include @@ -76,7 +77,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET diff --git a/cpu/mpc8xx/start.S b/cpu/mpc8xx/start.S index 7b75660..45c902e 100644 --- a/cpu/mpc8xx/start.S +++ b/cpu/mpc8xx/start.S @@ -39,6 +39,7 @@ */ #include #include +#include #include #define CONFIG_8xx 1 /* needed for Linux kernel header files */ @@ -87,7 +88,7 @@ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET diff --git a/cpu/mpc8xx/video.c b/cpu/mpc8xx/video.c index 2e6a22a..5479644 100644 --- a/cpu/mpc8xx/video.c +++ b/cpu/mpc8xx/video.c @@ -32,7 +32,10 @@ #include #include #include +#ifdef VIDEO_INFO #include +#include +#endif #include #include #include @@ -1174,7 +1177,8 @@ static void *video_logo (void) easylogo_plot (VIDEO_LOGO_ADDR, screen, width, 0, 0); #ifdef VIDEO_INFO - sprintf (info, "%s (%s - %s) ", U_BOOT_VERSION, __DATE__, __TIME__); + sprintf (info, "%s (%s - %s) ", + U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME); video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, info); sprintf (info, "(C) 2002 DENX Software Engineering"); diff --git a/cpu/nios/start.S b/cpu/nios/start.S index 5d15e8d..3578a04 100644 --- a/cpu/nios/start.S +++ b/cpu/nios/start.S @@ -23,6 +23,7 @@ #include +#include #include #if !defined(CONFIG_IDENT_STRING) @@ -233,5 +234,5 @@ dly_clks: version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" diff --git a/cpu/nios2/start.S b/cpu/nios2/start.S index ea41435..31cd5b0 100644 --- a/cpu/nios2/start.S +++ b/cpu/nios2/start.S @@ -23,6 +23,7 @@ #include +#include #include /************************************************************************* @@ -212,5 +213,5 @@ dly_clks: version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index e68cf9b..4b5349e 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -63,6 +63,7 @@ */ #include #include +#include #include #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ @@ -510,7 +511,7 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/ .globl version_string version_string: .ascii U_BOOT_VERSION - .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET diff --git a/include/.gitignore b/include/.gitignore index ef7dd5f..4481412 100644 --- a/include/.gitignore +++ b/include/.gitignore @@ -5,4 +5,5 @@ /bmp_logo.h /config.h /config.mk +/timestamp_autogenerated.h /version_autogenerated.h diff --git a/include/configs/NETPHONE.h b/include/configs/NETPHONE.h index a147aff..34de947 100644 --- a/include/configs/NETPHONE.h +++ b/include/configs/NETPHONE.h @@ -799,7 +799,7 @@ typedef unsigned int led_id_t; #define CONFIG_CDP_DEVICE_ID_PREFIX "NP" /* netphone */ #define CONFIG_CDP_PORT_ID "eth%d" #define CONFIG_CDP_CAPABILITIES 0x00000010 -#define CONFIG_CDP_VERSION "u-boot" " " __DATE__ " " __TIME__ +#define CONFIG_CDP_VERSION "u-boot" " " U_BOOT_DATE " " U_BOOT_TIME #define CONFIG_CDP_PLATFORM "Intracom NetPhone" #define CONFIG_CDP_TRIGGER 0x20020001 #define CONFIG_CDP_POWER_CONSUMPTION 4300 /* 90 mA @ 48V */ diff --git a/include/configs/NETTA.h b/include/configs/NETTA.h index 63810b3..004b3c8 100644 --- a/include/configs/NETTA.h +++ b/include/configs/NETTA.h @@ -775,7 +775,7 @@ #define CONFIG_CDP_DEVICE_ID_PREFIX "NT" /* netta */ #define CONFIG_CDP_PORT_ID "eth%d" #define CONFIG_CDP_CAPABILITIES 0x00000010 -#define CONFIG_CDP_VERSION "u-boot 1.0" " " __DATE__ " " __TIME__ +#define CONFIG_CDP_VERSION "u-boot 1.0" " " U_BOOT_DATE " " U_BOOT_TIME #define CONFIG_CDP_PLATFORM "Intracom NetTA" #define CONFIG_CDP_TRIGGER 0x20020001 #define CONFIG_CDP_POWER_CONSUMPTION 4300 /* 90 mA @ 48V */ diff --git a/include/configs/NETTA2.h b/include/configs/NETTA2.h index 61c5547..70995fa 100644 --- a/include/configs/NETTA2.h +++ b/include/configs/NETTA2.h @@ -750,7 +750,7 @@ typedef unsigned int led_id_t; #define CONFIG_CDP_DEVICE_ID_PREFIX "NT" /* netta2 */ #define CONFIG_CDP_PORT_ID "eth%d" #define CONFIG_CDP_CAPABILITIES 0x00000010 -#define CONFIG_CDP_VERSION "u-boot" " " __DATE__ " " __TIME__ +#define CONFIG_CDP_VERSION "u-boot" " " U_BOOT_DATE " " U_BOOT_TIME #define CONFIG_CDP_PLATFORM "Intracom NetTA2" #define CONFIG_CDP_TRIGGER 0x20020001 #define CONFIG_CDP_POWER_CONSUMPTION 4300 /* 90 mA @ 48V */ diff --git a/include/timestamp.h b/include/timestamp.h new file mode 100644 index 0000000..b2f4cf4 --- /dev/null +++ b/include/timestamp.h @@ -0,0 +1,30 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __TIMESTAMP_H__ +#define __TIMESTAMP_H__ + +#ifndef DO_DEPS_ONLY +#include "timestamp_autogenerated.h" +#endif + +#endif /* __TIMESTAMP_H__ */ diff --git a/lib_arm/board.c b/lib_arm/board.c index 4ba1f5e..2358beb 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,7 @@ extern void dataflash_print_info(void); #endif const char version_string[] = - U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"CONFIG_IDENT_STRING; + U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING; #ifdef CONFIG_DRIVER_CS8900 extern void cs8900_get_enetaddr (uchar * addr); diff --git a/lib_avr32/board.c b/lib_avr32/board.c index 8771de9..2a98bd4 100644 --- a/lib_avr32/board.c +++ b/lib_avr32/board.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,7 @@ DECLARE_GLOBAL_DATA_PTR; const char version_string[] = - U_BOOT_VERSION " (" __DATE__ " - " __TIME__ ") " CONFIG_IDENT_STRING; + U_BOOT_VERSION " ("U_BOOT_DATE" - "U_BOOT_TIME") " CONFIG_IDENT_STRING; unsigned long monitor_flash_len; diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index e184fd2..fde4bbe 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,7 @@ int post_flag; DECLARE_GLOBAL_DATA_PTR; -const char version_string[] = U_BOOT_VERSION " (" __DATE__ " - " __TIME__ ")"; +const char version_string[] = U_BOOT_VERSION " ("U_BOOT_DATE" - "U_BOOT_TIME")"; __attribute__((always_inline)) static inline void serial_early_puts(const char *s) diff --git a/lib_i386/board.c b/lib_i386/board.c index 659f9a2..1734f86 100644 --- a/lib_i386/board.c +++ b/lib_i386/board.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ ulong i386boot_bios_size = (ulong)&_i386boot_bios_size; /* size of BIOS const char version_string[] = - U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"; + U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"; /* diff --git a/lib_microblaze/board.c b/lib_microblaze/board.c index cd61918..250972c 100644 --- a/lib_microblaze/board.c +++ b/lib_microblaze/board.c @@ -27,12 +27,13 @@ #include #include #include +#include #include #include DECLARE_GLOBAL_DATA_PTR; -const char version_string[] = U_BOOT_VERSION " (" __DATE__ " - " __TIME__ ")"; +const char version_string[] = U_BOOT_VERSION " ("U_BOOT_DATE" - "U_BOOT_TIME")"; #ifdef CONFIG_SYS_GPIO_0 extern int gpio_init (void); diff --git a/lib_mips/board.c b/lib_mips/board.c index 77e1cc8..9c997f1 100644 --- a/lib_mips/board.c +++ b/lib_mips/board.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ extern ulong uboot_end; ulong monitor_flash_len; const char version_string[] = - U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"; + U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"; static char *failed = "*** failed ***\n"; diff --git a/lib_sh/board.c b/lib_sh/board.c index b6be22e..d4cc85c 100644 --- a/lib_sh/board.c +++ b/lib_sh/board.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,7 @@ extern int board_init(void); extern int dram_init(void); extern int timer_init(void); -const char version_string[] = U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"; +const char version_string[] = U_BOOT_VERSION" ("U_BOOT_DATE" - "U_BOOT_TIME")"; unsigned long monitor_flash_len = CONFIG_SYS_MONITOR_LEN; diff --git a/net/net.c b/net/net.c index 77e83b5..e9754e4 100644 --- a/net/net.c +++ b/net/net.c @@ -89,6 +89,9 @@ #if defined(CONFIG_CMD_SNTP) #include "sntp.h" #endif +#if defined(CONFIG_CDP_VERSION) +#include +#endif #if defined(CONFIG_CMD_NET) -- cgit v1.1 From ace514837cac656e29c37a19569cb8ea83071126 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Fri, 31 Oct 2008 11:12:38 -0500 Subject: lcd: Let the board code show board-specific info cleanup remove unneeded version.h from lcd.c Signed-off-by: Peter Tyser Signed-off-by: Wolfgang Denk --- common/lcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/common/lcd.c b/common/lcd.c index 31bb190..ae79051 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From 0b2f4ecad473d785959c7976f20d2a00bd0ee01f Mon Sep 17 00:00:00 2001 From: Niklaus Giger Date: Mon, 3 Nov 2008 22:13:47 +0100 Subject: README: Document CONFIG_SYS parameters for vxworks Signed-off-by: Niklaus Giger --- README | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README b/README index 861ea83..2a553c2 100644 --- a/README +++ b/README @@ -381,6 +381,24 @@ The following options need to be configured: This define fills in the correct boot CPU in the boot param header, the default value is zero if undefined. +- vxWorks boot parameters: + + bootvx constructs a valid bootline using the following + environments variables: bootfile, ipaddr, serverip, hostname. + It loads the vxWorks image pointed bootfile. + + CONFIG_SYS_VXWORKS_BOOT_DEVICE - The vxworks device name + CONFIG_SYS_VXWORKS_MAC_PTR - Ethernet 6 byte MA -address + CONFIG_SYS_VXWORKS_SERVERNAME - Name of the server + CONFIG_SYS_VXWORKS_BOOT_ADDR - Address of boot parameters + + CONFIG_SYS_VXWORKS_ADD_PARAMS + + Add it at the end of the bootline. E.g "u=username pw=secret" + + Note: If a "bootargs" environment is defined, it will overwride + the defaults discussed just above. + - Serial Ports: CONFIG_PL010_SERIAL -- cgit v1.1 From e9084b23d16102f44ace24379a1c0c352497ef80 Mon Sep 17 00:00:00 2001 From: Niklaus Giger Date: Mon, 3 Nov 2008 22:14:36 +0100 Subject: Add vxworks.h to handle CONFIG_SYS_VXWORKS parameters Signed-off-by: Niklaus Giger --- include/vxworks.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 include/vxworks.h diff --git a/include/vxworks.h b/include/vxworks.h new file mode 100644 index 0000000..548e8e8 --- /dev/null +++ b/include/vxworks.h @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2008 + * Niklaus Giger, niklaus.giger@member.fsf.org + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _VXWORKS_H_ +#define _VXWORKS_H_ + +int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +/* + * Use bootaddr to find the location in memory that VxWorks + * will look for the bootline string. The default value for + * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which + * defaults to 0x4200 + */ +#ifndef CONFIG_SYS_VXWORKS_BOOT_ADDR +#define CONFIG_SYS_VXWORKS_BOOT_ADDR 0x4200 +#endif + +#ifndef CONFIG_SYS_VXWORKS_BOOT_DEVICE +#if defined(CONFIG_4xx) +#define CONFIG_SYS_VXWORKS_BOOT_DEVICE "emac(0,0)" +#elif defined(CONFIG_IOP480) +#define CONFIG_SYS_VXWORKS_BOOT_DEVICE "dc(0,0)" +#else +#define CONFIG_SYS_VXWORKS_BOOT_DEVICE "eth(0,0)" +#endif +#endif + +#ifndef CONFIG_SYS_VXWORKS_SERVERNAME +#define CONFIG_SYS_VXWORKS_SERVERNAME srv +#endif + +#endif -- cgit v1.1 From 29a4c24de99d8cb4ac32991c04cab87ed94ca1f9 Mon Sep 17 00:00:00 2001 From: Niklaus Giger Date: Mon, 3 Nov 2008 22:15:34 +0100 Subject: cmd_elf.c: Cleanup bootvx and handle new CONFIG_SYS_VXWORKS parameters - fix size too small by one in sprintf - changed old (pre 2004) device name ibmEmac to emac - boot device may be overriden in board config - servername may be defined in board config - additional parameters may be defined in board config - fixed some line wrappings - replaced redundant MAX define by max Signed-off-by: Niklaus Giger --- common/cmd_elf.c | 77 ++++++++++++++++++++++---------------------------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/common/cmd_elf.c b/common/cmd_elf.c index 4d8e1d2..27a4b73 100644 --- a/common/cmd_elf.c +++ b/common/cmd_elf.c @@ -18,6 +18,7 @@ #include #include #include +#include #if defined(CONFIG_WALNUT) || defined(CONFIG_SYS_VXWORKS_MAC_PTR) DECLARE_GLOBAL_DATA_PTR; @@ -98,13 +99,10 @@ int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) unsigned long bootaddr; /* Address to put the bootline */ char *bootline; /* Text of the bootline */ char *tmp; /* Temporary char pointer */ + char build_buf[128]; /* Buffer for building the bootline */ -#if defined(CONFIG_4xx) || defined(CONFIG_IOP480) - char build_buf[80]; /* Buffer for building the bootline */ -#endif - /* -------------------------------------------------- */ - - /* + /* --------------------------------------------------- + * * Check the loadaddr variable. * If we don't know where the image is then we're done. */ @@ -120,7 +118,8 @@ int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) { if (NetLoop (TFTP) <= 0) return 1; - printf ("Automatic boot of VxWorks image at address 0x%08lx ... \n", addr); + printf ("Automatic boot of VxWorks image at address 0x%08lx ... \n", + addr); } #endif @@ -148,7 +147,7 @@ int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ if ((tmp = getenv ("bootaddr")) == NULL) - bootaddr = 0x4200; + bootaddr = CONFIG_SYS_VXWORKS_BOOT_ADDR; else bootaddr = simple_strtoul (tmp, NULL, 16); @@ -159,54 +158,40 @@ int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ if ((bootline = getenv ("bootargs")) != NULL) { - memcpy ((void *) bootaddr, bootline, MAX(strlen(bootline), 255)); - flush_cache (bootaddr, MAX(strlen(bootline), 255)); + memcpy ((void *) bootaddr, bootline, + max (strlen (bootline), 255)); + flush_cache (bootaddr, max (strlen (bootline), 255)); } else { -#if defined(CONFIG_4xx) - sprintf (build_buf, "ibmEmac(0,0)"); - if ((tmp = getenv ("hostname")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "host:%s ", tmp); + + sprintf (build_buf, CONFIG_SYS_VXWORKS_BOOT_DEVICE); + if ((tmp = getenv ("bootfile")) != NULL) { + sprintf (&build_buf[strlen (build_buf)], + "%s:%s ", CONFIG_SYS_VXWORKS_SERVERNAME, tmp); } else { - sprintf (&build_buf[strlen (build_buf - 1)], - ": "); + sprintf (&build_buf[strlen (build_buf)], + "%s:file ", CONFIG_SYS_VXWORKS_SERVERNAME); } if ((tmp = getenv ("ipaddr")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "e=%s ", tmp); + sprintf (&build_buf[strlen (build_buf)], "e=%s ", tmp); } - memcpy ((void *)bootaddr, build_buf, MAX(strlen(build_buf), 255)); - flush_cache (bootaddr, MAX(strlen(build_buf), 255)); -#elif defined(CONFIG_IOP480) - sprintf (build_buf, "dc(0,0)"); - if ((tmp = getenv ("hostname")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "host:%s ", tmp); - } else { - sprintf (&build_buf[strlen (build_buf - 1)], - ": "); + if ((tmp = getenv ("serverip")) != NULL) { + sprintf (&build_buf[strlen (build_buf)], "h=%s ", tmp); } - if ((tmp = getenv ("ipaddr")) != NULL) { - sprintf (&build_buf[strlen (build_buf - 1)], - "e=%s ", tmp); + if ((tmp = getenv ("hostname")) != NULL) { + sprintf (&build_buf[strlen (build_buf)], "tn=%s ", tmp); } - memcpy ((void *) bootaddr, build_buf, MAX(strlen(build_buf), 255)); - flush_cache (bootaddr, MAX(strlen(build_buf), 255)); -#else - - /* - * I'm not sure what the device should be for other - * PPC flavors, the hostname and ipaddr should be ok - * to just copy - */ - - puts ("No bootargs defined\n"); - return 1; +#ifdef CONFIG_SYS_VXWORKS_ADD_PARAMS + sprintf (&build_buf[strlen (build_buf)], + CONFIG_SYS_VXWORKS_ADD_PARAMS); #endif + + memcpy ((void *) bootaddr, build_buf, + max (strlen (build_buf), 255)); + flush_cache (bootaddr, max (strlen (build_buf), 255)); } /* @@ -251,8 +236,7 @@ int valid_elf_image (unsigned long addr) } if (ehdr->e_type != ET_EXEC) { - printf ("## Not a 32-bit elf image at address 0x%08lx\n", - addr); + printf ("## Not a 32-bit elf image at address 0x%08lx\n", addr); return 0; } @@ -267,7 +251,6 @@ int valid_elf_image (unsigned long addr) return 1; } - /* ====================================================================== * A very simple elf loader, assumes the image is valid, returns the * entry point address. -- cgit v1.1 From b03150b52e3c491a86a3cc0945274f0e8f9872e7 Mon Sep 17 00:00:00 2001 From: Niklaus Giger Date: Mon, 3 Nov 2008 22:16:18 +0100 Subject: Use new CONFIG_SYS_VXWORKS parameters for Netstal boards Signed-off-by: Niklaus Giger --- include/configs/netstal-common.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/include/configs/netstal-common.h b/include/configs/netstal-common.h index 0a75794..4d5c1ab 100644 --- a/include/configs/netstal-common.h +++ b/include/configs/netstal-common.h @@ -202,8 +202,9 @@ #define CONFIG_ETHADDR 00:60:13:00:00:00 /* Netstal Machines AG MAC */ #define CONFIG_OVERWRITE_ETHADDR_ONCE -#define CONFIG_SYS_TFTP_LOADADDR 0x01000000 - +#define CONFIG_SYS_TFTP_LOADADDR 0x01000000 +#define CONFIG_SYS_VXWORKS_ADD_PARAMS "u=dpu pw=netstal8752" +#define CONFIG_SYS_VXWORKS_SERVERNAME "c" /* * General common environment variables shared by all boards produced by Netstal Maschinen */ @@ -223,19 +224,17 @@ "fdt_addr_r=800000\0" \ "hostname=" xstr(CONFIG_HOSTNAME) "\0" \ "bootfile=" xstr(CONFIG_HOSTNAME) "/uImage\0" \ - "load=tftp 200000 " xstr(CONFIG_HOSTNAME) "/u-boot.bin\0" \ - "update=protect off " xstr(CONFIG_SYS_MONITOR_BASE) " FFFFFFFF;" \ - "era " xstr(CONFIG_SYS_MONITOR_BASE) " FFFFFFFF;" \ - "cp.b ${fileaddr} " xstr(CONFIG_SYS_MONITOR_BASE) " ${filesize};" \ - "setenv filesize\0" \ - "upd=run load update\0" \ - "vx_rom=" xstr(CONFIG_HOSTNAME) "/" \ - xstr(CONFIG_HOSTNAME) "_vx_rom\0" \ - "vx=tftp " xstr(CONFIG_SYS_TFTP_LOADADDR) " ${vx_rom};run vxargs;" \ - "bootvx\0" \ - "vxargs=setenv bootargs emac(0,0)c:${vx_rom} e=${ipaddr}" \ - " h=${serverip} u=dpu pw=netstal8752 " \ - "tn=" xstr(CONFIG_HOSTNAME) " f=0x3008\0" \ + "uload=tftp " xstr(CONFIG_SYS_TFTP_LOADADDR) " " \ + xstr(CONFIG_HOSTNAME) "/u-boot.bin\0" \ + "vx_rom=" xstr(CONFIG_HOSTNAME) "/" \ + xstr(CONFIG_HOSTNAME) "_vx_rom\0" \ + "update=protect off " xstr(CONFIG_SYS_MONITOR_BASE) " FFFFFFFF;"\ + "era " xstr(CONFIG_SYS_MONITOR_BASE) " FFFFFFFF;" \ + "cp.b ${fileaddr} "xstr(CONFIG_SYS_MONITOR_BASE) \ + " ${filesize}; setenv filesize\0" \ + "upd=run uload update\0" \ + "vx=setenv bootfile ${vx_rom}; tftp " \ + xstr(CONFIG_SYS_TFTP_LOADADDR) "; bootvx\0" \ CONFIG_NETSTAL_DEF_ENV_ROOTPATH /* -- cgit v1.1 From 774ce72026f74ac9641bcbbc588b20f2e13f7ab8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 4 Nov 2008 16:03:46 -0500 Subject: strings: use puts() rather than printf() When running `strings` on really long strings, the stack tends to get smashed due to printf(). Switch to puts() instead since we're only passing the data through. Signed-off-by: Mike Frysinger --- common/cmd_strings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/cmd_strings.c b/common/cmd_strings.c index db54f29..7d05cf8 100644 --- a/common/cmd_strings.c +++ b/common/cmd_strings.c @@ -29,7 +29,8 @@ int do_strings(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *addr = start_addr; do { - printf("%s\n", addr); + puts(addr); + puts("\n"); addr += strlen(addr) + 1; } while (addr[0] && addr < last_addr); -- cgit v1.1 From 16a28ef219c27423a1ef502f19070c4d375079b8 Mon Sep 17 00:00:00 2001 From: Gary Jennejohn Date: Thu, 6 Nov 2008 15:04:23 +0100 Subject: IOMUX: Add console multiplexing support. Modifications to support console multiplexing. This is controlled using CONFIG_SYS_CONSOLE_MUX in the board configuration file. This allows a user to specify multiple console devices in the environment with a command like this: setenv stdin serial,nc. As a result, the user can enter text on both the serial and netconsole interfaces. All devices - stdin, stdout and stderr - can be set in this manner. 1) common/iomux.c and include/iomux.h contain the environment setting implementation. 2) doc/README.iomux contains a somewhat more detailed description. 3) The implementation in (1) is called from common/cmd_nvedit.c to handle setenv and from common/console.c to handle initialization of input/output devices at boot time. 4) common/console.c also contains the code needed to poll multiple console devices for input and send output to all devices registered for output. 5) include/common.h includes iomux.h and common/Makefile generates iomux.o when CONFIG_SYS_CONSOLE_MUX is set. Signed-off-by: Gary Jennejohn --- common/Makefile | 1 + common/cmd_nvedit.c | 6 ++ common/console.c | 156 +++++++++++++++++++++++++++++++++++++++++++++- common/iomux.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/README.iomux | 106 +++++++++++++++++++++++++++++++ include/common.h | 7 +++ include/iomux.h | 48 ++++++++++++++ 7 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 common/iomux.c create mode 100644 doc/README.iomux create mode 100644 include/iomux.h diff --git a/common/Makefile b/common/Makefile index 596fef3..93e3963 100644 --- a/common/Makefile +++ b/common/Makefile @@ -142,6 +142,7 @@ COBJS-$(CONFIG_VFD) += cmd_vfd.o # others COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o COBJS-$(CONFIG_CMD_DOC) += docecc.o +COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o COBJS-y += flash.o COBJS-y += kgdb.o COBJS-$(CONFIG_LCD) += lcd.o diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index d280cb0..85025da 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -213,6 +213,11 @@ int _do_setenv (int flag, int argc, char *argv[]) return 1; } +#ifdef CONFIG_CONSOLE_MUX + i = iomux_doenv(console, argv[2]); + if (i) + return i; +#else /* Try assigning specified device */ if (console_assign (console, argv[2]) < 0) return 1; @@ -221,6 +226,7 @@ int _do_setenv (int flag, int argc, char *argv[]) if (serial_assign (argv[2]) < 0) return 1; #endif +#endif /* CONFIG_CONSOLE_MUX */ } /* diff --git a/common/console.c b/common/console.c index 6f0846f..89aeab6 100644 --- a/common/console.c +++ b/common/console.c @@ -93,6 +93,76 @@ static int console_setfile (int file, device_t * dev) return error; } +#if defined(CONFIG_CONSOLE_MUX) +/** Console I/O multiplexing *******************************************/ + +static device_t *tstcdev; +device_t **console_devices[MAX_FILES]; +int cd_count[MAX_FILES]; + +/* + * This depends on tstc() always being called before getc(). + * This is guaranteed to be true because this routine is called + * only from fgetc() which assures it. + * No attempt is made to demultiplex multiple input sources. + */ +static int iomux_getc(void) +{ + unsigned char ret; + + /* This is never called with testcdev == NULL */ + ret = tstcdev->getc(); + tstcdev = NULL; + return ret; +} + +static int iomux_tstc(int file) +{ + int i, ret; + device_t *dev; + + disable_ctrlc(1); + for (i = 0; i < cd_count[file]; i++) { + dev = console_devices[file][i]; + if (dev->tstc != NULL) { + ret = dev->tstc(); + if (ret > 0) { + tstcdev = dev; + disable_ctrlc(0); + return ret; + } + } + } + disable_ctrlc(0); + + return 0; +} + +static void iomux_putc(int file, const char c) +{ + int i; + device_t *dev; + + for (i = 0; i < cd_count[file]; i++) { + dev = console_devices[file][i]; + if (dev->putc != NULL) + dev->putc(c); + } +} + +static void iomux_puts(int file, const char *s) +{ + int i; + device_t *dev; + + for (i = 0; i < cd_count[file]; i++) { + dev = console_devices[file][i]; + if (dev->puts != NULL) + dev->puts(s); + } +} +#endif /* defined(CONFIG_CONSOLE_MUX) */ + /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ void serial_printf (const char *fmt, ...) @@ -114,8 +184,31 @@ void serial_printf (const char *fmt, ...) int fgetc (int file) { - if (file < MAX_FILES) + if (file < MAX_FILES) { +#if defined(CONFIG_CONSOLE_MUX) + /* + * Effectively poll for input wherever it may be available. + */ + for (;;) { + /* + * Upper layer may have already called tstc() so + * check for that first. + */ + if (tstcdev != NULL) + return iomux_getc(); + iomux_tstc(file); +#ifdef CONFIG_WATCHDOG + /* + * If the watchdog must be rate-limited then it should + * already be handled in board-specific code. + */ + udelay(1); +#endif + } +#else return stdio_devices[file]->getc (); +#endif + } return -1; } @@ -123,7 +216,11 @@ int fgetc (int file) int ftstc (int file) { if (file < MAX_FILES) +#if defined(CONFIG_CONSOLE_MUX) + return iomux_tstc(file); +#else return stdio_devices[file]->tstc (); +#endif return -1; } @@ -131,13 +228,21 @@ int ftstc (int file) void fputc (int file, const char c) { if (file < MAX_FILES) +#if defined(CONFIG_CONSOLE_MUX) + iomux_putc(file, c); +#else stdio_devices[file]->putc (c); +#endif } void fputs (int file, const char *s) { if (file < MAX_FILES) +#if defined(CONFIG_CONSOLE_MUX) + iomux_puts(file, s); +#else stdio_devices[file]->puts (s); +#endif } void fprintf (int file, const char *fmt, ...) @@ -407,6 +512,9 @@ int console_init_r (void) #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE int i; #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ +#ifdef CONFIG_CONSOLE_MUX + int iomux_err = 0; +#endif /* set default handlers at first */ gd->jt[XF_getc] = serial_getc; @@ -425,6 +533,14 @@ int console_init_r (void) inputdev = search_device (DEV_FLAGS_INPUT, stdinname); outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname); errdev = search_device (DEV_FLAGS_OUTPUT, stderrname); +#ifdef CONFIG_CONSOLE_MUX + iomux_err = iomux_doenv(stdin, stdinname); + iomux_err += iomux_doenv(stdout, stdoutname); + iomux_err += iomux_doenv(stderr, stderrname); + if (!iomux_err) + /* Successful, so skip all the code below. */ + goto done; +#endif } /* if the devices are overwritten or not found, use default device */ if (inputdev == NULL) { @@ -438,15 +554,34 @@ int console_init_r (void) } /* Initializes output console first */ if (outputdev != NULL) { +#ifdef CONFIG_CONSOLE_MUX + /* need to set a console if not done above. */ + iomux_doenv(stdout, outputdev->name); +#else console_setfile (stdout, outputdev); +#endif } if (errdev != NULL) { +#ifdef CONFIG_CONSOLE_MUX + /* need to set a console if not done above. */ + iomux_doenv(stderr, errdev->name); +#else console_setfile (stderr, errdev); +#endif } if (inputdev != NULL) { +#ifdef CONFIG_CONSOLE_MUX + /* need to set a console if not done above. */ + iomux_doenv(stdin, inputdev->name); +#else console_setfile (stdin, inputdev); +#endif } +#ifdef CONFIG_CONSOLE_MUX +done: +#endif + gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET @@ -455,21 +590,33 @@ int console_init_r (void) if (stdio_devices[stdin] == NULL) { puts ("No input devices available!\n"); } else { +#ifdef CONFIG_CONSOLE_MUX + iomux_printdevs(stdin); +#else printf ("%s\n", stdio_devices[stdin]->name); +#endif } puts ("Out: "); if (stdio_devices[stdout] == NULL) { puts ("No output devices available!\n"); } else { +#ifdef CONFIG_CONSOLE_MUX + iomux_printdevs(stdout); +#else printf ("%s\n", stdio_devices[stdout]->name); +#endif } puts ("Err: "); if (stdio_devices[stderr] == NULL) { puts ("No error devices available!\n"); } else { +#ifdef CONFIG_CONSOLE_MUX + iomux_printdevs(stderr); +#else printf ("%s\n", stdio_devices[stderr]->name); +#endif } #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ @@ -524,11 +671,18 @@ int console_init_r (void) if (outputdev != NULL) { console_setfile (stdout, outputdev); console_setfile (stderr, outputdev); +#ifdef CONFIG_CONSOLE_MUX + console_devices[stdout][0] = outputdev; + console_devices[stderr][0] = outputdev; +#endif } /* Initializes input console */ if (inputdev != NULL) { console_setfile (stdin, inputdev); +#ifdef CONFIG_CONSOLE_MUX + console_devices[stdin][0] = inputdev; +#endif } gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ diff --git a/common/iomux.c b/common/iomux.c new file mode 100644 index 0000000..bdcc853 --- /dev/null +++ b/common/iomux.c @@ -0,0 +1,175 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_CONSOLE_MUX +void iomux_printdevs(const int console) +{ + int i; + device_t *dev; + + for (i = 0; i < cd_count[console]; i++) { + dev = console_devices[console][i]; + printf("%s ", dev->name); + } + printf("\n"); +} + +/* This tries to preserve the old list if an error occurs. */ +int iomux_doenv(const int console, const char *arg) +{ + char *console_args, *temp, **start; + int i, j, k, io_flag, cs_idx, repeat; + device_t *dev; + device_t **cons_set; + + console_args = strdup(arg); + if (console_args == NULL) + return 1; + /* + * Check whether a comma separated list of devices was + * entered and count how many devices were entered. + * The array start[] has pointers to the beginning of + * each device name (up to MAX_CONSARGS devices). + * + * Have to do this twice - once to count the number of + * commas and then again to populate start. + */ + i = 0; + temp = console_args; + for (;;) { + temp = strchr(temp, ','); + if (temp != NULL) { + i++; + temp++; + continue; + } + /* There's always one entry more than the number of commas. */ + i++; + break; + } + start = (char **)malloc(i * sizeof(char *)); + if (start == NULL) { + free(console_args); + return 1; + } + i = 0; + start[0] = console_args; + for (;;) { + temp = strchr(start[i++], ','); + if (temp == NULL) + break; + *temp = '\0'; + start[i] = temp + 1; + } + cons_set = (device_t **)calloc(i, sizeof(device_t *)); + if (cons_set == NULL) { + free(start); + free(console_args); + return 1; + } + + switch (console) { + case stdin: + io_flag = DEV_FLAGS_INPUT; + break; + case stdout: + case stderr: + io_flag = DEV_FLAGS_OUTPUT; + break; + default: + free(start); + free(console_args); + free(cons_set); + return 1; + } + + cs_idx = 0; + for (j = 0; j < i; j++) { + /* + * Check whether the device exists and is valid. + * console_assign() also calls search_device(), + * but I need the pointer to the device. + */ + dev = search_device(io_flag, start[j]); + if (dev == NULL) + continue; + /* + * Prevent multiple entries for a device. + */ + repeat = 0; + for (k = 0; k < cs_idx; k++) { + if (dev == cons_set[k]) { + repeat++; + break; + } + } + if (repeat) + continue; + /* + * Try assigning the specified device. + * This could screw up the console settings for apps. + */ + if (console_assign(console, start[j]) < 0) + continue; +#ifdef CONFIG_SERIAL_MULTI + /* + * This was taken from common/cmd_nvedit.c. + * This will never work because serial_assign() returns + * 1 upon error, not -1. + * This would almost always return an error anyway because + * serial_assign() expects the name of a serial device, like + * serial_smc, but the user generally only wants to set serial. + */ + if (serial_assign(start[j]) < 0) + continue; +#endif + cons_set[cs_idx++] = dev; + } + free(console_args); + free(start); + /* failed to set any console */ + if (cs_idx == 0) { + free(cons_set); + return 1; + } else { + /* Works even if console_devices[console] is NULL. */ + console_devices[console] = + (device_t **)realloc(console_devices[console], + cs_idx * sizeof(device_t *)); + if (console_devices[console] == NULL) { + free(cons_set); + return 1; + } + memcpy(console_devices[console], cons_set, cs_idx * + sizeof(device_t *)); + + cd_count[console] = cs_idx; + } + free(cons_set); + return 0; +} +#endif /* CONFIG_CONSOLE_MUX */ diff --git a/doc/README.iomux b/doc/README.iomux new file mode 100644 index 0000000..5b82a86 --- /dev/null +++ b/doc/README.iomux @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +U-Boot console multiplexing +=========================== + +HOW CONSOLE MULTIPLEXING WORKS +------------------------------ + +This functionality is controlled with CONFIG_CONSOLE_MUX in the board +configuration file. + +Two new files, common/iomux.c and include/iomux.h, contain the heart +(iomux_doenv()) of the environment setting implementation. + +iomux_doenv() is called in common/cmd_nvedit.c to handle setenv and in +common/console.c in console_init_r() during bootup to initialize +stdio_devices[]. + +A user can use a comma-separated list of devices to set stdin, stdout +and stderr. For example: "setenv stdin serial,nc". NOTE: No spaces +are allowed around the comma(s)! + +The length of the list is limited by malloc(), since the array used +is allocated and freed dynamically. + +It should be possible to specify any device which console_assign() +finds acceptable, but the code has only been tested with serial and +nc. + +iomux_doenv() prevents multiple use of the same device, e.g. "setenv +stdin nc,nc,serial" will discard the second nc. iomux_doenv() is +not able to modify the environment, however, so that "pri stdin" still +shows "nc,nc,serial". + +The major change in common/console.c was to modify fgetc() to call +the iomux_tstc() routine in a for-loop. iomux_tstc() in turn calls +the tstc() routine for every registered device, but exits immediately +when one of them returns true. fgetc() then calls iomux_getc(), +which calls the corresponding getc() routine. fgetc() hangs in +the for-loop until iomux_tstc() returns true and the input can be +retrieved. + +Thus, a user can type into any device registered for stdin. No effort +has been made to demulitplex simultaneous input from multiple stdin +devices. + +fputc() and fputs() have been modified to call iomux_putc() and +iomux_puts() respectively, which call the corresponding output +routines for every registered device. + +Thus, a user can see the ouput for any device registered for stdout +or stderr on all devices registered for stdout or stderr. As an +example, if stdin=serial,nc and stdout=serial,nc then all output +for serial, e.g. echos of input on serial, will appear on serial and nc. + +Just as with the old console code, this statement is still true: +If not defined in the environment, the first input device is assigned +to the 'stdin' file, the first output one to 'stdout' and 'stderr'. + +If CONFIG_SYS_CONSOLE_IS_IN_ENV is defined then multiple input/output +devices can be set at boot time if defined in the environment. + +CAVEATS +------- + +Note that common/iomux.c calls console_assign() for every registered +device as it is discovered. This means that the environment settings +for application consoles will be set to the last device in the list. + +On a slow machine, such as MPC852T clocked at 66MHz, the overhead associated +with calling tstc() and then getc() means that copy&paste will normally not +work, even when stdin=stdout=stderr=serial. +On a faster machine, such as a sequoia, cut&paste of longer (about 80 +characters) lines works fine when serial is the only device used. + +Using nc as a stdin device results in even more overhead because nc_tstc() +is quite slow. Even on a sequoia cut&paste does not work on the serial +interface when nc is added to stdin, although there is no character loss using +the ethernet interface for input. In this test case stdin=serial,nc and +stdout=serial. + +In addition, the overhead associated with sending to two devices, when one of +them is nc, also causes problems. Even on a sequoia cut&paste does not work +on the serial interface (stdin=serial) when nc is added to stdout (stdout= +serial,nc). diff --git a/include/common.h b/include/common.h index df64bf0..5968036 100644 --- a/include/common.h +++ b/include/common.h @@ -678,6 +678,13 @@ void fputc(int file, const char c); int ftstc(int file); int fgetc(int file); +/* + * CONSOLE multiplexing. + */ +#ifdef CONFIG_CONSOLE_MUX +#include +#endif + int pcmcia_init (void); #ifdef CONFIG_STATUS_LED diff --git a/include/iomux.h b/include/iomux.h new file mode 100644 index 0000000..257c1f7 --- /dev/null +++ b/include/iomux.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + *This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _IO_MUX_H +#define _IO_MUX_H + +#include + +/* + * Stuff required to support console multiplexing. + */ + +/* + * Pointers to devices used for each file type. Defined in console.c + * but storage is allocated in iomux.c. + */ +extern device_t **console_devices[MAX_FILES]; +/* + * The count of devices assigned to each FILE. Defined in console.c + * and populated in iomux.c. + */ +extern int cd_count[MAX_FILES]; + +int iomux_doenv(const int, const char *); +void iomux_printdevs(const int); +device_t *search_device(int, char *); + +#endif /* _IO_MUX_H */ -- cgit v1.1 From bcdf1d2cf6b24fb905fd7da80da4b3c65a7995b5 Mon Sep 17 00:00:00 2001 From: Richard Retanubun Date: Thu, 6 Nov 2008 14:01:51 -0500 Subject: common/cmd_ide.c: Corrected endian order printing for compact flash serial number. Corrected endian order printing for compact flash serial number. Signed-off-by: Richard Retanubun --- common/cmd_ide.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 2564c2b..db05f76 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -1166,15 +1166,16 @@ static void ide_ident (block_dev_desc_t *dev_desc) ident_cpy ((unsigned char*)dev_desc->product, iop->serial_no, sizeof(dev_desc->product)); #ifdef __LITTLE_ENDIAN /* - * firmware revision and model number have Big Endian Byte - * order in Word. Convert both to little endian. + * firmware revision, model, and serial number have Big Endian Byte + * order in Word. Convert all three to little endian. * * See CF+ and CompactFlash Specification Revision 2.0: - * 6.2.1.6: Identfy Drive, Table 39 for more details + * 6.2.1.6: Identify Drive, Table 39 for more details */ strswab (dev_desc->revision); strswab (dev_desc->vendor); + strswab (dev_desc->product); #endif /* __LITTLE_ENDIAN */ if ((iop->config & 0x0080)==0x0080) -- cgit v1.1 From 1cb82a9207a550557399eabc7fe47f21bbd9ddf8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 7 Nov 2008 22:46:22 +0100 Subject: drivers/bios_emulator: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/bios_emulator/Makefile | 3 ++- drivers/bios_emulator/atibios.c | 5 ----- drivers/bios_emulator/besys.c | 4 ---- drivers/bios_emulator/bios.c | 4 ---- drivers/bios_emulator/biosemu.c | 4 ---- drivers/bios_emulator/x86emu/debug.c | 5 ----- drivers/bios_emulator/x86emu/decode.c | 5 ----- drivers/bios_emulator/x86emu/ops.c | 5 ----- drivers/bios_emulator/x86emu/ops2.c | 5 ----- drivers/bios_emulator/x86emu/prim_ops.c | 5 ----- drivers/bios_emulator/x86emu/sys.c | 5 ----- 11 files changed, 2 insertions(+), 48 deletions(-) diff --git a/drivers/bios_emulator/Makefile b/drivers/bios_emulator/Makefile index 90c64da..c73da97 100644 --- a/drivers/bios_emulator/Makefile +++ b/drivers/bios_emulator/Makefile @@ -6,7 +6,7 @@ X86DIR = x86emu $(shell mkdir -p $(obj)$(X86DIR)) -COBJS = atibios.o biosemu.o besys.o bios.o \ +COBJS-$(CONFIG_BIOSEMU) = atibios.o biosemu.o besys.o bios.o \ $(X86DIR)/decode.o \ $(X86DIR)/ops2.o \ $(X86DIR)/ops.o \ @@ -14,6 +14,7 @@ COBJS = atibios.o biosemu.o besys.o bios.o \ $(X86DIR)/sys.o \ $(X86DIR)/debug.o +COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 5779f99..d950b18 100644 --- a/drivers/bios_emulator/atibios.c +++ b/drivers/bios_emulator/atibios.c @@ -46,9 +46,6 @@ * BIOS in u-boot. ****************************************************************************/ #include - -#ifdef CONFIG_BIOSEMU - #include "biosemui.h" #include @@ -336,5 +333,3 @@ int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp) *pVGAInfo = VGAInfo; return true; } - -#endif diff --git a/drivers/bios_emulator/besys.c b/drivers/bios_emulator/besys.c index cb1b0c1..cbc5062 100644 --- a/drivers/bios_emulator/besys.c +++ b/drivers/bios_emulator/besys.c @@ -48,9 +48,6 @@ ****************************************************************************/ #include - -#if defined(CONFIG_BIOSEMU) - #include "biosemui.h" /*------------------------- Global Variables ------------------------------*/ @@ -721,4 +718,3 @@ void X86API BE_outl(X86EMU_pioAddr port, u32 val) #endif LOG_outpd(port, val); } -#endif diff --git a/drivers/bios_emulator/bios.c b/drivers/bios_emulator/bios.c index d41511c..edda276 100644 --- a/drivers/bios_emulator/bios.c +++ b/drivers/bios_emulator/bios.c @@ -42,9 +42,6 @@ ****************************************************************************/ #include - -#if defined(CONFIG_BIOSEMU) - #include "biosemui.h" /*----------------------------- Implementation ----------------------------*/ @@ -323,4 +320,3 @@ void _BE_bios_init(u32 * intrTab) bios_intr_tab[0x6D] = int10; X86EMU_setupIntrFuncs(bios_intr_tab); } -#endif diff --git a/drivers/bios_emulator/biosemu.c b/drivers/bios_emulator/biosemu.c index decdb79..d0c6521 100644 --- a/drivers/bios_emulator/biosemu.c +++ b/drivers/bios_emulator/biosemu.c @@ -47,9 +47,6 @@ #include #include - -#if defined(CONFIG_BIOSEMU) - #include "biosemui.h" BE_sysEnv _BE_env = {{0}}; @@ -372,4 +369,3 @@ int X86API BE_int86x(int intno, RMREGS * in, RMREGS * out, RMSREGS * sregs) sregs->gs = M.x86.R_GS; return out->x.ax; } -#endif diff --git a/drivers/bios_emulator/x86emu/debug.c b/drivers/bios_emulator/x86emu/debug.c index 29fe3f1..241acf3 100644 --- a/drivers/bios_emulator/x86emu/debug.c +++ b/drivers/bios_emulator/x86emu/debug.c @@ -39,9 +39,6 @@ #include #include - -#if defined(CONFIG_BIOSEMU) - #include "x86emu/x86emui.h" /*----------------------------- Implementation ----------------------------*/ @@ -463,5 +460,3 @@ void x86emu_dump_xregs(void) printk("NC "); printk("\n"); } - -#endif diff --git a/drivers/bios_emulator/x86emu/decode.c b/drivers/bios_emulator/x86emu/decode.c index 7a9a1dd..a782b81 100644 --- a/drivers/bios_emulator/x86emu/decode.c +++ b/drivers/bios_emulator/x86emu/decode.c @@ -37,9 +37,6 @@ * ****************************************************************************/ #include - -#if defined(CONFIG_BIOSEMU) - #include "x86emu/x86emui.h" /*----------------------------- Implementation ----------------------------*/ @@ -1145,5 +1142,3 @@ unsigned decode_rmXX_address(int mod, int rm) return decode_rm01_address(rm); return decode_rm10_address(rm); } - -#endif diff --git a/drivers/bios_emulator/x86emu/ops.c b/drivers/bios_emulator/x86emu/ops.c index 10f2757..d63c99f 100644 --- a/drivers/bios_emulator/x86emu/ops.c +++ b/drivers/bios_emulator/x86emu/ops.c @@ -76,9 +76,6 @@ ****************************************************************************/ #include - -#if defined(CONFIG_BIOSEMU) - #include "x86emu/x86emui.h" /*----------------------------- Implementation ----------------------------*/ @@ -5434,5 +5431,3 @@ void (*x86emu_optab[256])(u8) __attribute__ ((section(GOT2_TYPE))) = /* 0xfe */ x86emuOp_opcFE_byte_RM, /* 0xff */ x86emuOp_opcFF_word_RM, }; - -#endif diff --git a/drivers/bios_emulator/x86emu/ops2.c b/drivers/bios_emulator/x86emu/ops2.c index d90d366..51e20e1 100644 --- a/drivers/bios_emulator/x86emu/ops2.c +++ b/drivers/bios_emulator/x86emu/ops2.c @@ -45,9 +45,6 @@ ****************************************************************************/ #include - -#if defined(CONFIG_BIOSEMU) - #include "x86emu/x86emui.h" /*----------------------------- Implementation ----------------------------*/ @@ -1772,5 +1769,3 @@ void (*x86emu_optab2[256])(u8) __attribute__((section(GOT2_TYPE))) = /* 0xfe */ x86emuOp2_illegal_op, /* 0xff */ x86emuOp2_illegal_op, }; - -#endif diff --git a/drivers/bios_emulator/x86emu/prim_ops.c b/drivers/bios_emulator/x86emu/prim_ops.c index 2a254a4..7553087 100644 --- a/drivers/bios_emulator/x86emu/prim_ops.c +++ b/drivers/bios_emulator/x86emu/prim_ops.c @@ -100,9 +100,6 @@ #include #define PRIM_OPS_NO_REDEFINE_ASM - -#if defined(CONFIG_BIOSEMU) - #include "x86emu/x86emui.h" /*------------------------- Global Variables ------------------------------*/ @@ -2448,5 +2445,3 @@ DB( if (CHECK_SP_ACCESS()) M.x86.R_SP += 4; return res; } - -#endif diff --git a/drivers/bios_emulator/x86emu/sys.c b/drivers/bios_emulator/x86emu/sys.c index dd44ff1..21f9730 100644 --- a/drivers/bios_emulator/x86emu/sys.c +++ b/drivers/bios_emulator/x86emu/sys.c @@ -40,9 +40,6 @@ ****************************************************************************/ #include - -#if defined(CONFIG_BIOSEMU) - #include "x86emu/x86emui.h" /*------------------------- Global Variables ------------------------------*/ @@ -324,5 +321,3 @@ void X86EMU_prepareForInt(int num) M.x86.R_IP = mem_access_word(num * 4); M.x86.intr = 0; } - -#endif -- cgit v1.1 From 135f5534538bb8ea4f38a7030da12187d22ef7e0 Mon Sep 17 00:00:00 2001 From: Gary Jennejohn Date: Sun, 9 Nov 2008 12:36:15 +0100 Subject: keymile add the common parts of the HDLC driver This implements the ICN protocol used across the backplane and is needed by all the keymile boards. Signed-off-by: Gary Jennejohn --- board/keymile/common/keymile_hdlc_enet.c | 620 +++++++++++++++++++++++++++++++ board/keymile/common/keymile_hdlc_enet.h | 129 +++++++ 2 files changed, 749 insertions(+) create mode 100644 board/keymile/common/keymile_hdlc_enet.c create mode 100644 board/keymile/common/keymile_hdlc_enet.h diff --git a/board/keymile/common/keymile_hdlc_enet.c b/board/keymile/common/keymile_hdlc_enet.c new file mode 100644 index 0000000..141371b --- /dev/null +++ b/board/keymile/common/keymile_hdlc_enet.c @@ -0,0 +1,620 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. + * + * Based in part on cpu/mpc8260/ether_scc.c. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_KEYMILE_HDLC_ENET +#ifdef TEST_IT +#include +#endif + +#include "keymile_hdlc_enet.h" + +extern char keymile_slot; /* our slot number in the backplane */ + +/* Allow up to about 50 ms for sending */ +#define TOUT_LOOP 50000 + +/* + * Since, except during initialization, ethact is always HDLC ETHERNET + * while we're in the driver, just use serial_printf() everywhere for + * output. This avoids possible conflicts when netconsole is being + * used. + */ +#define dprintf(fmt, args...) serial_printf(fmt, ##args) + +/* Cannot use the storage from net.c because we allocate larger buffers */ +static volatile uchar MyPktBuf[HDLC_PKTBUFSRX * PKT_MAXBLR_SIZE + PKTALIGN]; +static volatile uchar *MyRxPackets[HDLC_PKTBUFSRX]; /* Receive packet */ + +static unsigned int keymile_rxIdx; /* index of the current RX buffer */ + +static IPaddr_t cachedNumbers[CACHEDNUMBERS]; /* 4 bytes per entry */ +void initCachedNumbers(int); + +/* + * SCC Ethernet Tx and Rx buffer descriptors allocated at the + * immr->udata_bd address on Dual-Port RAM + * Provide for Double Buffering + */ +typedef volatile struct CommonBufferDescriptor { + cbd_t txbd; /* Tx BD */ + cbd_t rxbd[HDLC_PKTBUFSRX]; /* Rx BD */ +} RTXBD; + +/* + * This must be extern because it is allocated in DPRAM using CPM-sepcific + * code. + */ +static RTXBD *rtx; + +static int keymile_hdlc_enet_send(struct eth_device *, volatile void *, int); +static int keymile_hdlc_enet_recv(struct eth_device *); +void keymile_hdlc_enet_init_bds(RTXBD *); +extern int keymile_hdlc_enet_init(struct eth_device *, bd_t *); +extern void keymile_hdlc_enet_halt(struct eth_device *); + +/* flags in the buffer descriptor not defined anywhere else */ +#define BD_SC_CT BD_SC_CD +#define BD_SC_CR 0x04 +#define BD_SC_DE 0x80 +#ifndef BD_SC_TC +#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */ +#endif +#define BD_SC_FIRST BD_SC_TC +#define BD_SC_STATS (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_CR | BD_SC_CD \ + | BD_SC_OV | BD_SC_DE) + +#if defined(TEST_RX) || defined(TEST_TX) || defined(TEST_IT) +static void hexdump(unsigned char *buf, int len) +{ + int i; + const int bytesPerLine = 32; + + if (len > 4 * bytesPerLine) + len = 4 * bytesPerLine; + dprintf("\t address: %08x\n", (unsigned int)buf); + for (i = 0; i < len; i++) { + if (i % bytesPerLine == 0) + dprintf("%04x: ", (unsigned short)i); + dprintf("%02x ", buf[i]); + if ((i + 1) % bytesPerLine == 0) { + dprintf("\n"); + continue; + } + if ((i + 1) % 8 == 0) + printf(" "); + } + if (len % bytesPerLine) + dprintf("\n"); +} +#endif + +int keymile_hdlc_enet_initialize(bd_t *bis) +{ + struct eth_device *dev; + + dev = (struct eth_device *) malloc(sizeof *dev); + memset(dev, 0, sizeof *dev); +#ifdef TEST_IT + seth = dev; +#endif + + sprintf(dev->name, "HDLC ETHERNET"); + dev->init = keymile_hdlc_enet_init; + dev->halt = keymile_hdlc_enet_halt; + dev->send = keymile_hdlc_enet_send; + dev->recv = keymile_hdlc_enet_recv; + + eth_register(dev); + + return 1; +} + +/* + * This is called from the board-specific driver after rtx is allocated. + */ +void keymile_hdlc_enet_init_bds(RTXBD *board_rtx) +{ + volatile cbd_t *bdp; + int i; + + rtx = board_rtx; + keymile_rxIdx = 0; + /* + * Initialize the buffer descriptors. + */ + bdp = &rtx->txbd; + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp->cbd_sc = BD_SC_WRAP; + + /* + * Setup RX packet buffers, aligned correctly. + * Borrowed from net/net.c. + */ + MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1); + MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN; + for (i = 1; i < HDLC_PKTBUFSRX; i++) + MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE; + + bdp = &rtx->rxbd[0]; + for (i = 0; i < HDLC_PKTBUFSRX; i++) { + bdp->cbd_sc = BD_SC_EMPTY; + /* Leave space at the start for INET header. */ + bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] + + INET_HDR_ALIGN); + bdp++; + } + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; +} + +/* + * This returns the current port number for NETCONSOLE. If nc_port + * in netconsole.c weren't declared static we wouldn't need this. + */ +static short get_netcons_port(void) +{ + char *p; + short nc_port; + + nc_port = 6666; /* default */ + + p = getenv("ncip"); + if (p != NULL) { + p = strchr(p, ':'); + if (p != NULL) + nc_port = simple_strtoul(p + 1, NULL, 10); + } + + return htons(nc_port); +} + +/* + * Read the port numbers from the variables + */ +void initCachedNumbers(int verbose) +{ + char *str; + ushort port; + + /* already in network order */ + cachedNumbers[IP_ADDR] = getenv_IPaddr("ipaddr"); + /* already in network order */ + cachedNumbers[IP_SERVER] = getenv_IPaddr("serverip"); + str = getenv("tftpsrcp"); + if (str != NULL) { + /* avoid doing htons() again and again */ + port = htons((ushort)simple_strtol(str, NULL, 10)); + cachedNumbers[TFTP_SRC_PORT] = port; + } else + /* this can never be a valid port number */ + cachedNumbers[TFTP_SRC_PORT] = (ulong)-1; + str = getenv("tftpdstp"); + if (str != NULL) { + /* avoid doing htons() again and again */ + port = htons((ushort)simple_strtol(str, NULL, 10)); + cachedNumbers[TFTP_DST_PORT] = port; + } else + /* this is the default value */ + cachedNumbers[TFTP_DST_PORT] = htons(WELL_KNOWN_PORT); + /* already in network order */ + cachedNumbers[NETCONS_PORT] = get_netcons_port(); + if (verbose) { + dprintf("\nIP Number Initialization:\n"); + dprintf(" ip address %08lx\n", cachedNumbers[IP_ADDR]); + dprintf(" server ip address %08lx\n", + cachedNumbers[IP_SERVER]); + dprintf(" tftp client port %ld\n", + cachedNumbers[TFTP_SRC_PORT]); + dprintf(" tftp server port %ld\n", + cachedNumbers[TFTP_DST_PORT]); + dprintf(" netcons port %ld\n", + cachedNumbers[NETCONS_PORT]); + dprintf(" slot number (hex) %02x\n", keymile_slot); + } +} + +static void keymile_hdlc_enet_doarp(volatile void *packet, int len) +{ + ARP_t *arp; + IPaddr_t src_ip; /* U-Boot's IP */ + IPaddr_t dest_ip; /* the mgcoge's IP */ + unsigned char *packet_copy = malloc(len); + + /* + * Handling an ARP request means that a new transfer has started. + * Update our cached parameters now. + */ + initCachedNumbers(0); /* may reinit port numbers */ + + /* special handling required for ARP */ + arp = (ARP_t *)(packet + ETHER_HDR_SIZE); + /* + * XXXX + * This is pretty dirty! NetReceive only uses + * a few fields when handling an ARP reply, so + * we only modify those here. This could + * result in catastrophic failure at a later + * time if the handler is modified! + */ + arp->ar_op = htons(ARPOP_REPLY); + /* save his/our IP */ + src_ip = NetReadIP(&arp->ar_data[6]); + dest_ip = NetReadIP(&arp->ar_data[16]); + /* copy target IP to source IP */ + NetCopyIP(&arp->ar_data[6], &dest_ip); + /* copy our IP to the right place */ + NetCopyIP(&arp->ar_data[16], &src_ip); + /* always use 0x7f as the MAC for the coge */ + arp->ar_data[0] = HDLC_UACUA; + /* + * copy the packet + * if NetReceive wants to write to stdout, it may overwrite packet + * especially if stdout is set to nc! + * + * However, if the malloc() above fails then we can still try the + * original packet, rather than causing the transfer to fail. + */ + if (packet_copy != NULL) { + memcpy(packet_copy, (char *)packet, len); + NetReceive(packet_copy, len); + free(packet_copy); + } else + NetReceive(packet, len); +} + +/* + * NOTE all callers ignore the returned value! + * At the moment this only handles ARP Requests, TFTP and NETCONSOLE. + */ +static int keymile_hdlc_enet_send(struct eth_device *dev, volatile void *packet, + int len) +{ + int j; + uint data_addr; + int data_len; + struct icn_hdr header; + struct icn_frame *frame; + Ethernet_t *et; + ARP_t *arp; + IP_t *ip; + + if (len > (MAX_FRAME_LENGTH - sizeof(header))) + return -1; + + frame = NULL; + et = NULL; + arp = NULL; + ip = NULL; + + j = 0; + while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) { + /* will also trigger Wd if needed, but maybe too often */ + udelay(1); + j++; + } + if (j >= TOUT_LOOP) { + dprintf("TX not ready sc %x\n", rtx->txbd.cbd_sc); + return -1; + } + + /* + * First check for an ARP Request since this requires special handling. + */ + if (len >= (ARP_HDR_SIZE + ETHER_HDR_SIZE)) { + et = (Ethernet_t *)packet; + arp = (ARP_t *)(((char *)et) + ETHER_HDR_SIZE); + /* ARP and REQUEST? */ + if (et->et_protlen == PROT_ARP && + arp->ar_op == htons(ARPOP_REQUEST)) { + /* just short-circuit the request on the U-Boot side */ + keymile_hdlc_enet_doarp(packet, len); + return 0; + } + } + + /* + * GJ - I suppose the assumption here that len will always be + * > INET_HDR_SIZE is alright as long as the network stack + * isn't changed. + * Do not send INET header. + */ + data_len = len + sizeof(header) - INET_HDR_SIZE; + frame = (struct icn_frame *) (((char *)packet) + INET_HDR_SIZE - + sizeof(header)); + +#ifdef TEST_TX + printf("frame: %08x, ", frame); + hexdump((unsigned char *)packet, data_len + INET_HDR_SIZE); +#endif + + data_addr = (uint)frame; + if (len >= (IP_HDR_SIZE + ETHER_HDR_SIZE)) + ip = (IP_t *)(packet + ETHER_HDR_SIZE); + /* Is it TFTP? TFTP always uses UDP and the cached dport */ + if (ip != NULL && ip->ip_p == IPPROTO_UDP && ip->udp_dst == + (ushort)cachedNumbers[TFTP_DST_PORT]) { + /* just in case the port wasn't set in the environment */ + if (cachedNumbers[TFTP_SRC_PORT] == (ulong)-1) + cachedNumbers[TFTP_SRC_PORT] = ip->udp_src; + frame->hdr.application = MGS_TFTP; + } + /* + * Is it NETCONSOLE? NETCONSOLE always uses UDP. + */ + else if (ip != NULL && ip->ip_p == IPPROTO_UDP + && ip->udp_dst == (ushort)cachedNumbers[NETCONS_PORT]) { + frame->hdr.application = MGS_NETCONS; + } else { + /* reject unknown packets */ + /* may do some check on frame->hdr.application */ + dprintf("Unknown packet type in %s, rejected\n", + __func__); + return -1; + } + /* + * Could extract the target's slot ID from its MAC here, + * but u-boot only wants to talk to the active server. + * + * avoid setting new source address when moving to another slot + */ + frame->hdr.src_addr = keymile_slot; + frame->hdr.dest_addr = HDLC_UACUA; +#ifdef TEST_TX + { + dprintf("TX: "); + hexdump((unsigned char *)data_addr, data_len); + } +#endif + + flush_cache(data_addr, data_len); + rtx->txbd.cbd_bufaddr = data_addr; + rtx->txbd.cbd_datlen = data_len; + rtx->txbd.cbd_sc |= (BD_SC_READY | BD_SC_TC | BD_SC_LAST | BD_SC_WRAP); + + while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) { + /* will also trigger Wd if needed, but maybe too often */ + udelay(1); + j++; + } + if (j >= TOUT_LOOP) + dprintf("TX timeout\n"); +#ifdef ET_DEBUG + dprintf("cycles: %d status: %x\n", j, rtx->txbd.cbd_sc); +#endif + j = (rtx->txbd.cbd_sc & BD_SC_STATS); /* return only status bits */ + return j; +} + +/* + * During a receive, the RxIdx points to the current incoming buffer. + * When we update through the ring, if the next incoming buffer has + * not been given to the system, we just set the empty indicator, + * effectively tossing the packet. + */ +static int keymile_hdlc_enet_recv(struct eth_device *dev) +{ + int length; + unsigned char app; + struct icn_frame *fp; + Ethernet_t *ep; + IP_t *ip; + + for (;;) { + if (rtx->rxbd[keymile_rxIdx].cbd_sc & BD_SC_EMPTY) { + length = -1; + break; /* nothing received - leave for() loop */ + } + + length = rtx->rxbd[keymile_rxIdx].cbd_datlen; +#ifdef TEST_RX + dprintf("packet %d bytes long\n", length); +#endif + + /* + * BD_SC_BR -> LG bit + * BD_SC_FR -> NO bit + * BD_SC_PR -> AB bit + * BD_SC_NAK -> CR bit + * 0x80 -> DE bit + */ + if (rtx->rxbd[keymile_rxIdx].cbd_sc & BD_SC_STATS) { +#ifdef ET_DEBUG + dprintf("err: %x\n", rtx->rxbd[keymile_rxIdx].cbd_sc); +#endif + } else if (length > MAX_FRAME_LENGTH) { /* can't happen */ +#ifdef ET_DEBUG + dprintf("err: packet too big\n"); +#endif + } else { + fp = (struct icn_frame *)(MyRxPackets[keymile_rxIdx] + + INET_HDR_ALIGN - INET_HDR_SIZE); +#ifdef TEST_RX + dprintf("RX %d: ", keymile_rxIdx); + hexdump((unsigned char *)MyRxPackets[keymile_rxIdx], + INET_HDR_ALIGN + INET_HDR_SIZE + 4); +#endif + /* copy icn header to the beginning */ + memcpy(fp, ((char *)fp + INET_HDR_SIZE), + sizeof(struct icn_hdr)); + app = fp->hdr.application; + if (app == MGS_NETCONS || app == MGS_TFTP) { + struct icn_hdr *ih = &fp->hdr; + unsigned char icn_src_addr = ih->src_addr; + unsigned char icn_dest_addr = ih->dest_addr; + + /* + * expand header by INET_HDR_SIZE + */ + length += INET_HDR_SIZE; + /* initalize header */ + memset((char *)fp->data, 0x00, INET_HDR_SIZE); + ep = (Ethernet_t *)fp->data; + /* set MACs */ + ep->et_dest[0] = icn_dest_addr; + ep->et_src[0] = icn_src_addr; + ep->et_protlen = htons(PROT_IP); + /* set ip stuff */ + ip = (IP_t *)(fp->data + ETHER_HDR_SIZE); + /* set ip addresses */ + ip->ip_src = cachedNumbers[IP_SERVER]; + ip->ip_dst = cachedNumbers[IP_ADDR]; + /* ip length */ + ip->ip_len = htons(length - ETHER_HDR_SIZE - + REMOVE); + /* ip proto */ + ip->ip_p = IPPROTO_UDP; + switch (app) { + case MGS_TFTP: + /* swap src/dst port numbers */ + ip->udp_src = (ushort) + cachedNumbers[TFTP_DST_PORT]; + ip->udp_dst = (ushort) + cachedNumbers[TFTP_SRC_PORT]; + ip->udp_len = ip->ip_len - + IP_HDR_SIZE_NO_UDP; + ip->udp_xsum = 0; + break; + case MGS_NETCONS: + ip->udp_src = (ushort) + cachedNumbers[NETCONS_PORT]; + /* + * in drivers/net/netconsole.c src port + * equals dest port + */ + ip->udp_dst = ip->udp_src; + ip->udp_len = ip->ip_len - + IP_HDR_SIZE_NO_UDP; + ip->udp_xsum = 0; + break; + } + /* ip version */ + ip->ip_hl_v = (0x40) | (0x0f & + (IP_HDR_SIZE_NO_UDP / 4)); + ip->ip_tos = 0; + ip->ip_id = 0; + /* flags, fragment offset */ + ip->ip_off = htons(0x4000); + ip->ip_ttl = 255; /* time to live */ + /* have to fixup the checksum */ + ip->ip_sum = ~NetCksum((uchar *)ip, + IP_HDR_SIZE_NO_UDP / 2); + /* + * Pass the packet up to the protocol layers + * but remove dest_addr, src_addr, application + * and the CRC. + */ +#ifdef TEST_RX + hexdump((unsigned char *)fp->data, + INET_HDR_SIZE + 4); +#endif + NetReceive(fp->data, length - REMOVE); + } else { + /* + * the other application types are not yet + * supported by u-boot. + */ + /* normally drop it */ +#ifdef TEST_NO + /* send it anyway */ + fp = (struct icn_frame *) + (MyRxPackets[keymile_rxIdx] + + INET_HDR_ALIGN); + NetReceive(fp->data, length - REMOVE); +#endif + } + } + + /* Give the buffer back to the SCC. */ + rtx->rxbd[keymile_rxIdx].cbd_datlen = 0; + + /* wrap around buffer index when necessary */ + if ((keymile_rxIdx + 1) >= HDLC_PKTBUFSRX) { + rtx->rxbd[HDLC_PKTBUFSRX - 1].cbd_sc = + (BD_SC_WRAP | BD_SC_EMPTY); + keymile_rxIdx = 0; + } else { + rtx->rxbd[keymile_rxIdx].cbd_sc = BD_SC_EMPTY; + keymile_rxIdx++; + } + } + return length; +} + +#ifdef TEST_IT +/* simple send test routine */ +int hdlc_enet_stest(struct cmd_tbl_s *a, int b, int c, char **d) +{ + unsigned char pkt[2]; + int ret; + + dprintf("enter stest\n"); + /* may have to initialize things */ + if (seth->state != ETH_STATE_ACTIVE) { + /* the bd_t* is not used */ + if (seth->init(seth, NULL) >= 0) + seth->state = ETH_STATE_ACTIVE; + } + pkt[0] = 0xea; + pkt[1] = 0xae; + ret = keymile_hdlc_enet_send(seth, pkt, 2); + dprintf("return from send %x\n", ret); + dprintf("exit stest\n"); + return ret; +} +U_BOOT_CMD( + stest, 1, 1, hdlc_enet_stest, + "stest - simple send test for hdlc_enet\n", + "no arguments\n" +); +/* simple receive test routine */ +int hdlc_enet_rtest(struct cmd_tbl_s *a, int b, int c, char **d) +{ + int ret; + + dprintf("enter rtest\n"); + /* may have to initialize things */ + if (seth->state != ETH_STATE_ACTIVE) { + /* the bd_t* is not used */ + if (seth->init(seth, NULL) >= 0) + seth->state = ETH_STATE_ACTIVE; + } + ret = keymile_hdlc_enet_recv(seth); + dprintf("return from recv %x\n", ret); + dprintf("exit rtest\n"); + return ret; +} +U_BOOT_CMD( + rtest, 1, 1, hdlc_enet_rtest, + "rtest - simple receive test for hdlc_enet\n", + "no arguments\n" +); +#endif + +#endif /* CONFIG_KEYMILE_HDLC_ENET */ diff --git a/board/keymile/common/keymile_hdlc_enet.h b/board/keymile/common/keymile_hdlc_enet.h new file mode 100644 index 0000000..965bd5a --- /dev/null +++ b/board/keymile/common/keymile_hdlc_enet.h @@ -0,0 +1,129 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _KEYMILE_HDLC_ENET_H_ +#define _KEYMILE_HDLC_ENET_H_ + +/* Unfortuantely, we have do this to get the flag defines in the cbd_t */ +#ifdef CONFIG_MGSUVD +#include +#endif +#ifdef CONFIG_MGCOGE +#include +#include +#endif + +/* + * Defines for the ICN protocol used for communication over HDLC + * on the backplane between MGSUVDs and MGCOGEs. + */ + +/* + * MAC which is reserved for communication (0x00 - 0xff in the last byte, + * which is the slot number) + */ + +/* + * A DLL frame looks like this: + * 8 bit | 8 bit | 8 bit | 8 bit | n * 8 bit| 16 bit| 8 bit + * opening| destination| source | application| data | FCS | closing + * flag | address | address| | | | flag + * (HW) (APP) (APP) (APP) (APP) (HW) (HW) + */ + +/* + * The opening flag, the FCS and the closing flag are set by the hardware so + * they are not reflected in this struct. + */ +struct icn_hdr { + unsigned char dest_addr; + unsigned char src_addr; + unsigned char application; +} __attribute__((packed)); + +#define ICNHDR_LEN (sizeof(struct icn_hdr)) +#define CRC_LEN (sizeof(short)) +/* bytes to remove from packet before sending it upstream */ +#define REMOVE (ICNHDR_LEN + CRC_LEN) + +struct icn_frame { + struct icn_hdr hdr; + unsigned char data[0]; /* a place holder */ +} __attribute__((packed)); + +/* Address field */ +#define HDLC_UUA 0x00 /* Unicast Unit Address */ +#define HDLC_UUA_MASK 0x3f /* the last 6 bits contain the slot number */ +#define SET_HDLC_UUA(x) ((HDLC_UUA | ((x) & HDLC_UUA_MASK))) +#define HDLC_UACUA 0x7f /* Unicast Active Control Unit Address */ +#define HDLC_BCAST 0xff /* broadcast */ + +/* Application field */ +#define MGS_UUSP 0x00 +#define MGS_UREP 0x01 +#define MGS_IUP 0x02 +#define MGS_UTA 0x03 +#define MGS_MDS 0x04 +#define MGS_ITIME 0x05 +/* added by DENX */ +#define MGS_NETCONS 0x06 /* netconsole */ +#define MGS_TFTP 0x07 + +/* Useful defines for buffer sizes, etc. */ +#define HDLC_PKTBUFSRX 32 +#define MAX_FRAME_LENGTH 1500 /* ethernet frame size */ + /* 14 + 28 */ +#define INET_HDR_SIZE (ETHER_HDR_SIZE + IP_HDR_SIZE) +#define INET_HDR_ALIGN (((INET_HDR_SIZE + PKTALIGN - 1) / PKTALIGN) * PKTALIGN) +/* INET_HDR_SIZE is stripped off */ +#define PKT_MAXBLR_SIZE (MAX_FRAME_LENGTH + INET_HDR_ALIGN) + +/* + * It is too slow to read always the port numbers and IP addresses from the + * string variables. + * cachedNumbers is meant to cache it. + * THIS IS ONLY A SPEED IMPROVEMENT! + */ +enum { + IP_ADDR = 0, /* getenv_IPaddr("serverip"); */ + IP_SERVER, /* getenv_IPaddr("ipaddr"); */ + TFTP_SRC_PORT, /* simple_strtol(getenv("tftpsrcp"), NULL, 10); */ + TFTP_DST_PORT, /* simple_strtol(getenv("tftpdstp"), NULL, 10); */ + NETCONS_PORT, /* simple_strtol(getenv("ncip"), NULL, 10); */ + CACHEDNUMBERS +}; + +#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */ + +/* define this to create a test commend (htest) */ +#undef TEST_IT +#ifdef TEST_IT +/* have to save a copy of the eth_device for the test command's use */ +struct eth_device *seth; +#endif +/* define this for outputting of received packets */ +#undef TEST_RX +/* define this for outputting of packets being sent */ +#undef TEST_TX + +#endif /* _KEYMILE_HDLC_ENET_H_ */ -- cgit v1.1 From 534a4359666af48bd69a3743d8a8c2bdb1d3ec70 Mon Sep 17 00:00:00 2001 From: Gary Jennejohn Date: Sun, 9 Nov 2008 12:45:03 +0100 Subject: mgcoge add the board-specific part of the HDLC driver Signed-off-by: Gary Jennejohn --- board/keymile/mgcoge/Makefile | 3 +- board/keymile/mgcoge/mgcoge_hdlc_enet.c | 276 ++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 board/keymile/mgcoge/mgcoge_hdlc_enet.c diff --git a/board/keymile/mgcoge/Makefile b/board/keymile/mgcoge/Makefile index 0cad821..2774a70 100644 --- a/board/keymile/mgcoge/Makefile +++ b/board/keymile/mgcoge/Makefile @@ -28,7 +28,8 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o ../common/common.o +COBJS := $(BOARD).o ../common/common.o ../common/keymile_hdlc_enet.o \ + mgcoge_hdlc_enet.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/keymile/mgcoge/mgcoge_hdlc_enet.c b/board/keymile/mgcoge/mgcoge_hdlc_enet.c new file mode 100644 index 0000000..34f04f5 --- /dev/null +++ b/board/keymile/mgcoge/mgcoge_hdlc_enet.c @@ -0,0 +1,276 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. + * + * Based in part on cpu/mpc8260/ether_scc.c. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_KEYMILE_HDLC_ENET + +#include "../common/keymile_hdlc_enet.h" + +char keymile_slot; /* our slot number in the backplane */ + +/* + * Since, except during initialization, ethact is always HDLC ETHERNET + * while we're in the driver, just use serial_printf() everywhere for + * output. This avoids possible conflicts when netconsole is being + * used. + */ +#define dprintf(fmt, args...) serial_printf(fmt, ##args) + +static int already_inited; + +/* + * SCC Ethernet Tx and Rx buffer descriptors allocated at the + * immr->udata_bd address on Dual-Port RAM + * Provide for Double Buffering + */ +typedef volatile struct CommonBufferDescriptor { + cbd_t txbd; /* Tx BD */ + cbd_t rxbd[HDLC_PKTBUFSRX]; /* Rx BD */ +} RTXBD; + +static RTXBD *rtx; + +int keymile_hdlc_enet_init(struct eth_device *, bd_t *); +void keymile_hdlc_enet_halt(struct eth_device *); +extern void keymile_hdlc_enet_init_bds(RTXBD *); +extern void initCachedNumbers(int); + +/* Use SCC1 */ +#define CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE +#define CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK +#define CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\ + CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK) +#define CMXSCR_VALUE (CMXSCR_RS1CS_CLK11|CMXSCR_TS1CS_CLK11) +#define MGC_PROFF_HDLC PROFF_SCC1 +#define MGC_SCC_HDLC 0 /* Index, not number! */ + +int keymile_hdlc_enet_init(struct eth_device *dev, bd_t *bis) +{ + /* int i; */ + uint dpr; + /* volatile cbd_t *bdp; */ + volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; + volatile cpm8260_t *cp = &(im->im_cpm); + volatile scc_t *sccp; + volatile scc_hdlc_t *hpr; + volatile iop8260_t *iop; + + if (already_inited) + return 0; + + hpr = (scc_hdlc_t *)(&im->im_dprambase[MGC_PROFF_HDLC]); + sccp = (scc_t *)(&im->im_scc[MGC_SCC_HDLC]); + iop = &im->im_ioport; + + /* + * Disable receive and transmit just in case. + */ + sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + /* + * Avoid exhausting DPRAM, which would cause a panic. + */ + if (rtx == NULL) { + /* dpr is an offset into dpram */ + dpr = m8260_cpm_dpalloc(sizeof(RTXBD), 8); + rtx = (RTXBD *)&im->im_dprambase[dpr]; + } + + /* We need the slot number for addressing. */ + keymile_slot = *(char *)(CONFIG_SYS_SLOT_ID_BASE + + CONFIG_SYS_SLOT_ID_OFF) & CONFIG_SYS_SLOT_ID_MASK; + /* + * Be consistent with the Linux driver and set + * only enetaddr[0]. + * + * Always add 1 to the slot number so that + * there are no problems with an ethaddr which + * is all 0s. This should be acceptable because + * a board should never have a slot number of 255, + * which is the broadcast address. The HDLC addressing + * uses only the slot number. + */ + dev->enetaddr[0] = keymile_slot + 1; +#ifdef TEST_IT + dprintf("slot %d\n", keymile_slot); +#endif + + /* use pd30, pd31 pins for TXD1, RXD1 respectively */ + iop->iop_ppard |= (0x80000000 >> 30) | (0x80000000 >> 31); + iop->iop_pdird |= (0x80000000 >> 30); + iop->iop_psord |= (0x80000000 >> 30); + + /* use pc21 as CLK11 */ + iop->iop_pparc |= (0x80000000 >> 21); + iop->iop_pdirc &= ~(0x80000000 >> 21); + iop->iop_psorc &= ~(0x80000000 >> 21); + + /* use pc15 as CTS1 */ + iop->iop_pparc |= (0x80000000 >> 15); + iop->iop_pdirc &= ~(0x80000000 >> 15); + iop->iop_psorc &= ~(0x80000000 >> 15); + + /* + * SI clock routing + * use CLK11 + * this also connects SCC1 to NMSI + */ + im->im_cpmux.cmx_scr = (im->im_cpmux.cmx_scr & ~CMXSCR_MASK) | + CMXSCR_VALUE; + + /* keymile_rxIdx = 0; */ + + /* + * Initialize function code registers for big-endian. + */ + hpr->sh_genscc.scc_rfcr = CPMFCR_EB; + hpr->sh_genscc.scc_tfcr = CPMFCR_EB; + + /* + * Set maximum bytes per receive buffer. + */ + hpr->sh_genscc.scc_mrblr = MAX_FRAME_LENGTH; + + /* Setup CRC generator values for HDLC */ + hpr->sh_cmask = 0x0000F0B8; + hpr->sh_cpres = 0x0000FFFF; + + /* Initialize all error counters to 0 */ + hpr->sh_disfc = 0; + hpr->sh_crcec = 0; + hpr->sh_abtsc = 0; + hpr->sh_nmarc = 0; + hpr->sh_retrc = 0; + + /* Set maximum frame length size */ + hpr->sh_mflr = MAX_FRAME_LENGTH; + + /* set to 1 for per frame processing change later if needed */ + hpr->sh_rfthr = 1; + + hpr->sh_hmask = 0xff; + + hpr->sh_haddr2 = SET_HDLC_UUA(keymile_slot); + hpr->sh_haddr3 = hpr->sh_haddr2; + hpr->sh_haddr4 = hpr->sh_haddr2; + /* broadcast */ + hpr->sh_haddr1 = HDLC_BCAST; + + hpr->sh_genscc.scc_rbase = (unsigned int) &rtx->rxbd[0]; + hpr->sh_genscc.scc_tbase = (unsigned int) &rtx->txbd; + +#if 0 + /* + * Initialize the buffer descriptors. + */ + bdp = &rtx->txbd; + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp->cbd_sc = BD_SC_WRAP; + + /* + * Setup RX packet buffers, aligned correctly. + * Borrowed from net/net.c. + */ + MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1); + MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN; + for (i = 1; i < HDLC_PKTBUFSRX; i++) + MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE; + + bdp = &rtx->rxbd[0]; + for (i = 0; i < HDLC_PKTBUFSRX; i++) { + bdp->cbd_sc = BD_SC_EMPTY; + /* Leave space at the start for INET header. */ + bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] + + INET_HDR_ALIGN); + bdp++; + } + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; +#else + keymile_hdlc_enet_init_bds(rtx); +#endif + + /* Let's re-initialize the channel now. We have to do it later + * than the manual describes because we have just now finished + * the BD initialization. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK, + 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + sccp->scc_gsmrl = SCC_GSMRL_MODE_HDLC; + /* CTSS=1 */ + sccp->scc_gsmrh = SCC_GSMRH_CTSS; + /* NOF=0, RTE=1, DRT=0, BUS=1 */ + sccp->scc_psmr = ((0x8000 >> 6) | (0x8000 >> 10)); + +/* loopback for local testing */ +#ifdef GJTEST + dprintf("LOOPBACK!\n"); + sccp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP; +#endif + + /* + * Disable all interrupts and clear all pending + * events. + */ + sccp->scc_sccm = 0; + sccp->scc_scce = 0xffff; + + /* + * And last, enable the transmit and receive processing. + */ + sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + dprintf("%s: HDLC ENET Version 0.3 on SCC%d\n", dev->name, + MGC_SCC_HDLC + 1); + + /* + * We may not get an ARP packet because ARP was already done on + * a different interface, so initialize the cached values now. + */ + initCachedNumbers(1); + + already_inited = 1; + + return 0; +} + +void keymile_hdlc_enet_halt(struct eth_device *dev) +{ +#if 0 /* just return, but keep this for reference */ + volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + + /* maybe should do a graceful stop here? */ + immr->im_scc[MGC_SCC_HDLC].scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#endif +} + +#endif /* CONFIG_MGCOGE_HDLC_ENET */ -- cgit v1.1 From 4c60259899aa00f59db0d936b8807f9a26411c0f Mon Sep 17 00:00:00 2001 From: Gary Jennejohn Date: Sun, 9 Nov 2008 12:50:59 +0100 Subject: mgsuvd add the board-specific part of the HDLC driver Signed-off-by: Gary Jennejohn --- board/keymile/mgsuvd/Makefile | 3 +- board/keymile/mgsuvd/mgsuvd_hdlc_enet.c | 278 ++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 board/keymile/mgsuvd/mgsuvd_hdlc_enet.c diff --git a/board/keymile/mgsuvd/Makefile b/board/keymile/mgsuvd/Makefile index b2145f9..2c5732d 100644 --- a/board/keymile/mgsuvd/Makefile +++ b/board/keymile/mgsuvd/Makefile @@ -28,7 +28,8 @@ endif LIB = $(obj)lib$(BOARD).a -COBJS = $(BOARD).o ../common/common.o +COBJS = $(BOARD).o ../common/common.o ../common/keymile_hdlc_enet.o \ + mgsuvd_hdlc_enet.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/keymile/mgsuvd/mgsuvd_hdlc_enet.c b/board/keymile/mgsuvd/mgsuvd_hdlc_enet.c new file mode 100644 index 0000000..9b93131 --- /dev/null +++ b/board/keymile/mgsuvd/mgsuvd_hdlc_enet.c @@ -0,0 +1,278 @@ +/* + * (C) Copyright 2008 + * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. + * + * Based in part on cpu/mpc8xx/scc.c. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include /* commproc.h is included here */ +#include +#include + +#ifdef CONFIG_KEYMILE_HDLC_ENET + +#include "../common/keymile_hdlc_enet.h" + +char keymile_slot; /* our slot number in the backplane */ + +/* + * Since, except during initialization, ethact is always HDLC ETHERNET + * while we're in the driver, just use serial_printf() everywhere for + * output. This avoids possible conflicts when netconsole is being + * used. + */ +#define dprintf(fmt, args...) serial_printf(fmt, ##args) + +static int already_inited; + +/* + * SCC Ethernet Tx and Rx buffer descriptors allocated at the + * immr->udata_bd address on Dual-Port RAM + * Provide for Double Buffering + */ +typedef volatile struct CommonBufferDescriptor { + cbd_t txbd; /* Tx BD */ + cbd_t rxbd[HDLC_PKTBUFSRX]; /* Rx BD */ +} RTXBD; + +static RTXBD *rtx; + +int keymile_hdlc_enet_init(struct eth_device *, bd_t *); +void keymile_hdlc_enet_halt(struct eth_device *); +extern void keymile_hdlc_enet_init_bds(RTXBD *); +extern void initCachedNumbers(int); + +/* Use SCC4 */ +#define MGS_CPM_CR_HDLC CPM_CR_CH_SCC4 +#define MGS_PROFF_HDLC PROFF_SCC4 +#define MGS_SCC_HDLC 3 /* Index, not number! */ + +int keymile_hdlc_enet_init(struct eth_device *dev, bd_t *bis) +{ + /* int i; */ + /* volatile cbd_t *bdp; */ + volatile cpm8xx_t *cp; + volatile scc_t *sccp; + volatile hdlc_pram_t *hpr; + volatile iop8xx_t *iop; + + if (already_inited) + return 0; + + cp = (cpm8xx_t *)&(((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm); + hpr = (hdlc_pram_t *)(&cp->cp_dparam[MGS_PROFF_HDLC]); + sccp = (volatile scc_t *)(&cp->cp_scc[MGS_SCC_HDLC]); + iop = (iop8xx_t *)&(((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport); + + /* + * Disable receive and transmit just in case. + */ + sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + +#ifndef CONFIG_SYS_ALLOC_DPRAM +#error "CONFIG_SYS_ALLOC_DPRAM must be defined" +#else + /* + * Avoid exhausting DPRAM, which would cause a panic. + * Actually this isn't really necessary, but leave it here + * for safety's sake. + */ + if (rtx == NULL) { + rtx = (RTXBD *) (cp->cp_dpmem + + dpram_alloc_align(sizeof(RTXBD), 8)); + if (rtx == (RTXBD *)CPM_DP_NOSPACE) + return -1; + memset((void *)rtx, 0, sizeof(RTXBD)); + } +#endif /* !CONFIG_SYS_ALLOC_DPRAM */ + + /* We need the slot number for addressing. */ + keymile_slot = *(char *)(CONFIG_SYS_SLOT_ID_BASE + + CONFIG_SYS_SLOT_ID_OFF) & CONFIG_SYS_SLOT_ID_MASK; + /* + * Be consistent with the Linux driver and set + * only enetaddr[0]. + * + * Always add 1 to the slot number so that + * there are no problems with an ethaddr which + * is all 0s. This should be acceptable because + * a board should never have a slot number of 255, + * which is the broadcast address. The HDLC addressing + * uses only the slot number. + */ + dev->enetaddr[0] = keymile_slot + 1; + +#ifdef TEST_IT + dprintf("slot %d\n", keymile_slot); +#endif + + /* use pa8, pa9 pins for TXD4, RXD4 respectively */ + iop->iop_papar |= ((0x8000 >> 8) | (0x8000 >> 9)); + iop->iop_padir &= ~((0x8000 >> 8) | (0x8000 >> 9)); + iop->iop_paodr &= ~((0x8000 >> 8) | (0x8000 >> 9)); + + /* also use pa0 as CLK8 */ + iop->iop_papar |= 0x8000; + iop->iop_padir &= ~0x8000; + iop->iop_paodr &= ~0x8000; + + /* use pc5 as CTS4 */ + iop->iop_pcpar &= ~(0x8000 >> 5); + iop->iop_pcdir &= ~(0x8000 >> 5); + iop->iop_pcso |= (0x8000 >> 5); + + /* + * SI clock routing + * use CLK8 + * this also connects SCC4 to NMSI + */ + cp->cp_sicr = (cp->cp_sicr & ~0xff000000) | 0x3f000000; + + /* keymile_rxIdx = 0; */ + + /* + * Initialize function code registers for big-endian. + */ + hpr->rfcr = SCC_EB; + hpr->tfcr = SCC_EB; + + /* + * Set maximum bytes per receive buffer. + */ + hpr->mrblr = MAX_FRAME_LENGTH; + + /* Setup CRC generator values for HDLC */ + hpr->c_mask = 0x0000F0B8; + hpr->c_pres = 0x0000FFFF; + + /* Initialize all error counters to 0 */ + hpr->disfc = 0; + hpr->crcec = 0; + hpr->abtsc = 0; + hpr->nmarc = 0; + hpr->retrc = 0; + + /* Set maximum frame length size */ + hpr->mflr = MAX_FRAME_LENGTH; + + /* set to 1 for per frame processing change later if needed */ + hpr->rfthr = 1; + + hpr->hmask = 0xff; + + hpr->haddr2 = SET_HDLC_UUA(keymile_slot); + hpr->haddr3 = hpr->haddr2; + hpr->haddr4 = hpr->haddr2; + /* broadcast */ + hpr->haddr1 = HDLC_BCAST; + + hpr->rbase = (unsigned int) &rtx->rxbd[0]; + hpr->tbase = (unsigned int) &rtx->txbd; + +#if 0 + /* + * Initialize the buffer descriptors. + */ + bdp = &rtx->txbd; + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp->cbd_sc = BD_SC_WRAP; + + /* + * Setup RX packet buffers, aligned correctly. + * Borrowed from net/net.c. + */ + MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1); + MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN; + for (i = 1; i < HDLC_PKTBUFSRX; i++) + MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE; + + bdp = &rtx->rxbd[0]; + for (i = 0; i < HDLC_PKTBUFSRX; i++) { + bdp->cbd_sc = BD_SC_EMPTY; + /* Leave space at the start for INET header. */ + bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] + + INET_HDR_ALIGN); + bdp++; + } + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; +#else + keymile_hdlc_enet_init_bds(rtx); +#endif + + /* Let's re-initialize the channel now. We have to do it later + * than the manual describes because we have just now finished + * the BD initialization. + */ + cp->cp_cpcr = mk_cr_cmd(MGS_CPM_CR_HDLC, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + sccp->scc_gsmrl = SCC_GSMRL_MODE_HDLC; + /* CTSS=1 */ + sccp->scc_gsmrh = SCC_GSMRH_CTSS; + /* NOF=0, RTE=1, DRT=0, BUS=1 */ + sccp->scc_psmr = ((0x8000 >> 6) | (0x8000 >> 10)); + +/* loopback for local testing */ +#ifdef GJTEST + dprintf("LOOPBACK!\n"); + sccp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP; +#endif + + /* + * Disable all interrupts and clear all pending + * events. + */ + sccp->scc_sccm = 0; + sccp->scc_scce = 0xffff; + + /* + * And last, enable the transmit and receive processing. + */ + sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + dprintf("%s: HDLC ENET Version 0.3 on SCC%d\n", dev->name, + MGS_SCC_HDLC + 1); + + /* + * We may not get an ARP packet because ARP was already done on + * a different interface, so initialize the cached values now. + */ + initCachedNumbers(1); + + already_inited = 1; + + return 0; +} + +void keymile_hdlc_enet_halt(struct eth_device *dev) +{ +#if 0 /* just return, but keep this for reference */ + volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + + /* maybe should do a graceful stop here? */ + immr->im_cpm.cp_scc[MGS_SCC_HDLC].scc_gsmrl &= + ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#endif +} + +#endif /* CONFIG_KEYMILE_HDLC_ENET */ -- cgit v1.1 From af5eb847a10f1037590001355d88bab3fe7be48b Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 10 Nov 2008 12:46:20 +0000 Subject: SPARC: Fixed compiler error introduced by commit c160a9544743 This patch fixes a build error for the SPARC platform. It was introduced by commit c160a9544743e80e8889edb2275538e7764ce334. Signed-off-by: Daniel Hellstrom --- lib_sparc/bootm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c index 4975759..c62cf57 100644 --- a/lib_sparc/bootm.c +++ b/lib_sparc/bootm.c @@ -27,6 +27,7 @@ #include #include #include +#include #define PRINT_KERNEL_HEADER @@ -178,7 +179,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t * images) * From now on the only code in u-boot that will be * executed is the PROM code. */ - kernel(kernel_arg_promvec, (void *)ep); + kernel(kernel_arg_promvec, (void *)images->ep); /* It will never come to this... */ while (1) ; -- cgit v1.1 From 4b530018764934ad5689196e9aa5714a6f4d1a6c Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 12 Nov 2008 09:50:45 +0100 Subject: jffs2: rename devices_init () in common/jffs2.c rename devices_init () in common/jffs2.c to jffs2_devices_init (), because there is also a devices_init () in common/devices.c. Signed-off-by: Heiko Schocher --- common/cmd_jffs2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index 791a572..c2caade 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -1056,7 +1056,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ * * @return 0 on success, 1 otherwise */ -static int devices_init(void) +static int jffs2_devices_init(void) { last_parts[0] = '\0'; current_dev = NULL; @@ -1471,12 +1471,12 @@ static int parse_mtdparts(const char *const mtdparts) DEBUGF("\n---parse_mtdparts---\nmtdparts = %s\n\n", p); /* delete all devices and partitions */ - if (devices_init() != 0) { + if (jffs2_devices_init() != 0) { printf("could not initialise device list\n"); return err; } - /* re-read 'mtdparts' variable, devices_init may be updating env */ + /* re-read 'mtdparts' variable, jffs2_devices_init may be updating env */ p = getenv("mtdparts"); if (strncmp(p, "mtdparts=", 9) != 0) { @@ -1698,7 +1698,7 @@ int mtdparts_init(void) ids_changed = 1; if (parse_mtdids(ids) != 0) { - devices_init(); + jffs2_devices_init(); return 1; } @@ -1731,7 +1731,7 @@ int mtdparts_init(void) /* mtdparts variable was reset to NULL, delete all devices/partitions */ if (!parts && (last_parts[0] != '\0')) - return devices_init(); + return jffs2_devices_init(); /* do not process current partition if mtdparts variable is null */ if (!parts) @@ -2105,8 +2105,8 @@ int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) setenv("mtdparts", NULL); - /* devices_init() calls current_save() */ - return devices_init(); + /* jffs2_devices_init() calls current_save() */ + return jffs2_devices_init(); } } -- cgit v1.1 From cf7a7b99794bac936899819b95539be1dbd71708 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Wed, 12 Nov 2008 12:33:20 -0600 Subject: Use bash for default GNU Make shell application Some Make script commands rely on bash-specific features like brace expansion, so default to bash for the SHELL variable with a fallback to the standard sh shell Signed-off-by: Peter Tyser --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 11fc3b7..913fd16 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,12 @@ HOSTARCH := $(shell uname -m | \ HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ sed -e 's/\(cygwin\).*/cygwin/') -export HOSTARCH HOSTOS +# Set shell to bash if possible, otherwise fall back to sh +SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi; fi) + +export HOSTARCH HOSTOS SHELL # Deal with colliding definitions from tcsh etc. VENDOR= -- cgit v1.1 From 434c51a5e62f608a2a78ed5398ac43a1c77cc183 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Wed, 12 Nov 2008 13:06:48 -0600 Subject: Remove unneeded CONFIG_SHELL references Make should be using the bash shell by default which makes CONFIG_SHELL unnecessary Signed-off-by: Peter Tyser --- Makefile | 3 +-- config.mk | 9 ++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 913fd16..4dafd2b 100644 --- a/Makefile +++ b/Makefile @@ -374,8 +374,7 @@ $(U_BOOT_ONENAND): $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk $(VERSION_FILE): @( printf '#define U_BOOT_VERSION "U-Boot %s%s"\n' "$(U_BOOT_VERSION)" \ - '$(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion $(TOPDIR))' \ - ) > $@.tmp + '$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ) > $@.tmp @cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@ $(TIMESTAMP_FILE): diff --git a/config.mk b/config.mk index 5a9334c..d770f09 100644 --- a/config.mk +++ b/config.mk @@ -46,10 +46,6 @@ PLATFORM_LDFLAGS = ######################################################################### -CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ - else if [ -x /bin/bash ]; then echo /bin/bash; \ - else echo sh; fi ; fi) - ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc) HOSTCC = cc else @@ -204,9 +200,8 @@ endif ######################################################################### -export CONFIG_SHELL HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE \ - AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP \ - MAKE +export HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE \ + AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE export TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS ######################################################################### -- cgit v1.1 From 153176a9414120ca1736f3cc4951623d6e14e6af Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 11 Nov 2008 06:08:59 +0100 Subject: avr32/bootm: remove unused variable 'ret' Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Haavard Skinnemoen --- lib_avr32/bootm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_avr32/bootm.c b/lib_avr32/bootm.c index 556e3ea..03ab8d1 100644 --- a/lib_avr32/bootm.c +++ b/lib_avr32/bootm.c @@ -176,7 +176,6 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) void (*theKernel)(int magic, void *tagtable); struct tag *params, *params_start; char *commandline = getenv("bootargs"); - int ret; if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; -- cgit v1.1 From 268405fa7c44156c5192a70779920c70906af8d6 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 9 Dec 2008 00:24:30 +0100 Subject: vxworks.h: Fix build problem introduced by commits 29a4c24d/e9084b23 Signed-off-by: Wolfgang Denk --- include/vxworks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vxworks.h b/include/vxworks.h index 548e8e8..1633904 100644 --- a/include/vxworks.h +++ b/include/vxworks.h @@ -47,7 +47,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif #ifndef CONFIG_SYS_VXWORKS_SERVERNAME -#define CONFIG_SYS_VXWORKS_SERVERNAME srv +#define CONFIG_SYS_VXWORKS_SERVERNAME "srv" #endif #endif -- cgit v1.1 From 7fa6a2f3b66579dea8bc1a9177646e1141731b15 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 9 Dec 2008 00:39:08 +0100 Subject: MAKEALL: Automatically use parallel builds Add logic to the MAKEALL script to determine the number of CPU cores on the system, and run a parallel build if there is more than one. Usually this significantrly accelerates builds. Allow to manually adjust the number of parallel make jobs by using the "BUILD_NCPUS" environment variable. Signed-off-by: Wolfgang Denk --- MAKEALL | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MAKEALL b/MAKEALL index dbed268..a16549c 100755 --- a/MAKEALL +++ b/MAKEALL @@ -1,6 +1,15 @@ #!/bin/sh -: ${JOBS:=} +# Determine number of CPU cores if no default was set +: ${BUILD_NCPUS:="`getconf _NPROCESSORS_ONLN`"} + +if [ "$BUILD_NCPUS" -gt 1 ] +then + JOBS=-j`expr "$BUILD_NCPUS" + 1` +else + JOBS="" +fi + if [ "${CROSS_COMPILE}" ] ; then MAKE="make CROSS_COMPILE=${CROSS_COMPILE}" -- cgit v1.1 From 5e3ab68e9acf9edf304b8aa32ad7e005483a2c47 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 12 Nov 2008 17:29:48 -0800 Subject: Section name should be ".data", not "data" Signed-off-by: Trent Piepho Signed-off-by: Wolfgang Denk --- cpu/mpc8260/i2c.c | 2 +- cpu/ppc4xx/i2c.c | 7 +++---- drivers/i2c/fsl_i2c.c | 7 +++---- drivers/i2c/soft_i2c.c | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c index a934193..c124639 100644 --- a/cpu/mpc8260/i2c.c +++ b/cpu/mpc8260/i2c.c @@ -37,7 +37,7 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_I2C_MULTI_BUS) -static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0; #endif /* CONFIG_I2C_MULTI_BUS */ /* uSec to wait between polls of the i2c */ diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 0deb149..9073ee2 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -42,11 +42,10 @@ DECLARE_GLOBAL_DATA_PTR; * runs from ROM, and we can't switch buses because we can't modify * the global variables. */ -#ifdef CONFIG_SYS_SPD_BUS_NUM -static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CONFIG_SYS_SPD_BUS_NUM; -#else -static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +#ifndef CONFIG_SYS_SPD_BUS_NUM +#define CONFIG_SYS_SPD_BUS_NUM 0 #endif +static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM; #endif /* CONFIG_I2C_MULTI_BUS */ static void _i2c_bus_reset(void) diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 281a88b..3b5c06b 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -38,11 +38,10 @@ DECLARE_GLOBAL_DATA_PTR; * runs from ROM, and we can't switch buses because we can't modify * the global variables. */ -#ifdef CONFIG_SYS_SPD_BUS_NUM -static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CONFIG_SYS_SPD_BUS_NUM; -#else -static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +#ifndef CONFIG_SYS_SPD_BUS_NUM +#define CONFIG_SYS_SPD_BUS_NUM 0 #endif +static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM; static unsigned int i2c_bus_speed[2] = {CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED}; diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index ebe60e2..d2a5142 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -73,7 +73,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif #if defined(CONFIG_I2C_MULTI_BUS) -static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0; #endif /* CONFIG_I2C_MULTI_BUS */ /*----------------------------------------------------------------------- -- cgit v1.1 From 9def12cae33d2d3ea2dd56b197fd3dfb3ad60bf4 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 27 Nov 2008 14:05:15 +0100 Subject: MTD: Fix problem based on non-working relocation (list head mtd_partitions) Don't use LIST_HEAD() but initialize the struct via INIT_LIST_HEAD() upon first call of add_mtd_partitions(). Otherwise this won't work on platforms where the relocation is broken (like MIPS or PPC). Signed-off-by: Stefan Roese --- drivers/mtd/mtdpart.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 9a3bf6f..f010f5e 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -20,7 +20,7 @@ #include /* Our partition linked list */ -static LIST_HEAD(mtd_partitions); +struct list_head mtd_partitions; /* Our partition node structure */ struct mtd_part { @@ -349,6 +349,14 @@ int add_mtd_partitions(struct mtd_info *master, u_int32_t cur_offset = 0; int i; + /* + * Need to init the list here, since LIST_INIT() does not + * work on platforms where relocation has problems (like MIPS + * & PPC). + */ + if (mtd_partitions.next == NULL) + INIT_LIST_HEAD(&mtd_partitions); + printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); for (i = 0; i < nbparts; i++) { -- cgit v1.1 From 2ee951ba2ac9874d2a93d52e7a187d3184be937e Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 27 Nov 2008 14:07:09 +0100 Subject: UBI: Enable re-initializing of the "ubi part" command With this patch now, the user can call "ubi part" multiple times to re-connect the UBI device to another MTD partition. Signed-off-by: Stefan Roese --- common/cmd_ubi.c | 11 +++++++++++ drivers/mtd/ubi/build.c | 1 + include/ubi_uboot.h | 1 + 3 files changed, 13 insertions(+) diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 8446765..495d71e 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -31,6 +31,7 @@ /* Private own data */ static struct ubi_device *ubi; static char buffer[80]; +static int ubi_initialized; struct selected_dev { char dev_name[32]; /* NAND/OneNAND etc */ @@ -428,6 +429,8 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev) return err; } + ubi_initialized = 1; + return 0; } @@ -464,6 +467,14 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ubi_dev.nr = 0; /* + * Call ubi_exit() before re-initializing the UBI subsystem + */ + if (ubi_initialized) { + ubi_exit(); + del_mtd_partitions(ubi_dev.mtd_info); + } + + /* * Check for nand|onenand selection */ #if defined(CONFIG_CMD_NAND) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 17cabb2..bdf75c9 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1059,6 +1059,7 @@ void __exit ubi_exit(void) misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); class_destroy(ubi_class); + mtd_devs = 0; } module_exit(ubi_exit); diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index 295f2c0..095dfc1 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -211,6 +211,7 @@ static inline long IS_ERR(const void *ptr) /* functions */ extern int ubi_mtd_param_parse(const char *val, struct kernel_param *kp); extern int ubi_init(void); +extern void ubi_exit(void); extern struct ubi_device *ubi_devices[]; -- cgit v1.1 From 2d2e05727fe4013f807ffa814dff0e75259a1db4 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 2 Dec 2008 10:53:47 +0100 Subject: UBI: Fix size parsing in "ubi create" Signed-off-by: Stefan Roese --- common/cmd_ubi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 495d71e..fd33a67 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -546,7 +546,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } /* E.g., create volume size */ if (argc == 4) { - addr = simple_strtoul(argv[3], NULL, 16); + size = simple_strtoul(argv[3], NULL, 16); argc--; } /* Use maximum available size */ -- cgit v1.1 From ee2e9ba917a62cc2e3a484bb79c8da0e01cb93ed Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 9 Dec 2008 17:52:05 +0100 Subject: video: fix FADS823 and RRvision compiling issues Since commit 561858ee building for FADS823 and RRvision doesn't work. Let's include version.h and timestamp.h unconditionally to fix the problem. Signed-off-by: Anatolij Gustschin --- cpu/mpc8xx/video.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpu/mpc8xx/video.c b/cpu/mpc8xx/video.c index 5479644..4a59927 100644 --- a/cpu/mpc8xx/video.c +++ b/cpu/mpc8xx/video.c @@ -32,10 +32,8 @@ #include #include #include -#ifdef VIDEO_INFO #include #include -#endif #include #include #include -- cgit v1.1 From dedacc18a8c2b3951581eb721fa055a4e0ac4845 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 7 Dec 2008 09:45:35 +0100 Subject: usbtty/omap: update to current API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Remy Böhmer --- drivers/serial/usbtty.c | 6 ++---- drivers/serial/usbtty.h | 31 +++++++++++++++++++++---------- drivers/usb/usbdcore_omap1510.c | 4 +++- include/usbdcore_omap1510.h | 6 +++--- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index e738c56..7eba470 100644 --- a/drivers/serial/usbtty.c +++ b/drivers/serial/usbtty.c @@ -22,16 +22,14 @@ */ #include - +#include #include #include #include "usbtty.h" #include "usb_cdc_acm.h" #include "usbdescriptors.h" -#include /* If defined, override Linux identifiers with - * vendor specific ones */ -#if 0 +#ifdef DEBUG #define TTYDBG(fmt,args...)\ serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) #else diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h index 71c47bc..ecefde5 100644 --- a/drivers/serial/usbtty.h +++ b/drivers/serial/usbtty.h @@ -24,11 +24,11 @@ #ifndef __USB_TTY_H__ #define __USB_TTY_H__ -#include "usbdcore.h" +#include #if defined(CONFIG_PPC) -#include "usbdcore_mpc8xx.h" +#include #elif defined(CONFIG_ARM) -#include "usbdcore_omap1510.h" +#include #endif #include @@ -36,14 +36,25 @@ /* If no VendorID/ProductID is defined in config.h, pretend to be Linux * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */ -#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ -#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ -#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ -#define CONFIG_USBD_MANUFACTURER "Das U-Boot" -#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION - +#ifndef CONFIG_USBD_VENDORID +#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ +#endif +#ifndef CONFIG_USBD_PRODUCTID_GSERIAL +#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ +#endif +#ifndef CONFIG_USBD_PRODUCTID_CDCACM +#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ +#endif +#ifndef CONFIG_USBD_MANUFACTURER +#define CONFIG_USBD_MANUFACTURER "Das U-Boot" +#endif +#ifndef CONFIG_USBD_PRODUCT_NAME +#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION +#endif -#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" +#ifndef CONFIG_USBD_CONFIGURATION_STR +#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" +#endif #define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT #define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE diff --git a/drivers/usb/usbdcore_omap1510.c b/drivers/usb/usbdcore_omap1510.c index cb9dc44..6b7b61b 100644 --- a/drivers/usb/usbdcore_omap1510.c +++ b/drivers/usb/usbdcore_omap1510.c @@ -1061,7 +1061,7 @@ void omap1510_udc_noniso_irq (void) */ /* Called to start packet transmission. */ -void udc_endpoint_write (struct usb_endpoint_instance *endpoint) +int udc_endpoint_write (struct usb_endpoint_instance *endpoint) { unsigned short epnum = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK; @@ -1078,6 +1078,8 @@ void udc_endpoint_write (struct usb_endpoint_instance *endpoint) /* deselect the endpoint FIFO */ outw (UDC_EP_Dir | epnum, UDC_EP_NUM); } + + return 0; } /* Start to initialize h/w stuff */ diff --git a/include/usbdcore_omap1510.h b/include/usbdcore_omap1510.h index 526fcd9..ece0e95 100644 --- a/include/usbdcore_omap1510.h +++ b/include/usbdcore_omap1510.h @@ -168,8 +168,8 @@ #define UDC_IN_ENDPOINT 1 #define UDC_IN_PACKET_SIZE 64 #define UDC_INT_ENDPOINT 5 -#define UDC_INT_PKTSIZE 16 -#define UDC_BULK_PKTSIZE 16 +#define UDC_INT_PACKET_SIZE 16 +#define UDC_BULK_PACKET_SIZE 16 void udc_irq (void); /* Flow control */ @@ -177,7 +177,7 @@ void udc_set_nak(int epid); void udc_unset_nak (int epid); /* Higher level functions for abstracting away from specific device */ -void udc_endpoint_write(struct usb_endpoint_instance *endpoint); +int udc_endpoint_write(struct usb_endpoint_instance *endpoint); int udc_init (void); -- cgit v1.1 From 4c253fdb2a175ea3472c38a1455a16faa58e81f0 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 9 Dec 2008 10:27:33 -0600 Subject: drivers/fsl_pci_init: Fix compile warning fsl_pci_init.c: In function 'fsl_pci_setup_inbound_windows': fsl_pci_init.c:122: warning: comparison is always true due to limited range of data type The check only makes sense if we are CONFIG_PHYS_64BIT Signed-off-by: Kumar Gala --- drivers/pci/fsl_pci_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index e57acba..1db42fd 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -119,9 +119,11 @@ int fsl_pci_setup_inbound_windows(struct pci_region *r) } #endif +#ifdef CONFIG_PHYS_64BIT if (sz && (((u64)gd->ram_size) < (1ull << 32))) printf("Was not able to map all of memory via " "inbound windows -- %lld remaining\n", sz); +#endif return r - rgn_base; } -- cgit v1.1 From d2776827315c3d469b8cb4cec14d58877798daa2 Mon Sep 17 00:00:00 2001 From: Stefan Althoefer Date: Sun, 7 Dec 2008 19:39:11 +0100 Subject: USB: descriptor handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi, I found a bug when working with the u-boot USB subsystem on IXP425 processor (big endian Xscale aka ARMv5). I recognized that the second usb_endpoint_descriptor of the attached memory stick was corrupted. The reason for this are the packed structures below (either u-boot and u-boot-usb): -------------- /* Endpoint descriptor */ struct usb_endpoint_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned char bEndpointAddress; unsigned char bmAttributes; unsigned short wMaxPacketSize; unsigned char bInterval; unsigned char bRefresh; unsigned char bSynchAddress; } __attribute__ ((packed)); /* Interface descriptor */ struct usb_interface_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned char bInterfaceNumber; unsigned char bAlternateSetting; unsigned char bNumEndpoints; unsigned char bInterfaceClass; unsigned char bInterfaceSubClass; unsigned char bInterfaceProtocol; unsigned char iInterface; unsigned char no_of_ep; unsigned char num_altsetting; unsigned char act_altsetting; struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS]; } __attribute__ ((packed)); ------------ As usb_endpoint_descriptor is only 7byte in length, the start of all odd ep_desc[] structures is not word aligned. This makes wMaxPacketSize of these structures also not word aligned. ARMv5 Architecture however does not support non-aligned multibyte data type (see A2.8 of ARM Architecture Reference Manual). Signed-off-by: Stefan Althoefer Signed-off-by: Remy Böhmer --- include/usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/usb.h b/include/usb.h index 84a77b2..510df95 100644 --- a/include/usb.h +++ b/include/usb.h @@ -91,7 +91,7 @@ struct usb_endpoint_descriptor { unsigned char bInterval; unsigned char bRefresh; unsigned char bSynchAddress; -} __attribute__ ((packed)); +} __attribute__ ((packed)) __attribute__ ((aligned(2))); /* Interface descriptor */ struct usb_interface_descriptor { -- cgit v1.1 From 1113cb764b3da256ef8a1f9539f4efbe221ff3c4 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 9 Dec 2008 23:13:51 +0100 Subject: evb64260: fix "cast to pointer from integer of different size" warnings Signed-off-by: Wolfgang Denk --- board/evb64260/zuma_pbb.c | 6 ++++-- board/evb64260/zuma_pbb_mbox.c | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/board/evb64260/zuma_pbb.c b/board/evb64260/zuma_pbb.c index 296e461..1d03570 100644 --- a/board/evb64260/zuma_pbb.c +++ b/board/evb64260/zuma_pbb.c @@ -149,8 +149,10 @@ void zuma_init_pbb (void) pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &iobase); - zuma_pbb_reg = - (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK); + iobase &= PCI_BASE_ADDRESS_MEM_MASK; + + zuma_pbb_reg = (PBB_DMA_REG_MAP *)iobase; + if (!zuma_pbb_reg) { printf ("zuma pbb bar none! (hah hah, get it?)\n"); diff --git a/board/evb64260/zuma_pbb_mbox.c b/board/evb64260/zuma_pbb_mbox.c index 6f5df6e..8e38102 100644 --- a/board/evb64260/zuma_pbb_mbox.c +++ b/board/evb64260/zuma_pbb_mbox.c @@ -165,7 +165,9 @@ int zuma_mbox_init(void) pci_read_config_dword(zuma_mbox_dev.dev, PCI_BASE_ADDRESS_0, &iobase); - zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK); + iobase &= PCI_BASE_ADDRESS_MEM_MASK; + + zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *)iobase; zuma_mbox_dev.sip->int_mask.word=0; -- cgit v1.1 From f73846956778a7dfee83403ef9747aff77198848 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 13 Nov 2008 19:49:31 +0300 Subject: jffs2: fix searching for latest version in jffs2_1pass_list_inodes() We need to update i_version inside cycle to find really latest version inside jffs2_1pass_list_inodes(). With that fixed we can use isize inside dump_inode() instead of calling expensive jffs2_1pass_read_inode(). Signed-off-by: Alexey Neyman Signed-off-by: Ilya Yanok --- fs/jffs2/jffs2_1pass.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 920d2fd..35743fc 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -940,9 +940,7 @@ static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, st st.st_mtime = i->mtime; st.st_mode = i->mode; st.st_ino = i->ino; - - /* neither dsize nor isize help us.. do it the long way */ - st.st_size = jffs2_1pass_read_inode(pL, i->ino, NULL); + st.st_size = i->isize; dump_stat(&st, fname); @@ -976,6 +974,7 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) jNode = (struct jffs2_raw_inode *) get_fl_mem(b2->offset, sizeof(ojNode), &ojNode); if (jNode->ino == jDir->ino && jNode->version >= i_version) { + i_version = jNode->version; if (i) put_fl_mem(i); -- cgit v1.1 From e0b5532579eda8b4629f1b4f6e49c3cc60f52237 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 13 Nov 2008 19:49:32 +0300 Subject: jffs2: add sector_size field to part_info structure This patch adds sector_size field to part_info structure (used by new JFFS2 code). Signed-off-by: Ilya Yanok --- common/cmd_jffs2.c | 20 +++++++++++++++++--- include/jffs2/load_kernel.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index c2caade..7866c80 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -339,11 +339,15 @@ static int part_validate_nor(struct mtdids *id, struct part_info *part) extern flash_info_t flash_info[]; flash_info_t *flash; int offset_aligned; - u32 end_offset; + u32 end_offset, sector_size = 0; int i; flash = &flash_info[id->num]; + /* size of last sector */ + part->sector_size = flash->size - + (flash->start[flash->sector_count-1] - flash->start[0]); + offset_aligned = 0; for (i = 0; i < flash->sector_count; i++) { if ((flash->start[i] - flash->start[0]) == part->offset) { @@ -358,12 +362,18 @@ static int part_validate_nor(struct mtdids *id, struct part_info *part) } end_offset = part->offset + part->size; + offset_aligned = 0; for (i = 0; i < flash->sector_count; i++) { + if (i) { + sector_size = flash->start[i] - flash->start[i-1]; + if (part->sector_size < sector_size) + part->sector_size = sector_size; + } if ((flash->start[i] - flash->start[0]) == end_offset) - return 0; + offset_aligned = 1; } - if (flash->size == end_offset) + if (offset_aligned || flash->size == end_offset) return 0; printf("%s%d: partition (%s) size alignment incorrect\n", @@ -389,6 +399,8 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part) nand = &nand_info[id->num]; + part->sector_size = nand->erasesize; + if ((unsigned long)(part->offset) % nand->erasesize) { printf("%s%d: partition (%s) start offset alignment incorrect\n", MTD_DEV_TYPE(id->type), id->num, part->name); @@ -424,6 +436,8 @@ static int part_validate_onenand(struct mtdids *id, struct part_info *part) mtd = &onenand_mtd; + part->sector_size = mtd->erasesize; + if ((unsigned long)(part->offset) % mtd->erasesize) { printf("%s%d: partition (%s) start offset" "alignment incorrect\n", diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h index e9b7d6e..8b2720e 100644 --- a/include/jffs2/load_kernel.h +++ b/include/jffs2/load_kernel.h @@ -50,6 +50,7 @@ struct part_info { u32 offset; /* offset within device */ void *jffs2_priv; /* used internaly by jffs2 */ u32 mask_flags; /* kernel MTD mask flags */ + u32 sector_size; /* size of sector */ struct mtd_device *dev; /* parent device */ }; -- cgit v1.1 From 8a36d31f72411144ac0412ee7e1880e801acd754 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 13 Nov 2008 19:49:33 +0300 Subject: jffs2: rewrite jffs2 scanning code based on Linux one Rewrites jffs2_1pass_build_lists() function in style of Linux's jffs2_scan_medium() and jffs2_scan_eraseblock(). This includes: - Caching flash acceses - Smart dealing with free space Signed-off-by: Alexey Neyman Signed-off-by: Ilya Yanok --- fs/jffs2/jffs2_1pass.c | 227 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 171 insertions(+), 56 deletions(-) diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 35743fc..30a6dba 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -389,6 +389,12 @@ static inline void *get_fl_mem_nor(u32 off) return (void*)addr; } +static inline void *get_fl_mem_nor_copy(u32 off, u32 size, void *ext_buf) +{ + memcpy(ext_buf, get_fl_mem_nor(off), size); + return ext_buf; +} + static inline void *get_node_mem_nor(u32 off) { return (void*)get_fl_mem_nor(off); @@ -405,8 +411,11 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) struct mtdids *id = current_part->dev->id; #if defined(CONFIG_CMD_FLASH) - if (id->type == MTD_DEV_TYPE_NOR) + if (id->type == MTD_DEV_TYPE_NOR) { + if (ext_buf) + return get_fl_mem_nor_copy(off, size, ext_buf); return get_fl_mem_nor(off); + } #endif #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) @@ -478,9 +487,6 @@ static char *compr_names[] = { #endif }; -/* Spinning wheel */ -static char spinner[] = { '|', '/', '-', '\\' }; - /* Memory management */ struct mem_block { u32 index; @@ -651,23 +657,6 @@ static int compare_dirents(struct b_node *new, struct b_node *old) } #endif -static u32 -jffs2_scan_empty(u32 start_offset, struct part_info *part) -{ - char *max = (char *)(part->offset + part->size - sizeof(struct jffs2_raw_inode)); - char *offset = (char *)(part->offset + start_offset); - u32 off; - - while (offset < max && - *(u32*)get_fl_mem((u32)offset, sizeof(u32), &off) == 0xFFFFFFFF) { - offset += sizeof(u32); - /* return if spinning is due */ - if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break; - } - - return (u32)offset - part->offset; -} - void jffs2_free_cache(struct part_info *part) { @@ -766,6 +755,10 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) put_fl_mem(jNode); continue; } + if (!data_crc(jNode)) { + put_fl_mem(jNode); + continue; + } lDest = (uchar *) (dest + jNode->offset); #if 0 @@ -1268,17 +1261,33 @@ dump_dirents(struct b_lists *pL) } #endif +#define min_t(type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1: __min2; }) + +#define DEFAULT_EMPTY_SCAN_SIZE 4096 + +static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) +{ + if (sector_size < DEFAULT_EMPTY_SCAN_SIZE) + return sector_size; + else + return DEFAULT_EMPTY_SCAN_SIZE; +} + static u32 jffs2_1pass_build_lists(struct part_info * part) { struct b_lists *pL; struct jffs2_unknown_node *node; - u32 offset, oldoffset = 0; - u32 max = part->size - sizeof(struct jffs2_raw_inode); - u32 counter = 0; + u32 nr_sectors = part->size/part->sector_size; + u32 i; u32 counter4 = 0; u32 counterF = 0; u32 counterN = 0; + u32 buf_size = DEFAULT_EMPTY_SCAN_SIZE; + char *buf; /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ /* jffs2 list building enterprise nope. in newer versions the overhead is */ @@ -1288,70 +1297,176 @@ jffs2_1pass_build_lists(struct part_info * part) /* if we are building a list we need to refresh the cache. */ jffs_init_1pass_list(part); pL = (struct b_lists *)part->jffs2_priv; - offset = 0; + buf = malloc(buf_size); puts ("Scanning JFFS2 FS: "); /* start at the beginning of the partition */ - while (offset < max) { - if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) { - printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); - oldoffset = offset; - } + for (i = 0; i < nr_sectors; i++) { + uint32_t sector_ofs = i * part->sector_size; + uint32_t buf_ofs = sector_ofs; + uint32_t buf_len = EMPTY_SCAN_SIZE(part->sector_size); + uint32_t ofs, prevofs; WATCHDOG_RESET(); + get_fl_mem((u32)part->offset + buf_ofs, buf_len, buf); - node = (struct jffs2_unknown_node *) get_node_mem((u32)part->offset + offset); - if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) { + /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ + ofs = 0; + + /* Scan only 4KiB of 0xFF before declaring it's empty */ + while (ofs < EMPTY_SCAN_SIZE(part->sector_size) && + *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) + ofs += 4; + + if (ofs == EMPTY_SCAN_SIZE(part->sector_size)) + continue; + + ofs += sector_ofs; + prevofs = ofs - 1; + + scan_more: + while (ofs < sector_ofs + part->sector_size) { + if (ofs == prevofs) { + printf("offset %08x already seen, skip\n", ofs); + ofs += 4; + counter4++; + continue; + } + prevofs = ofs; + if (sector_ofs + part->sector_size < + ofs + sizeof(*node)) + break; + if (buf_ofs + buf_len < ofs + sizeof(*node)) { + buf_len = min_t(uint32_t, buf_size, sector_ofs + + part->sector_size - ofs); + get_fl_mem((u32)part->offset + ofs, buf_len, + buf); + buf_ofs = ofs; + } + + node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs]; + + if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { + uint32_t inbuf_ofs; + uint32_t empty_start, scan_end; + + empty_start = ofs; + ofs += 4; + scan_end = min_t(uint32_t, EMPTY_SCAN_SIZE( + part->sector_size)/8, + buf_len); + more_empty: + inbuf_ofs = ofs - buf_ofs; + while (inbuf_ofs < scan_end) { + if (*(uint32_t *)(&buf[inbuf_ofs]) != + 0xffffffff) + goto scan_more; + + inbuf_ofs += 4; + ofs += 4; + } + /* Ran off end. */ + + /* See how much more there is to read in this + * eraseblock... + */ + buf_len = min_t(uint32_t, buf_size, + sector_ofs + + part->sector_size - ofs); + if (!buf_len) { + /* No more to read. Break out of main + * loop without marking this range of + * empty space as dirty (because it's + * not) + */ + break; + } + scan_end = buf_len; + get_fl_mem((u32)part->offset + ofs, buf_len, + buf); + buf_ofs = ofs; + goto more_empty; + } + if (node->magic != JFFS2_MAGIC_BITMASK || + !hdr_crc(node)) { + ofs += 4; + counter4++; + continue; + } + if (ofs + node->totlen > + sector_ofs + part->sector_size) { + ofs += 4; + counter4++; + continue; + } /* if its a fragment add it */ - if (node->nodetype == JFFS2_NODETYPE_INODE && - inode_crc((struct jffs2_raw_inode *) node) && - data_crc((struct jffs2_raw_inode *) node)) { + switch (node->nodetype) { + case JFFS2_NODETYPE_INODE: + if (buf_ofs + buf_len < ofs + sizeof(struct + jffs2_raw_inode)) { + get_fl_mem((u32)part->offset + ofs, + buf_len, buf); + buf_ofs = ofs; + node = (void *)buf; + } + if (!inode_crc((struct jffs2_raw_inode *) node)) + break; + if (insert_node(&pL->frag, (u32) part->offset + - offset) == NULL) { - put_fl_mem(node); + ofs) == NULL) return 0; + break; + case JFFS2_NODETYPE_DIRENT: + if (buf_ofs + buf_len < ofs + sizeof(struct + jffs2_raw_dirent) + + ((struct + jffs2_raw_dirent *) + node)->nsize) { + get_fl_mem((u32)part->offset + ofs, + buf_len, buf); + buf_ofs = ofs; + node = (void *)buf; } - } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && - dirent_crc((struct jffs2_raw_dirent *) node) && - dirent_name_crc((struct jffs2_raw_dirent *) node)) { + + if (!dirent_crc((struct jffs2_raw_dirent *) + node) || + !dirent_name_crc( + (struct + jffs2_raw_dirent *) + node)) + break; if (! (counterN%100)) puts ("\b\b. "); if (insert_node(&pL->dir, (u32) part->offset + - offset) == NULL) { - put_fl_mem(node); + ofs) == NULL) return 0; - } counterN++; - } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { + break; + case JFFS2_NODETYPE_CLEANMARKER: if (node->totlen != sizeof(struct jffs2_unknown_node)) printf("OOPS Cleanmarker has bad size " "%d != %zu\n", node->totlen, sizeof(struct jffs2_unknown_node)); - } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { + break; + case JFFS2_NODETYPE_PADDING: if (node->totlen < sizeof(struct jffs2_unknown_node)) printf("OOPS Padding has bad size " "%d < %zu\n", node->totlen, sizeof(struct jffs2_unknown_node)); - } else { + break; + default: printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, - node->totlen, offset); + node->totlen, ofs); } - offset += ((node->totlen + 3) & ~3); + ofs += ((node->totlen + 3) & ~3); counterF++; - } else if (node->magic == JFFS2_EMPTY_BITMASK && - node->nodetype == JFFS2_EMPTY_BITMASK) { - offset = jffs2_scan_empty(offset, part); - } else { /* if we know nothing, we just step and look. */ - offset += 4; - counter4++; } -/* printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */ - put_fl_mem(node); } + free(buf); putstr("\b\b done.\r\n"); /* close off the dots */ /* turn the lcd back on. */ /* splash(); */ -- cgit v1.1 From 70741004dc28946cd82c7af6789c4ddb3fc94526 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 13 Nov 2008 19:49:34 +0300 Subject: jffs2: add buffer to cache flash accesses With this patch JFFS2 code allocates memory buffer of max_totlen size (size of the largest node, calculated during scan time) and uses it to store entire node. Speeds up loading. If malloc fails we use old ways to do things. Signed-off-by: Alexey Neyman Signed-off-by: Ilya Yanok --- fs/jffs2/jffs2_1pass.c | 116 +++++++++++++++++++++++++++++------------------ fs/jffs2/jffs2_private.h | 2 +- 2 files changed, 73 insertions(+), 45 deletions(-) diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 30a6dba..73d3ddc 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -245,7 +245,7 @@ static void *get_fl_mem_nand(u32 off, u32 size, void *ext_buf) return buf; } -static void *get_node_mem_nand(u32 off) +static void *get_node_mem_nand(u32 off, void *ext_buf) { struct jffs2_unknown_node node; void *ret = NULL; @@ -255,7 +255,7 @@ static void *get_node_mem_nand(u32 off) if (!(ret = get_fl_mem_nand(off, node.magic == JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node), - NULL))) { + ext_buf))) { printf("off = %#x magic %#x type %#x node.totlen = %d\n", off, node.magic, node.nodetype, node.totlen); } @@ -344,7 +344,7 @@ static void *get_fl_mem_onenand(u32 off, u32 size, void *ext_buf) return buf; } -static void *get_node_mem_onenand(u32 off) +static void *get_node_mem_onenand(u32 off, void *ext_buf) { struct jffs2_unknown_node node; void *ret = NULL; @@ -354,7 +354,7 @@ static void *get_node_mem_onenand(u32 off) ret = get_fl_mem_onenand(off, node.magic == JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node), - NULL); + ext_buf); if (!ret) { printf("off = %#x magic %#x type %#x node.totlen = %d\n", off, node.magic, node.nodetype, node.totlen); @@ -377,7 +377,7 @@ static void put_fl_mem_onenand(void *buf) * NOR flash memory is mapped in processor's address space, * just return address. */ -static inline void *get_fl_mem_nor(u32 off) +static inline void *get_fl_mem_nor(u32 off, u32 size, void *ext_buf) { u32 addr = off; struct mtdids *id = current_part->dev->id; @@ -386,18 +386,22 @@ static inline void *get_fl_mem_nor(u32 off) flash_info_t *flash = &flash_info[id->num]; addr += flash->start[0]; + if (ext_buf) { + memcpy(ext_buf, (void *)addr, size); + return ext_buf; + } return (void*)addr; } -static inline void *get_fl_mem_nor_copy(u32 off, u32 size, void *ext_buf) +static inline void *get_node_mem_nor(u32 off, void *ext_buf) { - memcpy(ext_buf, get_fl_mem_nor(off), size); - return ext_buf; -} + struct jffs2_unknown_node *pNode; -static inline void *get_node_mem_nor(u32 off) -{ - return (void*)get_fl_mem_nor(off); + /* pNode will point directly to flash - don't provide external buffer + and don't care about size */ + pNode = get_fl_mem_nor(off, 0, NULL); + return (void *)get_fl_mem_nor(off, pNode->magic == JFFS2_MAGIC_BITMASK ? + pNode->totlen : sizeof(*pNode), ext_buf); } #endif @@ -412,9 +416,7 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) #if defined(CONFIG_CMD_FLASH) if (id->type == MTD_DEV_TYPE_NOR) { - if (ext_buf) - return get_fl_mem_nor_copy(off, size, ext_buf); - return get_fl_mem_nor(off); + return get_fl_mem_nor(off, size, ext_buf); } #endif @@ -432,34 +434,38 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) return (void*)off; } -static inline void *get_node_mem(u32 off) +static inline void *get_node_mem(u32 off, void *ext_buf) { struct mtdids *id = current_part->dev->id; #if defined(CONFIG_CMD_FLASH) if (id->type == MTD_DEV_TYPE_NOR) - return get_node_mem_nor(off); + return get_node_mem_nor(off, ext_buf); #endif #if defined(CONFIG_JFFS2_NAND) && \ defined(CONFIG_CMD_NAND) if (id->type == MTD_DEV_TYPE_NAND) - return get_node_mem_nand(off); + return get_node_mem_nand(off, ext_buf); #endif #if defined(CONFIG_CMD_ONENAND) if (id->type == MTD_DEV_TYPE_ONENAND) - return get_node_mem_onenand(off); + return get_node_mem_onenand(off, ext_buf); #endif printf("get_node_mem: unknown device type, using raw offset!\n"); return (void*)off; } -static inline void put_fl_mem(void *buf) +static inline void put_fl_mem(void *buf, void *ext_buf) { struct mtdids *id = current_part->dev->id; + /* If buf is the same as ext_buf, it was provided by the caller - + we shouldn't free it then. */ + if (buf == ext_buf) + return; switch (id->type) { #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) case MTD_DEV_TYPE_NAND: @@ -666,6 +672,7 @@ jffs2_free_cache(struct part_info *part) pL = (struct b_lists *)part->jffs2_priv; free_nodes(&pL->frag); free_nodes(&pL->dir); + free(pL->readbuf); free(pL); } } @@ -712,7 +719,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) */ for (b = pL->frag.listHead; b != NULL; b = b->next) { jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(struct jffs2_raw_inode), NULL); + sizeof(struct jffs2_raw_inode), pL->readbuf); if ((inode == jNode->ino)) { /* get actual file length from the newest node */ if (jNode->version >= latestVersion) { @@ -720,12 +727,13 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) latestVersion = jNode->version; } } - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); } #endif for (b = pL->frag.listHead; b != NULL; b = b->next) { - jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset); + jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset, + pL->readbuf); if ((inode == jNode->ino)) { #if 0 putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen); @@ -752,11 +760,11 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) src = ((uchar *) jNode) + sizeof(struct jffs2_raw_inode); /* ignore data behind latest known EOF */ if (jNode->offset > totalSize) { - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); continue; } if (!data_crc(jNode)) { - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); continue; } @@ -797,7 +805,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) default: /* unknown */ putLabeledWord("UNKOWN COMPRESSION METHOD = ", jNode->compr); - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); return -1; break; } @@ -809,7 +817,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) #endif } counter++; - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); } #if 0 @@ -835,12 +843,13 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) counter = 0; /* we need to search all and return the inode with the highest version */ for(b = pL->dir.listHead; b; b = b->next, counter++) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); if ((pino == jDir->pino) && (len == jDir->nsize) && (jDir->ino) && /* 0 for unlink */ (!strncmp((char *)jDir->name, name, len))) { /* a match */ if (jDir->version < version) { - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); continue; } @@ -862,7 +871,7 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) putLabeledWord("b = ", (u32) b); putLabeledWord("counter = ", counter); #endif - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } return inode; } @@ -956,7 +965,8 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) struct jffs2_raw_dirent *jDir; for (b = pL->dir.listHead; b; b = b->next) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ u32 i_version = 0; struct jffs2_raw_inode ojNode; @@ -969,20 +979,23 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) if (jNode->ino == jDir->ino && jNode->version >= i_version) { i_version = jNode->version; if (i) - put_fl_mem(i); + put_fl_mem(i, NULL); if (jDir->type == DT_LNK) - i = get_node_mem(b2->offset); + i = get_node_mem(b2->offset, + NULL); else - i = get_fl_mem(b2->offset, sizeof(*i), NULL); + i = get_fl_mem(b2->offset, + sizeof(*i), + NULL); } b2 = b2->next; } dump_inode(pL, jDir, i); - put_fl_mem(i); + put_fl_mem(i, NULL); } - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } return pino; } @@ -1060,10 +1073,11 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) /* we need to search all and return the inode with the highest version */ for(b = pL->dir.listHead; b; b = b->next) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); if (ino == jDir->ino) { if (jDir->version < version) { - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); continue; } @@ -1080,7 +1094,7 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) jDirFoundPino = jDir->pino; version = jDir->version; } - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } /* now we found the right entry again. (shoulda returned inode*) */ if (jDirFoundType != DT_LNK) @@ -1089,7 +1103,8 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) /* it's a soft link so we follow it again. */ b2 = pL->frag.listHead; while (b2) { - jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset); + jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset, + pL->readbuf); if (jNode->ino == jDirFoundIno) { src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode); @@ -1101,11 +1116,11 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) #endif strncpy(tmp, (char *)src, jNode->dsize); tmp[jNode->dsize] = '\0'; - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); break; } b2 = b2->next; - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); } /* ok so the name of the new file to find is in tmp */ /* if it starts with a slash it is root based else shared dirs */ @@ -1240,7 +1255,8 @@ dump_dirents(struct b_lists *pL) putstr("\r\n\r\n******The directory Entries******\r\n"); b = pL->dir.listHead; while (b) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); putstr("\r\n"); putnstr(jDir->name, jDir->nsize); putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); @@ -1256,7 +1272,7 @@ dump_dirents(struct b_lists *pL) putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ b = b->next; - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } } #endif @@ -1286,6 +1302,7 @@ jffs2_1pass_build_lists(struct part_info * part) u32 counter4 = 0; u32 counterF = 0; u32 counterN = 0; + u32 max_totlen = 0; u32 buf_size = DEFAULT_EMPTY_SCAN_SIZE; char *buf; @@ -1415,6 +1432,8 @@ jffs2_1pass_build_lists(struct part_info * part) if (insert_node(&pL->frag, (u32) part->offset + ofs) == NULL) return 0; + if (max_totlen < node->totlen) + max_totlen = node->totlen; break; case JFFS2_NODETYPE_DIRENT: if (buf_ofs + buf_len < ofs + sizeof(struct @@ -1440,6 +1459,8 @@ jffs2_1pass_build_lists(struct part_info * part) if (insert_node(&pL->dir, (u32) part->offset + ofs) == NULL) return 0; + if (max_totlen < node->totlen) + max_totlen = node->totlen; counterN++; break; case JFFS2_NODETYPE_CLEANMARKER: @@ -1468,6 +1489,13 @@ jffs2_1pass_build_lists(struct part_info * part) free(buf); putstr("\b\b done.\r\n"); /* close off the dots */ + + /* We don't care if malloc failed - then each read operation will + * allocate its own buffer as necessary (NAND) or will read directly + * from flash (NOR). + */ + pL->readbuf = malloc(max_totlen); + /* turn the lcd back on. */ /* splash(); */ diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index 9745762..3633dea 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -24,7 +24,7 @@ struct b_list { struct b_lists { struct b_list dir; struct b_list frag; - + void *readbuf; }; struct b_compr_info { -- cgit v1.1 From 9b7076229ec6a958bd835ab70745f7676297ce82 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 13 Nov 2008 19:49:35 +0300 Subject: jffs2: summary support This patch adds support for reading fs information from summary node instead of scanning full eraseblock. Signed-off-by: Ilya Yanok --- fs/jffs2/jffs2_1pass.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++- fs/jffs2/summary.h | 163 ++++++++++++++++++++++++++++++++++++++++++ include/jffs2/jffs2.h | 19 +++++ 3 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 fs/jffs2/summary.h diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 73d3ddc..4e49a05 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -138,6 +138,8 @@ # define DEBUGF(fmt,args...) #endif +#include "summary.h" + /* keeps pointer to currentlu processed partition */ static struct part_info *current_part; @@ -1214,6 +1216,132 @@ jffs2_1pass_rescan_needed(struct part_info *part) return 0; } +#define dbg_summary(...) do {} while (0); +/* Process the stored summary information - helper function for + * jffs2_sum_scan_sumnode() + */ + +static int jffs2_sum_process_sum_data(struct part_info *part, uint32_t offset, + struct jffs2_raw_summary *summary, + struct b_lists *pL) +{ + void *sp; + int i; + + sp = summary->sum; + + for (i = 0; i < summary->sum_num; i++) { + dbg_summary("processing summary index %d\n", i); + + switch (((struct jffs2_sum_unknown_flash *)sp)->nodetype) { + case JFFS2_NODETYPE_INODE: { + struct jffs2_sum_inode_flash *spi; + spi = sp; + + dbg_summary("Inode at 0x%08x-0x%08x\n", + offset + spi->offset, + offset + spi->offset + spi->totlen); + + if (insert_node(&pL->frag, (u32) part->offset + + offset + spi->offset) == NULL) + return -1; + + sp += JFFS2_SUMMARY_INODE_SIZE; + + break; + } + + case JFFS2_NODETYPE_DIRENT: { + struct jffs2_sum_dirent_flash *spd; + spd = sp; + + dbg_summary("Dirent at 0x%08x-0x%08x\n", + offset + spd->offset, + offset + spd->offset + spd->totlen); + + if (insert_node(&pL->dir, (u32) part->offset + + offset + spd->offset) == NULL) + return -1; + + sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize); + + break; + } + default : { + uint16_t nodetype = + ((struct jffs2_sum_unknown_flash *) + sp)->nodetype; + printf("Unsupported node type %x found in " + "summary!\n", nodetype); + break; + } + } + } + return 0; +} + +/* Process the summary node - called from jffs2_scan_eraseblock() */ +int jffs2_sum_scan_sumnode(struct part_info *part, uint32_t offset, + struct jffs2_raw_summary *summary, uint32_t sumsize, + struct b_lists *pL) +{ + struct jffs2_unknown_node crcnode; + int ret, ofs; + uint32_t crc; + + ofs = part->sector_size - sumsize; + + dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", + offset, offset + ofs, sumsize); + + /* OK, now check for node validity and CRC */ + crcnode.magic = JFFS2_MAGIC_BITMASK; + crcnode.nodetype = JFFS2_NODETYPE_SUMMARY; + crcnode.totlen = summary->totlen; + crc = crc32_no_comp(0, (uchar *)&crcnode, sizeof(crcnode)-4); + + if (summary->hdr_crc != crc) { + dbg_summary("Summary node header is corrupt (bad CRC or " + "no summary at all)\n"); + goto crc_err; + } + + if (summary->totlen != sumsize) { + dbg_summary("Summary node is corrupt (wrong erasesize?)\n"); + goto crc_err; + } + + crc = crc32_no_comp(0, (uchar *)summary, + sizeof(struct jffs2_raw_summary)-8); + + if (summary->node_crc != crc) { + dbg_summary("Summary node is corrupt (bad CRC)\n"); + goto crc_err; + } + + crc = crc32_no_comp(0, (uchar *)summary->sum, + sumsize - sizeof(struct jffs2_raw_summary)); + + if (summary->sum_crc != crc) { + dbg_summary("Summary node data is corrupt (bad CRC)\n"); + goto crc_err; + } + + if (summary->cln_mkr) + dbg_summary("Summary : CLEANMARKER node \n"); + + ret = jffs2_sum_process_sum_data(part, offset, summary, pL); + if (ret) + return ret; /* real error */ + + return 1; + +crc_err: + putstr("Summary node crc error, skipping summary information.\n"); + + return 0; +} + #ifdef DEBUG_FRAGMENTS static void dump_fragments(struct b_lists *pL) @@ -1321,10 +1449,65 @@ jffs2_1pass_build_lists(struct part_info * part) for (i = 0; i < nr_sectors; i++) { uint32_t sector_ofs = i * part->sector_size; uint32_t buf_ofs = sector_ofs; - uint32_t buf_len = EMPTY_SCAN_SIZE(part->sector_size); + uint32_t buf_len; uint32_t ofs, prevofs; + struct jffs2_sum_marker *sm; + void *sumptr = NULL; + uint32_t sumlen; + int ret; WATCHDOG_RESET(); + + buf_len = sizeof(*sm); + + /* Read as much as we want into the _end_ of the preallocated + * buffer + */ + get_fl_mem(part->offset + sector_ofs + part->sector_size - + buf_len, buf_len, buf + buf_size - buf_len); + + sm = (void *)buf + buf_size - sizeof(*sm); + if (sm->magic == JFFS2_SUM_MAGIC) { + sumlen = part->sector_size - sm->offset; + sumptr = buf + buf_size - sumlen; + + /* Now, make sure the summary itself is available */ + if (sumlen > buf_size) { + /* Need to kmalloc for this. */ + sumptr = malloc(sumlen); + if (!sumptr) { + putstr("Can't get memory for summary " + "node!\n"); + return 0; + } + memcpy(sumptr + sumlen - buf_len, buf + + buf_size - buf_len, buf_len); + } + if (buf_len < sumlen) { + /* Need to read more so that the entire summary + * node is present + */ + get_fl_mem(part->offset + sector_ofs + + part->sector_size - sumlen, + sumlen - buf_len, sumptr); + } + } + + if (sumptr) { + ret = jffs2_sum_scan_sumnode(part, sector_ofs, sumptr, + sumlen, pL); + + if (buf_size && sumlen > buf_size) + free(sumptr); + if (ret < 0) + return 0; + if (ret) + continue; + + } + + buf_len = EMPTY_SCAN_SIZE(part->sector_size); + get_fl_mem((u32)part->offset + buf_ofs, buf_len, buf); /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ @@ -1477,6 +1660,8 @@ jffs2_1pass_build_lists(struct part_info * part) node->totlen, sizeof(struct jffs2_unknown_node)); break; + case JFFS2_NODETYPE_SUMMARY: + break; default: printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h new file mode 100644 index 0000000..834933c --- /dev/null +++ b/fs/jffs2/summary.h @@ -0,0 +1,163 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright © 2004 Ferenc Havasi , + * Zoltan Sogor , + * Patrik Kluba , + * University of Szeged, Hungary + * + * For licensing information, see the file 'LICENCE' in this directory. + * + */ + +#ifndef JFFS2_SUMMARY_H +#define JFFS2_SUMMARY_H + +#define BLK_STATE_ALLFF 0 +#define BLK_STATE_CLEAN 1 +#define BLK_STATE_PARTDIRTY 2 +#define BLK_STATE_CLEANMARKER 3 +#define BLK_STATE_ALLDIRTY 4 +#define BLK_STATE_BADBLOCK 5 + +#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff +#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash)) +#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x)) +#define JFFS2_SUMMARY_XATTR_SIZE (sizeof(struct jffs2_sum_xattr_flash)) +#define JFFS2_SUMMARY_XREF_SIZE (sizeof(struct jffs2_sum_xref_flash)) + +/* Summary structures used on flash */ + +struct jffs2_sum_unknown_flash +{ + __u16 nodetype; /* node type */ +}; + +struct jffs2_sum_inode_flash +{ + __u16 nodetype; /* node type */ + __u32 inode; /* inode number */ + __u32 version; /* inode version */ + __u32 offset; /* offset on jeb */ + __u32 totlen; /* record length */ +} __attribute__((packed)); + +struct jffs2_sum_dirent_flash +{ + __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */ + __u32 totlen; /* record length */ + __u32 offset; /* offset on jeb */ + __u32 pino; /* parent inode */ + __u32 version; /* dirent version */ + __u32 ino; /* == zero for unlink */ + uint8_t nsize; /* dirent name size */ + uint8_t type; /* dirent type */ + uint8_t name[0]; /* dirent name */ +} __attribute__((packed)); + +struct jffs2_sum_xattr_flash +{ + __u16 nodetype; /* == JFFS2_NODETYPE_XATR */ + __u32 xid; /* xattr identifier */ + __u32 version; /* version number */ + __u32 offset; /* offset on jeb */ + __u32 totlen; /* node length */ +} __attribute__((packed)); + +struct jffs2_sum_xref_flash +{ + __u16 nodetype; /* == JFFS2_NODETYPE_XREF */ + __u32 offset; /* offset on jeb */ +} __attribute__((packed)); + +union jffs2_sum_flash +{ + struct jffs2_sum_unknown_flash u; + struct jffs2_sum_inode_flash i; + struct jffs2_sum_dirent_flash d; + struct jffs2_sum_xattr_flash x; + struct jffs2_sum_xref_flash r; +}; + +/* Summary structures used in the memory */ + +struct jffs2_sum_unknown_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; /* node type */ +}; + +struct jffs2_sum_inode_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; /* node type */ + __u32 inode; /* inode number */ + __u32 version; /* inode version */ + __u32 offset; /* offset on jeb */ + __u32 totlen; /* record length */ +} __attribute__((packed)); + +struct jffs2_sum_dirent_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */ + __u32 totlen; /* record length */ + __u32 offset; /* ofset on jeb */ + __u32 pino; /* parent inode */ + __u32 version; /* dirent version */ + __u32 ino; /* == zero for unlink */ + uint8_t nsize; /* dirent name size */ + uint8_t type; /* dirent type */ + uint8_t name[0]; /* dirent name */ +} __attribute__((packed)); + +struct jffs2_sum_xattr_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; + __u32 xid; + __u32 version; + __u32 offset; + __u32 totlen; +} __attribute__((packed)); + +struct jffs2_sum_xref_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; + __u32 offset; +} __attribute__((packed)); + +union jffs2_sum_mem +{ + struct jffs2_sum_unknown_mem u; + struct jffs2_sum_inode_mem i; + struct jffs2_sum_dirent_mem d; + struct jffs2_sum_xattr_mem x; + struct jffs2_sum_xref_mem r; +}; + +/* Summary related information stored in superblock */ + +struct jffs2_summary +{ + uint32_t sum_size; /* collected summary information for nextblock */ + uint32_t sum_num; + uint32_t sum_padded; + union jffs2_sum_mem *sum_list_head; + union jffs2_sum_mem *sum_list_tail; + + __u32 *sum_buf; /* buffer for writing out summary */ +}; + +/* Summary marker is stored at the end of every sumarized erase block */ + +struct jffs2_sum_marker +{ + __u32 offset; /* offset of the summary node in the jeb */ + __u32 magic; /* == JFFS2_SUM_MAGIC */ +}; + +#define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker)) + +#endif /* JFFS2_SUMMARY_H */ diff --git a/include/jffs2/jffs2.h b/include/jffs2/jffs2.h index d142cd1..ed96bab 100644 --- a/include/jffs2/jffs2.h +++ b/include/jffs2/jffs2.h @@ -50,6 +50,9 @@ #define JFFS2_EMPTY_BITMASK 0xffff #define JFFS2_DIRTY_BITMASK 0x0000 +/* Summary node MAGIC marker */ +#define JFFS2_SUM_MAGIC 0x02851885 + /* We only allow a single char for length, and 0xFF is empty flash so we don't want it confused with a real length. Hence max 254. */ @@ -89,6 +92,7 @@ #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) #define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) +#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6) /* Maybe later... */ /*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */ @@ -166,9 +170,24 @@ struct jffs2_raw_inode /* __u8 data[dsize]; */ } __attribute__((packed)); +struct jffs2_raw_summary +{ + __u16 magic; + __u16 nodetype; /* = JFFS2_NODETYPE_SUMMARY */ + __u32 totlen; + __u32 hdr_crc; + __u32 sum_num; /* number of sum entries*/ + __u32 cln_mkr; /* clean marker size, 0 = no cleanmarker */ + __u32 padded; /* sum of the size of padding nodes */ + __u32 sum_crc; /* summary information crc */ + __u32 node_crc; /* node crc */ + __u32 sum[0]; /* inode summary info */ +}; + union jffs2_node_union { struct jffs2_raw_inode i; struct jffs2_raw_dirent d; + struct jffs2_raw_summary s; struct jffs2_unknown_node u; } __attribute__((packed)); -- cgit v1.1 From 142a80ffc3b537a9c45acd2444a42a77f147c602 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 13 Nov 2008 19:49:36 +0300 Subject: jffs2: cache data_crc results As we moved data_crc() invocation from jffs2_1pass_build_lists() to jffs2_1pass_read_inode() data_crc is going to be calculated on each inode access. This patch adds caching of data_crc() results. There is no significant improvement in speed (because of flash access caching added in previous patch I think, crc in RAM is really fast) but this patch impacts memory usage -- every b_node structure uses 12 bytes instead of 8. Signed-off-by: Alexey Neyman Signed-off-by: Ilya Yanok --- fs/jffs2/jffs2_1pass.c | 5 ++++- fs/jffs2/jffs2_private.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 4e49a05..be7c1a1 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -765,7 +765,10 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) put_fl_mem(jNode, pL->readbuf); continue; } - if (!data_crc(jNode)) { + if (b->datacrc == CRC_UNKNOWN) + b->datacrc = data_crc(jNode) ? + CRC_OK : CRC_BAD; + if (b->datacrc == CRC_BAD) { put_fl_mem(jNode, pL->readbuf); continue; } diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index 3633dea..658b325 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -7,6 +7,7 @@ struct b_node { u32 offset; struct b_node *next; + enum { CRC_UNKNOWN = 0, CRC_OK, CRC_BAD } datacrc; }; struct b_list { -- cgit v1.1 From c034075a713b60e654c64e88e87da29440f31bb4 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 12 Nov 2008 13:30:10 +0100 Subject: serial: Add vcth UART driver This patch adds the UART driver for the upcoming VCTH board support. Signed-off-by: Stefan Roese --- drivers/serial/Makefile | 1 + drivers/serial/vcth.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100755 drivers/serial/vcth.c diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index eafe543..17235ff 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -38,6 +38,7 @@ COBJS-$(CONFIG_PL011_SERIAL) += serial_pl01x.o COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o COBJS-$(CONFIG_USB_TTY) += usbtty.o +COBJS-$(CONFIG_VCTH_SERIAL) += vcth.o COBJS := $(sort $(COBJS-y)) SRCS := $(COBJS:.o=.c) diff --git a/drivers/serial/vcth.c b/drivers/serial/vcth.c new file mode 100755 index 0000000..2c847d0 --- /dev/null +++ b/drivers/serial/vcth.c @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2008 Stefan Roese , DENX Software Engineering + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define UART_1_BASE 0xBF89C000 + +#define UART_RBR_OFF 0x00 /* receiver buffer reg */ +#define UART_THR_OFF 0x00 /* transmit holding reg */ +#define UART_DLL_OFF 0x00 /* divisor latch low reg */ +#define UART_IER_OFF 0x04 /* interrupt enable reg */ +#define UART_DLH_OFF 0x04 /* receiver buffer reg */ +#define UART_FCR_OFF 0x08 /* fifo control register */ +#define UART_LCR_OFF 0x0c /* line control register */ +#define UART_MCR_OFF 0x10 /* modem control register */ +#define UART_LSR_OFF 0x14 /* line status register */ +#define UART_MSR_OFF 0x18 /* modem status register */ +#define UART_SCR_OFF 0x1c /* scratch pad register */ + +#define UART_RCV_DATA_RDY 0x01 /* Data Received */ +#define UART_XMT_HOLD_EMPTY 0x20 +#define UART_TRANSMIT_EMPTY 0x40 + +/* 7 bit on line control reg. enalbing rw to dll and dlh */ +#define UART_LCR_DLAB 0x0080 + +#define UART___9600_BDR 0x84 +#define UART__19200_BDR 0x42 +#define UART_115200_BDR 0x08 + +#define UART_DIS_ALL_INTER 0x00 /* disable all interrupts */ + +#define UART_5DATA_BITS 0x0000 /* 5 [bits] 1.5 bits 2 */ +#define UART_6DATA_BITS 0x0001 /* 6 [bits] 1 bits 2 */ +#define UART_7DATA_BITS 0x0002 /* 7 [bits] 1 bits 2 */ +#define UART_8DATA_BITS 0x0003 /* 8 [bits] 1 bits 2 */ + +static void vcth_uart_set_baud_rate(u32 address, u32 dh, u32 dl) +{ + u32 val = __raw_readl(UART_1_BASE + UART_LCR_OFF); + + /* set 7 bit on 1 */ + val |= UART_LCR_DLAB; + __raw_writel(val, UART_1_BASE + UART_LCR_OFF); + + __raw_writel(dl, UART_1_BASE + UART_DLL_OFF); + __raw_writel(dh, UART_1_BASE + UART_DLH_OFF); + + /* set 7 bit on 0 */ + val &= ~UART_LCR_DLAB; + __raw_writel(val, UART_1_BASE + UART_LCR_OFF); + + return; +} + +int serial_init(void) +{ + __raw_writel(UART_DIS_ALL_INTER, UART_1_BASE + UART_IER_OFF); + vcth_uart_set_baud_rate(UART_1_BASE, 0, UART_115200_BDR); + __raw_writel(UART_8DATA_BITS, UART_1_BASE + UART_LCR_OFF); + + return 0; +} + +void serial_setbrg(void) +{ + /* + * Baudrate change not supported currently, fixed to 115200 baud + */ +} + +void serial_putc(const char c) +{ + if (c == '\n') + serial_putc('\r'); + + while (!(UART_XMT_HOLD_EMPTY & __raw_readl(UART_1_BASE + UART_LSR_OFF))) + ; + + __raw_writel(c, UART_1_BASE + UART_THR_OFF); +} + +void serial_puts(const char *s) +{ + while (*s) + serial_putc(*s++); +} + +int serial_getc(void) +{ + while (!(UART_RCV_DATA_RDY & __raw_readl(UART_1_BASE + UART_LSR_OFF))) + ; + + return __raw_readl(UART_1_BASE + UART_RBR_OFF) & 0xff; +} + +int serial_tstc(void) +{ + if (!(UART_RCV_DATA_RDY & __raw_readl(UART_1_BASE + UART_LSR_OFF))) + return 0; + + return 1; +} -- cgit v1.1 From d4f70da544c33db3e4fce6473dea4ecca4322545 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Fri, 21 Nov 2008 06:28:05 +1100 Subject: Fixed build error due to #define of _LINUX_STRING_H_ in 82559_eeprom.c Signed-off-by: Graeme Russ --- examples/82559_eeprom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/82559_eeprom.c b/examples/82559_eeprom.c index d99af26..5e2eee9 100644 --- a/examples/82559_eeprom.c +++ b/examples/82559_eeprom.c @@ -19,7 +19,6 @@ */ #define _PPC_STRING_H_ /* avoid unnecessary str/mem functions */ -#define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */ #include #include -- cgit v1.1 From 1f5070c0c18fa5684bfce09c8abdf10c04ed48fa Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sat, 22 Nov 2008 08:43:21 +1100 Subject: Fixed path to sc520 SSI include file Signed Off By: Graeme Russ --- cpu/i386/sc520.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/i386/sc520.c b/cpu/i386/sc520.c index 8bcb979..cb6bc03 100644 --- a/cpu/i386/sc520.c +++ b/cpu/i386/sc520.c @@ -32,7 +32,7 @@ #include #include #ifdef CONFIG_SC520_SSI -#include +#include #endif #include #include -- cgit v1.1 From 1fc2b165c51d6f40c8d505f1b3eaefdb6599b17b Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sat, 22 Nov 2008 08:43:29 +1100 Subject: Moved sc520 PCI definitions to stand-alone file Signed Off By: Graeme Russ --- include/asm-i386/ic/pci.h | 49 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-i386/ic/sc520.h | 22 -------------------- 2 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 include/asm-i386/ic/pci.h diff --git a/include/asm-i386/ic/pci.h b/include/asm-i386/ic/pci.h new file mode 100644 index 0000000..bcccdbe --- /dev/null +++ b/include/asm-i386/ic/pci.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2002 + * Daniel Engstrm, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_IC_SC520_PCI_H_ +#define _ASM_IC_SC520_PCI_H_ 1 + +/* pin number used for PCI interrupt mappings */ +#define SC520_PCI_INTA 0 +#define SC520_PCI_INTB 1 +#define SC520_PCI_INTC 2 +#define SC520_PCI_INTD 3 +#define SC520_PCI_GPIRQ0 4 +#define SC520_PCI_GPIRQ1 5 +#define SC520_PCI_GPIRQ2 6 +#define SC520_PCI_GPIRQ3 7 +#define SC520_PCI_GPIRQ4 8 +#define SC520_PCI_GPIRQ5 9 +#define SC520_PCI_GPIRQ6 10 +#define SC520_PCI_GPIRQ7 11 +#define SC520_PCI_GPIRQ8 12 +#define SC520_PCI_GPIRQ9 13 +#define SC520_PCI_GPIRQ10 14 + +extern int sc520_pci_ints[]; + +void pci_sc520_init(struct pci_controller *hose); +int pci_sc520_set_irq(int pci_pin, int irq); + +#endif diff --git a/include/asm-i386/ic/sc520.h b/include/asm-i386/ic/sc520.h index 0f7e7a5..bf39516 100644 --- a/include/asm-i386/ic/sc520.h +++ b/include/asm-i386/ic/sc520.h @@ -282,24 +282,6 @@ #define SC520_IRQ14 9 #define SC520_IRQ15 10 - -/* pin number used for PCI interrupt mappings */ -#define SC520_PCI_INTA 0 -#define SC520_PCI_INTB 1 -#define SC520_PCI_INTC 2 -#define SC520_PCI_INTD 3 -#define SC520_PCI_GPIRQ0 4 -#define SC520_PCI_GPIRQ1 5 -#define SC520_PCI_GPIRQ2 6 -#define SC520_PCI_GPIRQ3 7 -#define SC520_PCI_GPIRQ4 8 -#define SC520_PCI_GPIRQ5 9 -#define SC520_PCI_GPIRQ6 10 -#define SC520_PCI_GPIRQ7 11 -#define SC520_PCI_GPIRQ8 12 -#define SC520_PCI_GPIRQ9 13 -#define SC520_PCI_GPIRQ10 14 - /* utility functions */ void write_mmcr_byte(u16 mmcr, u8 data); void write_mmcr_word(u16 mmcr, u16 data); @@ -308,11 +290,7 @@ u8 read_mmcr_byte(u16 mmcr); u16 read_mmcr_word(u16 mmcr); u32 read_mmcr_long(u16 mmcr); -extern int sc520_pci_ints[]; - void init_sc520(void); unsigned long init_sc520_dram(void); -void pci_sc520_init(struct pci_controller *hose); -int pci_sc520_set_irq(int pci_pin, int irq); #endif -- cgit v1.1 From 97a24a78ee6f34b89b821cb70eda1cf34aa11d97 Mon Sep 17 00:00:00 2001 From: Jerry Van Baren Date: Mon, 24 Nov 2008 08:15:02 -0500 Subject: libfdt: Fix redefined uintptr_t warning for USE_HOSTCC Compiling U-Boot in an old OS environment (RedHat-7.3 :-) gives the following warnings from FDT: include/libfdt_env.h:50: warning: redefinition of 'uintptr_t' /usr/include/stdint.h:129: warning: 'uintptr_t' previously declared here Fix: Protect the definition of uintptr_t when compiling on the host system. Signed-off-by: Gerald Van Baren --- include/libfdt_env.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/libfdt_env.h b/include/libfdt_env.h index 355ebf2..ea474a5 100644 --- a/include/libfdt_env.h +++ b/include/libfdt_env.h @@ -47,6 +47,7 @@ extern struct fdt_header *working_fdt; /* Pointer to the working fdt */ #define cpu_to_fdt64(x) (x) #endif +#ifndef USE_HOSTCC /* * Types for `void *' pointers. * @@ -58,5 +59,6 @@ typedef unsigned long int uintptr_t; #else typedef unsigned int uintptr_t; #endif +#endif /* not USE_HOSTCC */ #endif /* _LIBFDT_ENV_H */ -- cgit v1.1 From 8c5170a7d088601d5f30d85093388dab1f1e8ec0 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 9 Dec 2008 23:20:18 -0500 Subject: fs/fat: handle FAT on SATA The FAT file system driver should also handle FAT on SATA devices. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger --- fs/fat/fat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 06eabc3..a9dde7d 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -84,6 +84,7 @@ fat_register_device(block_dev_desc_t *dev_desc, int part_no) return -1; } #if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ @@ -980,12 +981,14 @@ file_fat_detectfs(void) return 1; } #if defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) printf("Interface: "); switch(cur_dev->if_type) { case IF_TYPE_IDE : printf("IDE"); break; + case IF_TYPE_SATA : printf("SATA"); break; case IF_TYPE_SCSI : printf("SCSI"); break; case IF_TYPE_ATAPI : printf("ATAPI"); break; case IF_TYPE_USB : printf("USB"); break; -- cgit v1.1 From bcb6dd9187d4b23c748704767bd12d20c829e996 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Dec 2008 23:20:31 -0500 Subject: tools/netconsole: new script for working with netconsole over UDP While the doc/README.NetConsole does have a snippet for people to create their own netcat script, it's a lot easier to make a simple dedicated script and tell people to use it. Also spruce it up a bit to make it user friendly. Signed-off-by: Mike Frysinger --- doc/README.NetConsole | 18 ++++-------------- tools/netconsole | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) create mode 100755 tools/netconsole diff --git a/doc/README.NetConsole b/doc/README.NetConsole index fea8e33..94c8816 100644 --- a/doc/README.NetConsole +++ b/doc/README.NetConsole @@ -22,21 +22,11 @@ For example, if your server IP is 192.168.1.1, you could use: On the host side, please use this script to access the console: -+++++++++++++++++++++++++++++++++++++++++++ -#! /bin/bash - -[ $# = 1 ] || { echo "Usage: $0 target_ip" >&2 ; exit 1 ; } -TARGET_IP=$1 + tools/netconsole [port] -stty -icanon -echo intr ^T -nc -u -l -p 6666 < /dev/null & -nc -u ${TARGET_IP} 6666 -stty icanon echo intr ^C -+++++++++++++++++++++++++++++++++++++++++++ - -The script expects exactly one argument, which is interpreted as the -target IP address (or host name, assuming DNS is working). The script -can be interrupted by pressing ^T (CTRL-T). +The script uses netcat to talk to the board over UDP. It requires you to +specify the target IP address (or host name, assuming DNS is working). The +script can be interrupted by pressing ^T (CTRL-T). Be aware that in some distributives (Fedora Core 5 at least) usage of nc has been changed and -l and -p options are considered diff --git a/tools/netconsole b/tools/netconsole new file mode 100755 index 0000000..09c8981 --- /dev/null +++ b/tools/netconsole @@ -0,0 +1,42 @@ +#!/bin/sh + +usage() { + ( + echo "Usage: $0 [board port]" + echo "" + echo "If port is not specified, '6666' will be used" + [ -z "$*" ] && exit 0 + echo "" + echo "ERROR: $*" + exit 1 + ) 1>&2 + exit $? +} + +while [ -n "$1" ] ; do + case $1 in + -h|--help) usage;; + --) break;; + -*) usage "Invalid option $1";; + *) break;; + esac + shift +done + +ip=$1 +port=${2:-6666} + +if [ -z "${ip}" ] || [ -n "$3" ] ; then + usage "Invalid number of arguments" +fi + +for nc in netcat nc ; do + type ${nc} >/dev/null && break +done + +trap "stty icanon echo intr ^C" 0 2 3 5 10 13 15 +echo "NOTE: the interrupt signal (normally ^C) has been remapped to ^T" + +stty -icanon -echo intr ^T +${nc} -u -l -p ${port} < /dev/null & +exec ${nc} -u ${ip} ${port} -- cgit v1.1 From c85ff0553a8cfbcca51c15b947e1ed55d3810a39 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 24 Nov 2008 11:38:22 +0100 Subject: microblaze: Set up relocation is done --- lib_microblaze/board.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_microblaze/board.c b/lib_microblaze/board.c index 250972c..4f48341 100644 --- a/lib_microblaze/board.c +++ b/lib_microblaze/board.c @@ -120,6 +120,7 @@ void board_init (void) bd->bi_baudrate = CONFIG_BAUDRATE; bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ /* Initialise malloc() area */ mem_malloc_init (); -- cgit v1.1 From e7d591e823a991513833af7030468409e25a3b13 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 24 Nov 2008 11:43:00 +0100 Subject: microblaze: Fix ml401 uart16550 setting Signed-off-by: Michal Simek --- include/configs/ml401.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/configs/ml401.h b/include/configs/ml401.h index 63d07ff..b31c4b5 100644 --- a/include/configs/ml401.h +++ b/include/configs/ml401.h @@ -37,17 +37,20 @@ #define CONFIG_SERIAL_BASE XILINX_UARTLITE_BASEADDR #define CONFIG_BAUDRATE XILINX_UARTLITE_BAUDRATE #define CONFIG_SYS_BAUDRATE_TABLE { CONFIG_BAUDRATE } -#else -#ifdef XILINX_UART16550_BASEADDR -#define CONFIG_SYS_NS16550 +#elif XILINX_UART16550_BASEADDR +#define CONFIG_SYS_NS16550 1 #define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE 4 +#define CONFIG_SYS_NS16550_REG_SIZE -4 #define CONFIG_CONS_INDEX 1 -#define CONFIG_SYS_NS16550_COM1 XILINX_UART16550_BASEADDR +#define CONFIG_SYS_NS16550_COM1 (XILINX_UART16550_BASEADDR + 0x1000 + 0x3) #define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ #define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 115200 } -#endif + +/* The following table includes the supported baudrates */ +#define CONFIG_SYS_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400} +#else +#error Undefined uart #endif /* setting reset address */ -- cgit v1.1 From 99ba6f353582720defff6e6e6761dc455a207d31 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 24 Nov 2008 18:25:41 +0100 Subject: microblaze: Remove CONFIG_LIBFDT due to error in common files --- include/configs/ml401.h | 1 - include/configs/xupv2p.h | 1 - 2 files changed, 2 deletions(-) diff --git a/include/configs/ml401.h b/include/configs/ml401.h index b31c4b5..c802dcb 100644 --- a/include/configs/ml401.h +++ b/include/configs/ml401.h @@ -277,6 +277,5 @@ "1m(romfs),1m(cramfs),-(jffs2)\0" #define CONFIG_CMDLINE_EDITING -#define CONFIG_OF_LIBFDT 1 #endif /* __CONFIG_H */ diff --git a/include/configs/xupv2p.h b/include/configs/xupv2p.h index 6a92703..ed844bf 100644 --- a/include/configs/xupv2p.h +++ b/include/configs/xupv2p.h @@ -222,6 +222,5 @@ #endif #define CONFIG_CMDLINE_EDITING -#define CONFIG_OF_LIBFDT 1 /* flat device tree */ #endif /* __CONFIG_H */ -- cgit v1.1 From 8fab49ea911fe925392fa5afcc9bc7373a3d0cee Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 25 Nov 2008 11:42:20 +0100 Subject: microblaze: Remove XUPV2P board --- Microblaze platforms use generic settings and to have many platforms is confusing that's why I decided to remove this platform from U-BOOT. ml401 tree is sufficient for covering all Microblaze platforms. This change will go through microblaze custodian tree. --- MAINTAINERS | 1 - MAKEALL | 1 - Makefile | 5 - board/xilinx/xupv2p/Makefile | 50 --------- board/xilinx/xupv2p/config.mk | 32 ------ board/xilinx/xupv2p/u-boot.lds | 68 ------------ board/xilinx/xupv2p/xparameters.h | 58 ---------- board/xilinx/xupv2p/xupv2p.c | 49 --------- include/configs/xupv2p.h | 226 -------------------------------------- 9 files changed, 490 deletions(-) delete mode 100644 board/xilinx/xupv2p/Makefile delete mode 100644 board/xilinx/xupv2p/config.mk delete mode 100644 board/xilinx/xupv2p/u-boot.lds delete mode 100644 board/xilinx/xupv2p/xparameters.h delete mode 100644 board/xilinx/xupv2p/xupv2p.c delete mode 100644 include/configs/xupv2p.h diff --git a/MAINTAINERS b/MAINTAINERS index 127604b..f048795 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -704,7 +704,6 @@ Yasushi Shoji Michal Simek ML401 MicroBlaze - XUPV2P MicroBlaze ######################################################################### # Coldfire Systems: # diff --git a/MAKEALL b/MAKEALL index a16549c..cc49a98 100755 --- a/MAKEALL +++ b/MAKEALL @@ -698,7 +698,6 @@ LIST_nios2=" \ LIST_microblaze=" \ ml401 \ suzaku \ - xupv2p \ " ######################################################################### diff --git a/Makefile b/Makefile index f8fe29c..ca91f05 100644 --- a/Makefile +++ b/Makefile @@ -3153,11 +3153,6 @@ suzaku_config: unconfig @echo "#define CONFIG_SUZAKU 1" > $(obj)include/config.h @$(MKCONFIG) -a $(@:_config=) microblaze microblaze suzaku AtmarkTechno -xupv2p_config: unconfig - @mkdir -p $(obj)include - @echo "#define CONFIG_XUPV2P 1" > $(obj)include/config.h - @$(MKCONFIG) -a $(@:_config=) microblaze microblaze xupv2p xilinx - #======================================================================== # Blackfin #======================================================================== diff --git a/board/xilinx/xupv2p/Makefile b/board/xilinx/xupv2p/Makefile deleted file mode 100644 index 10b47b2..0000000 --- a/board/xilinx/xupv2p/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program 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. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(BOARD).a - -COBJS = $(BOARD).o - -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) - -$(LIB): $(OBJS) $(SOBJS) - $(AR) $(ARFLAGS) $@ $^ - -clean: - rm -f $(SOBJS) $(OBJS) - -distclean: clean - rm -f $(LIB) core *.bak $(obj).depend - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/board/xilinx/xupv2p/config.mk b/board/xilinx/xupv2p/config.mk deleted file mode 100644 index c07b0b3..0000000 --- a/board/xilinx/xupv2p/config.mk +++ /dev/null @@ -1,32 +0,0 @@ -# -# (C) Copyright 2007 Michal Simek -# -# Michal SIMEK -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program 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. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -# CAUTION: This file is automatically generated by libgen. -# Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 -# - -TEXT_BASE = 0x38000000 - -PLATFORM_CPPFLAGS += -mno-xl-soft-mul -PLATFORM_CPPFLAGS += -mno-xl-soft-div -PLATFORM_CPPFLAGS += -mxl-barrel-shift diff --git a/board/xilinx/xupv2p/u-boot.lds b/board/xilinx/xupv2p/u-boot.lds deleted file mode 100644 index b38f648..0000000 --- a/board/xilinx/xupv2p/u-boot.lds +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Yasushi SHOJI - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_ARCH(microblaze) -ENTRY(_start) - -SECTIONS -{ - .text ALIGN(0x4): - { - __text_start = .; - cpu/microblaze/start.o (.text) - *(.text) - __text_end = .; - } - - .rodata ALIGN(0x4): - { - __rodata_start = .; - *(.rodata) - __rodata_end = .; - } - - .data ALIGN(0x4): - { - __data_start = .; - *(.data) - __data_end = .; - } - - .u_boot_cmd ALIGN(0x4): - { - . = .; - __u_boot_cmd_start = .; - *(.u_boot_cmd) - __u_boot_cmd_end = .; - } - - .bss ALIGN(0x4): - { - __bss_start = .; - *(.bss) - . = ALIGN(4); - __bss_end = .; - } - __end = . ; -} diff --git a/board/xilinx/xupv2p/xparameters.h b/board/xilinx/xupv2p/xparameters.h deleted file mode 100644 index 9e5ebda..0000000 --- a/board/xilinx/xupv2p/xparameters.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * CAUTION: This file is automatically generated by libgen. - * Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4 - */ - -/* System Clock Frequency */ -#define XILINX_CLOCK_FREQ 100000000 - -/* Interrupt controller is opb_intc_0 */ -#define XILINX_INTC_BASEADDR 0x41200000 -#define XILINX_INTC_NUM_INTR_INPUTS 11 - -/* Timer pheriphery is opb_timer_1 */ -#define XILINX_TIMER_BASEADDR 0x41c00000 -#define XILINX_TIMER_IRQ 1 - -/* Uart pheriphery is RS232_Uart_1 */ -#define XILINX_UARTLITE_BASEADDR 0x40600000 -#define XILINX_UARTLITE_BAUDRATE 115200 - -/* GPIO is LEDs_4Bit*/ -#define XILINX_GPIO_BASEADDR 0x40000000 - -/* FLASH doesn't exist none */ - -/* Main Memory is DDR_256MB_32MX64_rank1_row13_col10_cl2_5 */ -#define XILINX_RAM_START 0x30000000 -#define XILINX_RAM_SIZE 0x10000000 - -/* Sysace Controller is SysACE_CompactFlash */ -#define XILINX_SYSACE_BASEADDR 0x41800000 -#define XILINX_SYSACE_HIGHADDR 0x4180ffff -#define XILINX_SYSACE_MEM_WIDTH 16 - -/* Ethernet controller is Ethernet_MAC */ -#define XILINX_EMACLITE_BASEADDR 0x40C00000 diff --git a/board/xilinx/xupv2p/xupv2p.c b/board/xilinx/xupv2p/xupv2p.c deleted file mode 100644 index b1a76c0..0000000 --- a/board/xilinx/xupv2p/xupv2p.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * - * Michal SIMEK - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This is a board specific file. It's OK to include board specific - * header files */ - -#include -#include - -void do_reset (void) -{ -#ifdef CONFIG_SYS_GPIO_0 - *((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) = - ++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR))); -#endif -#ifdef CONFIG_SYS_RESET_ADDRESS - puts ("Reseting board\n"); - asm ("bra r0"); -#endif -} - -int gpio_init (void) -{ -#ifdef CONFIG_SYS_GPIO_0 - *((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) = 0x0; -#endif - return 0; -} diff --git a/include/configs/xupv2p.h b/include/configs/xupv2p.h deleted file mode 100644 index ed844bf..0000000 --- a/include/configs/xupv2p.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * (C) Copyright 2007-2008 Michal Simek - * - * Michal SIMEK - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "../board/xilinx/xupv2p/xparameters.h" - -#define CONFIG_MICROBLAZE 1 /* MicroBlaze CPU */ -#define CONFIG_XUPV2P 1 - -/* uart */ -#ifdef XILINX_UARTLITE_BASEADDR -#define CONFIG_XILINX_UARTLITE -#define CONFIG_SERIAL_BASE XILINX_UARTLITE_BASEADDR -#define CONFIG_BAUDRATE XILINX_UARTLITE_BAUDRATE -#define CONFIG_SYS_BAUDRATE_TABLE { CONFIG_BAUDRATE } -#else -#ifdef XILINX_UART16550_BASEADDR -#define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE 4 -#define CONFIG_CONS_INDEX 1 -#define CONFIG_SYS_NS16550_COM1 XILINX_UART16550_BASEADDR -#define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ -#define CONFIG_BAUDRATE 115200 -#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 115200 } -#endif -#endif - -/* - * setting reset address - * - * TEXT_BASE is set to place, where the U-BOOT run in RAM, but - * if you want to store U-BOOT in flash, set CONFIG_SYS_RESET_ADDRESS - * to FLASH memory and after loading bitstream jump to FLASH. - * U-BOOT auto-relocate to TEXT_BASE. After RESET command Microblaze - * jump to CONFIG_SYS_RESET_ADDRESS where is the original U-BOOT code. - */ -/* #define CONFIG_SYS_RESET_ADDRESS 0x36000000 */ - -/* ethernet */ -#ifdef XILINX_EMAC_BASEADDR -#define CONFIG_XILINX_EMAC 1 -#define CONFIG_SYS_ENET -#else -#ifdef XILINX_EMACLITE_BASEADDR -#define CONFIG_XILINX_EMACLITE 1 -#define CONFIG_SYS_ENET -#endif -#endif -#undef ET_DEBUG - -/* gpio */ -#ifdef XILINX_GPIO_BASEADDR -#define CONFIG_SYS_GPIO_0 1 -#define CONFIG_SYS_GPIO_0_ADDR XILINX_GPIO_BASEADDR -#endif - -/* interrupt controller */ -#ifdef XILINX_INTC_BASEADDR -#define CONFIG_SYS_INTC_0 1 -#define CONFIG_SYS_INTC_0_ADDR XILINX_INTC_BASEADDR -#define CONFIG_SYS_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS -#endif - -/* timer */ -#ifdef XILINX_TIMER_BASEADDR -#if (XILINX_TIMER_IRQ != -1) -#define CONFIG_SYS_TIMER_0 1 -#define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR -#define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ -#define FREQUENCE XILINX_CLOCK_FREQ -#define CONFIG_SYS_TIMER_0_PRELOAD ( FREQUENCE/1000 ) -#endif -#else -#ifdef XILINX_CLOCK_FREQ -#define CONFIG_XILINX_CLOCK_FREQ XILINX_CLOCK_FREQ -#else -#error BAD CLOCK FREQ -#endif -#endif -/* - * memory layout - Example - * TEXT_BASE = 0x3600_0000; - * CONFIG_SYS_SRAM_BASE = 0x3000_0000; - * CONFIG_SYS_SRAM_SIZE = 0x1000_0000; - * - * CONFIG_SYS_GBL_DATA_OFFSET = 0x3000_0000 + 0x1000_0000 - 0x1000 = 0x3FFF_F000 - * CONFIG_SYS_MONITOR_BASE = 0x3FFF_F000 - 0x40000 = 0x3FFB_F000 - * CONFIG_SYS_MALLOC_BASE = 0x3FFB_F000 - 0x40000 = 0x3FF7_F000 - * - * 0x3000_0000 CONFIG_SYS_SDRAM_BASE - * FREE - * 0x3600_0000 TEXT_BASE - * U-BOOT code - * 0x3602_0000 - * FREE - * - * STACK - * 0x3FF7_F000 CONFIG_SYS_MALLOC_BASE - * MALLOC_AREA 256kB Alloc - * 0x3FFB_F000 CONFIG_SYS_MONITOR_BASE - * MONITOR_CODE 256kB Env - * 0x3FFF_F000 CONFIG_SYS_GBL_DATA_OFFSET - * GLOBAL_DATA 4kB bd, gd - * 0x4000_0000 CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - */ - -/* ddr sdram - main memory */ -#define CONFIG_SYS_SDRAM_BASE XILINX_RAM_START -#define CONFIG_SYS_SDRAM_SIZE XILINX_RAM_SIZE -#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE -#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x1000) - -/* global pointer */ -#define CONFIG_SYS_GBL_DATA_SIZE 0x1000 /* size of global data */ -#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - CONFIG_SYS_GBL_DATA_SIZE) /* start of global data */ - -/* monitor code */ -#define SIZE 0x40000 -#define CONFIG_SYS_MONITOR_LEN SIZE -#define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_GBL_DATA_OFFSET - CONFIG_SYS_MONITOR_LEN) -#define CONFIG_SYS_MONITOR_END (CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) -#define CONFIG_SYS_MALLOC_LEN SIZE -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) - -/* stack */ -#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_MALLOC_BASE - -#define CONFIG_SYS_NO_FLASH 1 -#define CONFIG_ENV_IS_NOWHERE 1 -#define CONFIG_ENV_SIZE 0x1000 -#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) - -/* - * BOOTP options - */ -#define CONFIG_BOOTP_BOOTFILESIZE -#define CONFIG_BOOTP_BOOTPATH -#define CONFIG_BOOTP_GATEWAY -#define CONFIG_BOOTP_HOSTNAME - -/* - * Command line configuration. - */ -#include - -#undef CONFIG_CMD_FLASH -#undef CONFIG_CMD_JFFS2 -#undef CONFIG_CMD_IMLS - -#define CONFIG_CMD_ASKENV -#define CONFIG_CMD_CACHE -#define CONFIG_CMD_IRQ - -#ifndef CONFIG_SYS_ENET - #undef CONFIG_CMD_NET -#else - #define CONFIG_CMD_PING -#endif - -#ifdef XILINX_SYSACE_BASEADDR -#define CONFIG_CMD_EXT2 -#define CONFIG_CMD_FAT -#endif - -/* Miscellaneous configurable options */ -#define CONFIG_SYS_PROMPT "U-Boot-mONStR> " -#define CONFIG_SYS_CBSIZE 512 /* size of console buffer */ -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) /* print buffer size */ -#define CONFIG_SYS_MAXARGS 15 /* max number of command args */ -#define CONFIG_SYS_LONGHELP -#define CONFIG_SYS_LOAD_ADDR 0x12000000 /* default load address */ - -#define CONFIG_BOOTDELAY 30 -#define CONFIG_BOOTARGS "root=romfs" -#define CONFIG_HOSTNAME "xupv2p" -#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm" -#define CONFIG_IPADDR 192.168.0.3 -#define CONFIG_SERVERIP 192.168.0.5 -#define CONFIG_GATEWAYIP 192.168.0.1 -#define CONFIG_ETHADDR 00:E0:0C:00:00:FD - -/* architecture dependent code */ -#define CONFIG_SYS_USR_EXCEP /* user exception */ -#define CONFIG_SYS_HZ 1000 - -#define CONFIG_PREBOOT "echo U-BOOT by mONStR;" \ - "base 0;" \ - "echo" - -/* system ace */ -#ifdef XILINX_SYSACE_BASEADDR -#define CONFIG_SYSTEMACE -/* #define DEBUG_SYSTEMACE */ -#define SYSTEMACE_CONFIG_FPGA -#define CONFIG_SYS_SYSTEMACE_BASE XILINX_SYSACE_BASEADDR -#define CONFIG_SYS_SYSTEMACE_WIDTH XILINX_SYSACE_MEM_WIDTH -#define CONFIG_DOS_PARTITION -#endif - -#define CONFIG_CMDLINE_EDITING - -#endif /* __CONFIG_H */ -- cgit v1.1 From 2145188bea2df8f2b47a87ec3071b55027e8d0ae Mon Sep 17 00:00:00 2001 From: Ben Warren Date: Tue, 9 Dec 2008 23:34:15 -0800 Subject: Fix compile error in building MBX860T. Signed-off-by: Ben Warren --- cpu/mpc8xx/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 40f81ef..2eb848b 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -644,7 +644,7 @@ void reset_8xx_watchdog (volatile immap_t * immr) */ int cpu_eth_init(bd_t *bis) { -#if defined(SCC_ENET) +#if defined(SCC_ENET) && defined(CONFIG_CMD_NET) scc_initialize(bis); #endif #if defined(FEC_ENET) -- cgit v1.1 From 817329351639a8895cd9b87b33aeff043f3d5a44 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 10 Dec 2008 10:28:33 +0100 Subject: UBI: Return -ENOMEM upon failing malloc Return with correct error code (-ENOMEM) from ubi_attach_mtd_dev() upon failing malloc(). Signed-off-by: Stefan Roese --- drivers/mtd/ubi/build.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index bdf75c9..f4b01a9 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -784,19 +784,20 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) if (err) goto out_free; + err = -ENOMEM; ubi->peb_buf1 = vmalloc(ubi->peb_size); if (!ubi->peb_buf1) goto out_free; ubi->peb_buf2 = vmalloc(ubi->peb_size); if (!ubi->peb_buf2) - goto out_free; + goto out_free; #ifdef CONFIG_MTD_UBI_DEBUG mutex_init(&ubi->dbg_buf_mutex); ubi->dbg_peb_buf = vmalloc(ubi->peb_size); if (!ubi->dbg_peb_buf) - goto out_free; + goto out_free; #endif err = attach_by_scanning(ubi); -- cgit v1.1 From 3b089e4f889a2902449d55e081c886ae607cae89 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 10 Dec 2008 10:32:59 +0100 Subject: UBI: Set ubi_dev.type back to DEV_TYPE_NONE upon failing initialization With this patch we set the type back to NONE upon failing UBI partition initialization. Otherwise further calls to the UBI subsystem would try to really access the non-existing UBI partition. Thanks to Michael Lawnick for pointing this out. Signed-off-by: Stefan Roese --- common/cmd_ubi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index fd33a67..4c35892 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -508,6 +508,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name); if (err) { printf("UBI init error %d\n", err); + ubi_dev.type = DEV_TYPE_NONE; return err; } -- cgit v1.1 From 8c92af7b2fbd60ae87379477f93c7ec9441b7452 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 9 Dec 2008 20:08:01 +0100 Subject: ppc4xx: Remove some features from ALPR to fit into 256k again Signed-off-by: Stefan Roese --- include/configs/alpr.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/configs/alpr.h b/include/configs/alpr.h index 6e9f5e5..7ce8205 100644 --- a/include/configs/alpr.h +++ b/include/configs/alpr.h @@ -235,18 +235,15 @@ #define CONFIG_CMD_DHCP #define CONFIG_CMD_DIAG #define CONFIG_CMD_EEPROM -#define CONFIG_CMD_ELF #define CONFIG_CMD_FPGA #define CONFIG_CMD_I2C #define CONFIG_CMD_IRQ #define CONFIG_CMD_MII #define CONFIG_CMD_NAND #define CONFIG_CMD_NET -#define CONFIG_CMD_NFS #define CONFIG_CMD_PCI #define CONFIG_CMD_PING -#define CONFIG_CMD_REGINFO - +#undef CONFIG_CMD_NFS #undef CONFIG_WATCHDOG /* watchdog disabled */ -- cgit v1.1 From 1951f847f0a851853871b613ad7cf21a5242226c Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Wed, 10 Dec 2008 14:41:25 +0100 Subject: ppc4xx: Update TEXT_BASE for CPCI405 boards This patch fixes building U-Boot for CPCI405 boards. Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- Makefile | 5 +---- board/esd/cpci405/config.mk | 6 +----- include/configs/CPCI405.h | 6 +++--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index f8fe29c..2f07657 100644 --- a/Makefile +++ b/Makefile @@ -1261,14 +1261,11 @@ CMS700_config: unconfig CPCI2DP_config: unconfig @$(MKCONFIG) $(@:_config=) ppc ppc4xx cpci2dp esd -CPCI405_config: unconfig - @$(MKCONFIG) $(@:_config=) ppc ppc4xx cpci405 esd - +CPCI405_config \ CPCI4052_config \ CPCI405DT_config \ CPCI405AB_config: unconfig @mkdir -p $(obj)board/esd/cpci405 - @echo "TEXT_BASE = 0xFFFC0000" > $(obj)board/esd/cpci405/config.tmp @$(MKCONFIG) $(@:_config=) ppc ppc4xx cpci405 esd CPCIISER4_config: unconfig diff --git a/board/esd/cpci405/config.mk b/board/esd/cpci405/config.mk index 6cfb891..1bdf5e4 100644 --- a/board/esd/cpci405/config.mk +++ b/board/esd/cpci405/config.mk @@ -21,8 +21,4 @@ # MA 02111-1307 USA # -sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp - -ifndef TEXT_BASE -TEXT_BASE = 0xFFFD0000 -endif +TEXT_BASE = 0xFFFC0000 diff --git a/include/configs/CPCI405.h b/include/configs/CPCI405.h index 1a2bc1c..89ba139 100644 --- a/include/configs/CPCI405.h +++ b/include/configs/CPCI405.h @@ -196,9 +196,9 @@ * Please note that CONFIG_SYS_SDRAM_BASE _must_ start at 0 */ #define CONFIG_SYS_SDRAM_BASE 0x00000000 -#define CONFIG_SYS_FLASH_BASE 0xFFFD0000 -#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE -#define CONFIG_SYS_MONITOR_LEN (192 * 1024) /* Reserve 196 kB for Monitor */ +#define CONFIG_SYS_FLASH_BASE TEXT_BASE +#define CONFIG_SYS_MONITOR_BASE TEXT_BASE +#define CONFIG_SYS_MONITOR_LEN (~(TEXT_BASE) + 1) #define CONFIG_SYS_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */ /* -- cgit v1.1 From 9a1d3557dcd47365c12eeab584b822e57d994352 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 11 Nov 2008 22:20:15 +0100 Subject: sh: fix rsk7203 and MigoR out of tree build Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f8fe29c..91acd14 100644 --- a/Makefile +++ b/Makefile @@ -3210,7 +3210,7 @@ mimc200_config : unconfig rsk7203_config: unconfig @ >include/config.h @echo "#define CONFIG_RSK7203 1" >> include/config.h - @./mkconfig -a $(@:_config=) sh sh2 rsk7203 renesas + @$(MKCONFIG) -a $(@:_config=) sh sh2 rsk7203 renesas ######################################################################### ## sh3 (Renesas SuperH) @@ -3233,7 +3233,7 @@ ms7720se_config: unconfig MigoR_config : unconfig @mkdir -p $(obj)include @echo "#define CONFIG_MIGO_R 1" > $(obj)include/config.h - @./mkconfig -a $(@:_config=) sh sh4 MigoR renesas + @$(MKCONFIG) -a $(@:_config=) sh sh4 MigoR renesas ms7750se_config: unconfig @mkdir -p $(obj)include -- cgit v1.1 From 15e2697c9f7fb2ba672a1a70f07cd6d9d4e92b51 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 17 Nov 2008 16:53:09 +0900 Subject: sh: Update SuperH serial driver The address of SCFSR register is wrong at SH7720/SH7721. This patch fix this. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- drivers/serial/serial_sh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index f30532b..1d76a19 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -94,7 +94,7 @@ # define LSR_ORER 1 # define FIFOLEVEL_MASK 0x1F #elif defined(CONFIG_CPU_SH7720) -# define SCLSR (vu_short *)(SCIF_BASE + 0x24) +# define SCLSR SCFSR # define LSR_ORER 0x0200 # define FIFOLEVEL_MASK 0x1F #elif defined(CONFIG_CPU_SH7710) || \ -- cgit v1.1 From 5783758fd260a02f44566ad8f29f899565cd0403 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 17 Nov 2008 16:52:09 +0900 Subject: sh: Update ms7722se board config Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- include/configs/ms7722se.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/configs/ms7722se.h b/include/configs/ms7722se.h index 9997c9b..5202004 100644 --- a/include/configs/ms7722se.h +++ b/include/configs/ms7722se.h @@ -31,10 +31,13 @@ #define CONFIG_MS7722SE 1 #define CONFIG_CMD_FLASH +#define CONFIG_CMD_JFFS2 #define CONFIG_CMD_NET +#define CONFIG_CMD_NFS #define CONFIG_CMD_PING #define CONFIG_CMD_DFL #define CONFIG_CMD_SDRAM +#define CONFIG_CMD_MEMORY #define CONFIG_CMD_ENV #define CONFIG_BAUDRATE 115200 -- cgit v1.1 From b81786cff476c41e332eaeb679158f6527cd67d4 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 4 Nov 2008 11:58:58 +0900 Subject: sh: Migo-R: Update BSC value A value of BSC CS4 was wrong, Fixed it. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- board/renesas/MigoR/lowlevel_init.S | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/board/renesas/MigoR/lowlevel_init.S b/board/renesas/MigoR/lowlevel_init.S index e48f7b3..4c1900e 100644 --- a/board/renesas/MigoR/lowlevel_init.S +++ b/board/renesas/MigoR/lowlevel_init.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 + * Copyright (C) 2007-2008 * Nobuhiro Iwamatsu * * Copyright (C) 2007 @@ -211,25 +211,25 @@ PFC_PULCR_D: .long 0x6000 PFC_DRVCR_D: .long 0x0464 FRQCR_D: .long 0x07033639 PLLCR_D: .long 0x00005000 -DLLFRQ_D: .long 0x000004F6 ! 20080115 +DLLFRQ_D: .long 0x000004F6 CMNCR_A: .long CMNCR -CMNCR_D: .long 0x0000001B ! 20080115 -CS0BCR_A: .long CS0BCR ! Flash bank 1 +CMNCR_D: .long 0x0000001B +CS0BCR_A: .long CS0BCR CS0BCR_D: .long 0x24920400 -CS4BCR_A: .long CS4BCR ! -CS4BCR_D: .long 0x10003400 ! 20080115 -CS5ABCR_A: .long CS5ABCR ! +CS4BCR_A: .long CS4BCR +CS4BCR_D: .long 0x00003400 +CS5ABCR_A: .long CS5ABCR CS5ABCR_D: .long 0x24920400 -CS5BBCR_A: .long CS5BBCR ! +CS5BBCR_A: .long CS5BBCR CS5BBCR_D: .long 0x24920400 -CS6ABCR_A: .long CS6ABCR ! +CS6ABCR_A: .long CS6ABCR CS6ABCR_D: .long 0x24920400 CS0WCR_A: .long CS0WCR CS0WCR_D: .long 0x00000380 CS4WCR_A: .long CS4WCR -CS4WCR_D: .long 0x00100A81 ! 20080115 +CS4WCR_D: .long 0x00110080 CS5AWCR_A: .long CS5AWCR CS5AWCR_D: .long 0x00000300 CS5BWCR_A: .long CS5BWCR @@ -238,20 +238,20 @@ CS6AWCR_A: .long CS6AWCR CS6AWCR_D: .long 0x00000300 SDCR_A: .long SBSC_SDCR -SDCR_D: .long 0x80160809 ! 20080115 +SDCR_D: .long 0x80160809 SDWCR_A: .long SBSC_SDWCR -SDWCR_D: .long 0x0014450C ! 20080115 +SDWCR_D: .long 0x0014450C SDPCR_A: .long SBSC_SDPCR SDPCR_D: .long 0x00000087 RTCOR_A: .long SBSC_RTCOR RTCNT_A: .long SBSC_RTCNT RTCNT_D: .long 0xA55A0012 -RTCOR_D: .long 0xA55A001C ! 20080115 +RTCOR_D: .long 0xA55A001C RTCSR_A: .long SBSC_RTCSR RFCR_A: .long SBSC_RFCR RFCR_D: .long 0xA55A0221 -RTCSR_D: .long 0xA55A009a ! 20080115 -SDMR3_A: .long 0xFE581180 ! 20080115 +RTCSR_D: .long 0xA55A009a +SDMR3_A: .long 0xFE581180 SR_MASK_D: .long 0xEFFFFF0F @@ -260,5 +260,5 @@ SR_MASK_D: .long 0xEFFFFF0F SBSCR_D: .word 0x0044 PSCR_D: .word 0x0000 RWTCSR_D_1: .word 0xA507 -RWTCSR_D_2: .word 0xA504 ! 20080115 +RWTCSR_D_2: .word 0xA504 RWTCNT_D: .word 0x5A00 -- cgit v1.1 From e9d5f35497885b3c65d494d09a525d443dcccd3b Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 20 Nov 2008 16:44:42 +0900 Subject: sh: Update sh timer function Change to write/readX function and fix timer problem. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- cpu/sh2/Makefile | 2 +- cpu/sh2/time.c | 111 ------------------------------------------------------ cpu/sh3/Makefile | 2 +- cpu/sh3/time.c | 103 -------------------------------------------------- cpu/sh4/Makefile | 2 +- cpu/sh4/time.c | 98 ----------------------------------------------- lib_sh/Makefile | 6 ++- lib_sh/time.c | 83 +++++++++++++++++++++++++++++++--------- lib_sh/time_sh2.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 185 insertions(+), 333 deletions(-) delete mode 100644 cpu/sh2/time.c delete mode 100644 cpu/sh3/time.c delete mode 100644 cpu/sh4/time.c create mode 100644 lib_sh/time_sh2.c diff --git a/cpu/sh2/Makefile b/cpu/sh2/Makefile index 50f6720..e33ba0f 100644 --- a/cpu/sh2/Makefile +++ b/cpu/sh2/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -OBJS = cpu.o interrupts.o watchdog.o time.o # cache.o +OBJS = cpu.o interrupts.o watchdog.o all: .depend $(START) $(LIB) diff --git a/cpu/sh2/time.c b/cpu/sh2/time.c deleted file mode 100644 index fcbb921..0000000 --- a/cpu/sh2/time.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2007,2008 Nobobuhiro Iwamatsu - * Copyright (C) 2008 Renesas Solutions Corp. - * - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define CMT_CMCSR_INIT 0x0001 /* PCLK/32 */ -#define CMT_CMCSR_CALIB 0x0000 -#define CMT_MAX_COUNTER (0xFFFFFFFF) -#define CMT_TIMER_RESET (0xFFFF) - -static vu_long cmt0_timer; - -static void cmt_timer_start(unsigned int timer) -{ - writew(readw(CMSTR) | 0x01, CMSTR); -} - -static void cmt_timer_stop(unsigned int timer) -{ - writew(readw(CMSTR) & ~0x01, CMSTR); -} - -int timer_init(void) -{ - cmt0_timer = 0; - /* Divide clock by 32 */ - readw(CMCSR_0); - writew(CMT_CMCSR_INIT, CMCSR_0); - - /* User Device 0 only */ - cmt_timer_stop(0); - set_timer(CMT_TIMER_RESET); - cmt_timer_start(0); - - return 0; -} - -unsigned long long get_ticks(void) -{ - return cmt0_timer; -} - -static vu_long cmcnt; -ulong get_timer(ulong base) -{ - ulong data = readw(CMCNT_0); - - if (data >= cmcnt) - cmcnt = data - cmcnt; - else - cmcnt = (CMT_TIMER_RESET - cmcnt) + data; - - if ((cmt0_timer + cmcnt) > CMT_MAX_COUNTER) - cmt0_timer = ((cmt0_timer + cmcnt) - CMT_MAX_COUNTER); - else - cmt0_timer += cmcnt; - - cmcnt = data; - return cmt0_timer - base; -} - -void set_timer(ulong t) -{ - writew((u16) t, CMCOR_0); -} - -void reset_timer(void) -{ - cmt_timer_stop(0); - set_timer(CMT_TIMER_RESET); - cmt0_timer = 0; - cmt_timer_start(0); -} - -void udelay(unsigned long usec) -{ - unsigned int start = get_timer(0); - - while (get_timer((ulong) start) < (usec * (CONFIG_SYS_HZ / 1000000))) - continue; -} - -unsigned long get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/sh3/Makefile b/cpu/sh3/Makefile index 587413d..35e8f51 100644 --- a/cpu/sh3/Makefile +++ b/cpu/sh3/Makefile @@ -32,7 +32,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a SOBJS = start.o -COBJS = cpu.o interrupts.o watchdog.o time.o cache.o +COBJS = cpu.o interrupts.o watchdog.o cache.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/cpu/sh3/time.c b/cpu/sh3/time.c deleted file mode 100644 index aab3659..0000000 --- a/cpu/sh3/time.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * (C) Copyright 2007 - * Yoshihiro Shimoda - * - * (C) Copyright 2007 - * Nobobuhiro Iwamatsu - * - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define TMU_MAX_COUNTER (~0UL) - -static void tmu_timer_start(unsigned int timer) -{ - if (timer > 2) - return; - - outb(inb(TSTR) | (1 << timer), TSTR); -} - -static void tmu_timer_stop(unsigned int timer) -{ - u8 val = inb(TSTR); - - if (timer > 2) - return; - outb(val & ~(1 << timer), TSTR); -} - -int timer_init(void) -{ - /* Divide clock by 4 */ - outw(0, TCR0); - - tmu_timer_stop(0); - tmu_timer_start(0); - return 0; -} - -/* - In theory we should return a true 64bit value (ie something that doesn't - overflow). However, we don't. Therefore if TMU runs at fastest rate of - 6.75 MHz this value will wrap after u-boot has been running for approx - 10 minutes. -*/ -unsigned long long get_ticks(void) -{ - return (0 - inl(TCNT0)); -} - -unsigned long get_timer(unsigned long base) -{ - return ((0 - inl(TCNT0)) - base); -} - -void set_timer(unsigned long t) -{ - outl(0 - t, TCNT0); -} - -void reset_timer(void) -{ - tmu_timer_stop(0); - set_timer(0); - tmu_timer_start(0); -} - -void udelay(unsigned long usec) -{ - unsigned int start = get_timer(0); - unsigned int end = start + (usec * ((CONFIG_SYS_HZ + 500000) / 1000000)); - - while (get_timer(0) < end) - continue; -} - -unsigned long get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/sh4/Makefile b/cpu/sh4/Makefile index d3c5eef..3c96a49 100644 --- a/cpu/sh4/Makefile +++ b/cpu/sh4/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a SOBJS = start.o -COBJS = cpu.o interrupts.o watchdog.o time.o cache.o +COBJS = cpu.o interrupts.o watchdog.o cache.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/cpu/sh4/time.c b/cpu/sh4/time.c deleted file mode 100644 index 77e0ae2..0000000 --- a/cpu/sh4/time.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * (C) Copyright 2007 - * Nobobuhiro Iwamatsu - * - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#define TMU_MAX_COUNTER (~0UL) - -static void tmu_timer_start (unsigned int timer) -{ - if (timer > 2) - return; - - *((volatile unsigned char *) TSTR) |= (1 << timer); -} - -static void tmu_timer_stop (unsigned int timer) -{ - u8 val = *((volatile u8 *)TSTR); - if (timer > 2) - return; - *((volatile unsigned char *)TSTR) = val &~(1 << timer); -} - -int timer_init (void) -{ - /* Divide clock by 4 */ - *(volatile u16 *)TCR0 = 0; - - tmu_timer_stop(0); - tmu_timer_start(0); - return 0; -} - -/* - In theory we should return a true 64bit value (ie something that doesn't - overflow). However, we don't. Therefore if TMU runs at fastest rate of - 6.75 MHz this value will wrap after u-boot has been running for approx - 10 minutes. -*/ -unsigned long long get_ticks (void) -{ - return (0 - *((volatile u32 *) TCNT0)); -} - -unsigned long get_timer (unsigned long base) -{ - return ((0 - *((volatile u32 *) TCNT0)) - base); -} - -void set_timer (unsigned long t) -{ - *((volatile unsigned int *) TCNT0) = (0 - t); -} - -void reset_timer (void) -{ - tmu_timer_stop(0); - set_timer (0); - tmu_timer_start(0); -} - -void udelay (unsigned long usec) -{ - unsigned int start = get_timer (0); - unsigned int end = start + (usec * ((CONFIG_SYS_HZ + 500000) / 1000000)); - - while (get_timer (0) < end) - continue; -} - -unsigned long get_tbclk (void) -{ - return CONFIG_SYS_HZ; -} diff --git a/lib_sh/Makefile b/lib_sh/Makefile index 4034381..f7c6479 100644 --- a/lib_sh/Makefile +++ b/lib_sh/Makefile @@ -26,7 +26,11 @@ SOBJS-y += COBJS-y += board.o COBJS-y += bootm.o -# COBJS-y += time.o +ifeq ($(CONFIG_SH2),y) +COBJS-y += time_sh2.o +else +COBJS-y += time.o +endif SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/lib_sh/time.c b/lib_sh/time.c index e637e95..2bd7715 100644 --- a/lib_sh/time.c +++ b/lib_sh/time.c @@ -1,6 +1,9 @@ /* - * Copyright (c) 2007 - * Nobuhiro Iwamatsu + * (C) Copyright 2007-2008 + * Nobobuhiro Iwamatsu + * + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. @@ -23,50 +26,96 @@ #include #include +#include + +#define TMU_MAX_COUNTER (~0UL) +static int clk_adj = 1; static void tmu_timer_start (unsigned int timer) { if (timer > 2) return; + writeb(readb(TSTR) | (1 << timer), TSTR); +} - *((volatile unsigned char *) TSTR0) |= (1 << timer); +static void tmu_timer_stop (unsigned int timer) +{ + if (timer > 2) + return; + writeb(readb(TSTR) & ~(1 << timer), TSTR); } int timer_init (void) { - *(volatile u16 *)TCR0 = 0; + /* Divide clock by TMU_CLK_DIVIDER */ + u16 bit = 0; + switch( TMU_CLK_DIVIDER ){ + case 4: + bit = 0; + break; + case 16: + bit = 1; + break; + case 64: bit = 2; + break; + case 256: + bit = 3; + break; + case 1024: + bit = 4; + break; + default: + bit = 0; + break; + } + writew(readw(TCR0) | bit, TCR0); + + /* Clock adjustment calc */ + clk_adj = (int)(1.0/((1.0/CONFIG_SYS_HZ)*1000000)); + if (clk_adj < 1) + clk_adj = 1; + + tmu_timer_stop(0); + tmu_timer_start(0); - tmu_timer_start (0); return 0; } unsigned long long get_ticks (void) { - return (0 - *((volatile unsigned int *) TCNT0)); + return 0 - readl(TCNT0); } -unsigned long get_timer (unsigned long base) +static unsigned long get_usec (void) { - return ((0 - *((volatile unsigned int *) TCNT0)) - base); + return (0 - readl(TCNT0)); } -void set_timer (unsigned long t) +void udelay (unsigned long usec) { - *((volatile unsigned int *) TCNT0) = (0 - t); + unsigned int start = get_usec(); + unsigned int end = start + (usec * clk_adj); + + while (get_usec() < end) + continue; } -void reset_timer (void) +unsigned long get_timer (unsigned long base) { - set_timer (0); + /* return msec */ + return ((get_usec()/clk_adj)/1000) - base; } -void udelay (unsigned long usec) +void set_timer (unsigned long t) { - unsigned int start = get_timer (0); - unsigned int end = start + (usec * ((CONFIG_SYS_HZ + 500000) / 1000000)); + writel((0 - t), TCNT0); +} - while (get_timer (0) < end) - continue; +void reset_timer (void) +{ + tmu_timer_stop(0); + set_timer (0); + tmu_timer_start(0); } unsigned long get_tbclk (void) diff --git a/lib_sh/time_sh2.c b/lib_sh/time_sh2.c new file mode 100644 index 0000000..fcbb921 --- /dev/null +++ b/lib_sh/time_sh2.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2007,2008 Nobobuhiro Iwamatsu + * Copyright (C) 2008 Renesas Solutions Corp. + * + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define CMT_CMCSR_INIT 0x0001 /* PCLK/32 */ +#define CMT_CMCSR_CALIB 0x0000 +#define CMT_MAX_COUNTER (0xFFFFFFFF) +#define CMT_TIMER_RESET (0xFFFF) + +static vu_long cmt0_timer; + +static void cmt_timer_start(unsigned int timer) +{ + writew(readw(CMSTR) | 0x01, CMSTR); +} + +static void cmt_timer_stop(unsigned int timer) +{ + writew(readw(CMSTR) & ~0x01, CMSTR); +} + +int timer_init(void) +{ + cmt0_timer = 0; + /* Divide clock by 32 */ + readw(CMCSR_0); + writew(CMT_CMCSR_INIT, CMCSR_0); + + /* User Device 0 only */ + cmt_timer_stop(0); + set_timer(CMT_TIMER_RESET); + cmt_timer_start(0); + + return 0; +} + +unsigned long long get_ticks(void) +{ + return cmt0_timer; +} + +static vu_long cmcnt; +ulong get_timer(ulong base) +{ + ulong data = readw(CMCNT_0); + + if (data >= cmcnt) + cmcnt = data - cmcnt; + else + cmcnt = (CMT_TIMER_RESET - cmcnt) + data; + + if ((cmt0_timer + cmcnt) > CMT_MAX_COUNTER) + cmt0_timer = ((cmt0_timer + cmcnt) - CMT_MAX_COUNTER); + else + cmt0_timer += cmcnt; + + cmcnt = data; + return cmt0_timer - base; +} + +void set_timer(ulong t) +{ + writew((u16) t, CMCOR_0); +} + +void reset_timer(void) +{ + cmt_timer_stop(0); + set_timer(CMT_TIMER_RESET); + cmt0_timer = 0; + cmt_timer_start(0); +} + +void udelay(unsigned long usec) +{ + unsigned int start = get_timer(0); + + while (get_timer((ulong) start) < (usec * (CONFIG_SYS_HZ / 1000000))) + continue; +} + +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} -- cgit v1.1 From c54b9a42d8f5ab5b2a039b3a2e6fde8b427745e5 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 25 Nov 2008 11:05:19 +0900 Subject: sh: Changed value of CACHE_OC_NUM_ENTRIES and CACHE_OC_WAY_SHIFT SH4 is different a value of CACHE_OC_NUM_ENTRIES and CACHE_OC_WAY_SHIFT every CPU. This patch corrects these values. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- include/asm-sh/cpu_sh4.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/asm-sh/cpu_sh4.h b/include/asm-sh/cpu_sh4.h index b6cc6cf..d2dbfcd 100644 --- a/include/asm-sh/cpu_sh4.h +++ b/include/asm-sh/cpu_sh4.h @@ -26,8 +26,15 @@ #define CCR_CACHE_ICI 0x00000800 #define CACHE_OC_ADDRESS_ARRAY 0xf4000000 + +#if defined (CONFIG_CPU_SH7750) || \ + defined(CONFIG_CPU_SH7751) #define CACHE_OC_WAY_SHIFT 14 #define CACHE_OC_NUM_ENTRIES 512 +#else +#define CACHE_OC_WAY_SHIFT 13 +#define CACHE_OC_NUM_ENTRIES 256 +#endif #define CACHE_OC_ENTRY_SHIFT 5 #if defined (CONFIG_CPU_SH7750) || \ -- cgit v1.1 From 4d4a96055f6917335a89dbdf2e5556fa5ac329f6 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 2 Dec 2008 07:40:03 +0100 Subject: sh: r2dplus/lowlevel_init: coding style fix Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- board/renesas/r2dplus/lowlevel_init.S | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/board/renesas/r2dplus/lowlevel_init.S b/board/renesas/r2dplus/lowlevel_init.S index 5755de8..87e30c5 100644 --- a/board/renesas/r2dplus/lowlevel_init.S +++ b/board/renesas/r2dplus/lowlevel_init.S @@ -11,7 +11,7 @@ .global lowlevel_init .text - .align 2 + .align 2 lowlevel_init: @@ -118,34 +118,34 @@ CCR_D_E: .long 0x8000090B FRQCR_A: .long FRQCR /* FRQCR Address */ FRQCR_D: .long 0x00000e0a /* 03/07/15 modify */ -BCR1_A: .long BCR1 /* BCR1 Address */ -BCR1_D: .long 0x00180008 -BCR2_A: .long BCR2 /* BCR2 Address */ -BCR2_D: .long 0xabe8 -BCR3_A: .long BCR3 /* BCR3 Address */ -BCR3_D: .long 0x0000 -BCR4_A: .long BCR4 /* BCR4 Address */ -BCR4_D: .long 0x00000010 -WCR1_A: .long WCR1 /* WCR1 Address */ -WCR1_D: .long 0x33343333 -WCR2_A: .long WCR2 /* WCR2 Address */ -WCR2_D: .long 0xcff86fbf -WCR3_A: .long WCR3 /* WCR3 Address */ -WCR3_D: .long 0x07777707 +BCR1_A: .long BCR1 /* BCR1 Address */ +BCR1_D: .long 0x00180008 +BCR2_A: .long BCR2 /* BCR2 Address */ +BCR2_D: .long 0xabe8 +BCR3_A: .long BCR3 /* BCR3 Address */ +BCR3_D: .long 0x0000 +BCR4_A: .long BCR4 /* BCR4 Address */ +BCR4_D: .long 0x00000010 +WCR1_A: .long WCR1 /* WCR1 Address */ +WCR1_D: .long 0x33343333 +WCR2_A: .long WCR2 /* WCR2 Address */ +WCR2_D: .long 0xcff86fbf +WCR3_A: .long WCR3 /* WCR3 Address */ +WCR3_D: .long 0x07777707 LED_A: .long 0x04000036 /* LED Address */ RTCNT_A: .long RTCNT /* RTCNT Address */ RTCNT_D: .long 0xA500 /* RTCNT Write Code A5h Data 00h */ RTCOR_A: .long RTCOR /* RTCOR Address */ -RTCOR_D: .long 0xA534 /* RTCOR Write Code */ +RTCOR_D: .long 0xA534 /* RTCOR Write Code */ RTCSR_A: .long RTCSR /* RTCSR Address */ RTCSR_D: .long 0xA510 /* RTCSR Write Code */ -SDMR3_A: .long 0xFF9400CC /* SDMR3 Address */ +SDMR3_A: .long 0xFF9400CC /* SDMR3 Address */ SDMR3_D: .long 0x55 MCR_A: .long MCR /* MCR Address */ -MCR_D1: .long 0x081901F4 /* MRSET:'0' */ -MCR_D2: .long 0x481901F4 /* MRSET:'1' */ -RFCR_A: .long RFCR /* RFCR Address */ -RFCR_D: .long 0xA400 /* RFCR Write Code A4h Data 00h */ +MCR_D1: .long 0x081901F4 /* MRSET:'0' */ +MCR_D2: .long 0x481901F4 /* MRSET:'1' */ +RFCR_A: .long RFCR /* RFCR Address */ +RFCR_D: .long 0xA400 /* RFCR Write Code A4h Data 00h */ PCR_A: .long PCR /* PCR Address */ PCR_D: .long 0x0000 MMUCR_A: .long MMUCR /* MMUCCR Address */ -- cgit v1.1 From a319f1496210117b73198e3d889ffffaf6825d00 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 5 Dec 2008 07:27:37 +0100 Subject: sh: r2dplus fix register access Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- board/renesas/r2dplus/lowlevel_init.S | 2 +- drivers/pci/pci_sh7751.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/board/renesas/r2dplus/lowlevel_init.S b/board/renesas/r2dplus/lowlevel_init.S index 87e30c5..28d2b37 100644 --- a/board/renesas/r2dplus/lowlevel_init.S +++ b/board/renesas/r2dplus/lowlevel_init.S @@ -21,7 +21,7 @@ lowlevel_init: mov.l MMUCR_A,r1 mov.l MMUCR_D,r0 - mov.w r0,@r1 + mov.l r0,@r1 mov.l BCR1_A,r1 mov.l BCR1_D,r0 diff --git a/drivers/pci/pci_sh7751.c b/drivers/pci/pci_sh7751.c index e3a0ea0..df6d76f 100644 --- a/drivers/pci/pci_sh7751.c +++ b/drivers/pci/pci_sh7751.c @@ -187,8 +187,8 @@ int pci_sh7751_init(struct pci_controller *hose) /* Copy BSC registers into PCI BSC */ p4_out(inl(SH7751_BCR1), SH7751_PCIBCR1); - p4_out(inl(SH7751_BCR2), SH7751_PCIBCR2); - p4_out(inl(SH7751_BCR3), SH7751_PCIBCR3); + p4_out(inw(SH7751_BCR2), SH7751_PCIBCR2); + p4_out(inw(SH7751_BCR3), SH7751_PCIBCR3); p4_out(inl(SH7751_WCR1), SH7751_PCIWCR1); p4_out(inl(SH7751_WCR2), SH7751_PCIWCR2); p4_out(inl(SH7751_WCR3), SH7751_PCIWCR3); -- cgit v1.1 From d8bbc51c7ba9b737a20984333d19fe28a3526431 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 9 Dec 2008 11:32:46 +0900 Subject: sh: Update sh2/sh2a timer Renesas SH2/SH2A timer broken. This patch fix timer function. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- lib_sh/time_sh2.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib_sh/time_sh2.c b/lib_sh/time_sh2.c index fcbb921..4f893c8 100644 --- a/lib_sh/time_sh2.c +++ b/lib_sh/time_sh2.c @@ -65,8 +65,8 @@ unsigned long long get_ticks(void) return cmt0_timer; } -static vu_long cmcnt; -ulong get_timer(ulong base) +static vu_long cmcnt = 0; +static unsigned long get_usec (void) { ulong data = readw(CMCNT_0); @@ -81,7 +81,13 @@ ulong get_timer(ulong base) cmt0_timer += cmcnt; cmcnt = data; - return cmt0_timer - base; + return cmt0_timer; +} + +/* return msec */ +ulong get_timer(ulong base) +{ + return (get_usec()/1000) - base; } void set_timer(ulong t) @@ -99,9 +105,9 @@ void reset_timer(void) void udelay(unsigned long usec) { - unsigned int start = get_timer(0); + unsigned long end = get_usec() + usec; - while (get_timer((ulong) start) < (usec * (CONFIG_SYS_HZ / 1000000))) + while (get_usec() < end) continue; } -- cgit v1.1 From 9d23fc584c4b7b8bb9ecbee48920b1b04b08fa1b Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 12 Nov 2008 13:18:19 +0100 Subject: MIPS: Add onenand_init() to board.c and move nand_init() This patch adds a call to onenand_init() for OneNAND support and moves the nand_init() call to an earlier place, so that the environment can be used from NAND and OneNAND. Signed-off-by: Stefan Roese Signed-off-by: Shinya Kuribayashi --- lib_mips/board.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib_mips/board.c b/lib_mips/board.c index 9c997f1..5133b8a 100644 --- a/lib_mips/board.c +++ b/lib_mips/board.c @@ -30,6 +30,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -378,6 +379,15 @@ void board_init_r (gd_t *id, ulong dest_addr) mem_malloc_init(); malloc_bin_reloc(); +#ifdef CONFIG_CMD_NAND + puts ("NAND: "); + nand_init (); /* go init the NAND */ +#endif + +#if defined(CONFIG_CMD_ONENAND) + onenand_init(); +#endif + /* relocate environment function pointers etc. */ env_relocate(); @@ -419,11 +429,6 @@ void board_init_r (gd_t *id, ulong dest_addr) } #endif -#ifdef CONFIG_CMD_NAND - puts ("NAND: "); - nand_init (); /* go init the NAND */ -#endif - #ifdef CONFIG_CMD_SPI puts ("SPI: "); spi_init (); /* go init the SPI */ -- cgit v1.1 From db08ecaa6eb8176904b3bae103a85ee8f735dc40 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Wed, 12 Nov 2008 13:18:02 +0100 Subject: MIPS: Add board_early_init_f() to init_sequence This patch adds the board_early_init_f() call to the MIPS init sequence. A weak dummy implementation is also added which can be overridden by a board specific version. This will be used by the upcoming VCTH board support. Signed-off-by: Stefan Roese Signed-off-by: Shinya Kuribayashi --- lib_mips/board.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib_mips/board.c b/lib_mips/board.c index 5133b8a..dfe6831 100644 --- a/lib_mips/board.c +++ b/lib_mips/board.c @@ -72,6 +72,15 @@ static ulong mem_malloc_brk; */ unsigned long mips_io_port_base = -1; +int __board_early_init_f(void) +{ + /* + * Nothing to do in this dummy implementation + */ + return 0; +} +int board_early_init_f(void) __attribute__((weak, alias("__board_early_init_f"))); + /* * The Malloc area is immediately below the monitor copy in DRAM */ @@ -169,6 +178,7 @@ static int init_baudrate (void) typedef int (init_fnc_t) (void); init_fnc_t *init_sequence[] = { + board_early_init_f, timer_init, env_init, /* initialize environment */ #ifdef CONFIG_INCA_IP -- cgit v1.1 From 44174343688dba32571a34550dba08971c65fef1 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 18 Nov 2008 16:36:22 +0100 Subject: MIPS: Add CONFIG_SKIP_LOWLEVEL_INIT This patch adds the CONFIG_SKIP_LOWLEVEL_INIT option to start.S. This enables support for boards where the lowlevel initialization is already done when U-Boot runs (e.g. via OnChip ROM). This will be used in the upcoming VCTH board support. Signed-off-by: Stefan Roese Signed-off-by: Shinya Kuribayashi --- cpu/mips/start.S | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpu/mips/start.S b/cpu/mips/start.S index 6a22302..f6069b3 100644 --- a/cpu/mips/start.S +++ b/cpu/mips/start.S @@ -243,9 +243,11 @@ reset: mtc0 zero, CP0_COUNT mtc0 zero, CP0_COMPARE +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) /* CONFIG0 register */ li t0, CONF_CM_UNCACHED mtc0 t0, CP0_CONFIG +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ /* Initialize $gp. */ @@ -255,6 +257,7 @@ reset: 1: lw gp, 0(ra) +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) /* Initialize any external memory. */ la t9, lowlevel_init @@ -271,6 +274,7 @@ reset: */ li t0, CONF_CM_CACHABLE_NONCOHERENT mtc0 t0, CP0_CONFIG +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ /* Set up temporary stack. */ -- cgit v1.1 From 71fa0714fe5134bc8718c38d5261d267e88582ba Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 18 Nov 2008 16:36:12 +0100 Subject: MIPS: Flush data cache upon relocation This patch now adds a flush to the data cache upon relocation. The current implementation is missing this. Only a comment states that it should be done. So let's really do it now. Signed-off-by: Stefan Roese Signed-off-by: Shinya Kuribayashi --- cpu/mips/start.S | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/cpu/mips/start.S b/cpu/mips/start.S index f6069b3..57db589 100644 --- a/cpu/mips/start.S +++ b/cpu/mips/start.S @@ -311,6 +311,7 @@ relocate_code: la t3, in_ram lw t2, -12(t3) /* t2 <-- uboot_end_data */ move t1, a2 + move s2, a2 /* s2 <-- destination address */ /* * Fix $gp: @@ -320,13 +321,21 @@ relocate_code: move t6, gp sub gp, CONFIG_SYS_MONITOR_BASE add gp, a2 /* gp now adjusted */ - sub t6, gp, t6 /* t6 <-- relocation offset */ + sub s1, gp, t6 /* s1 <-- relocation offset */ /* * t0 = source address * t1 = target address * t2 = source end address */ + + /* + * Save destination address and size for later usage in flush_cache() + */ + move s0, a1 /* save gd in s0 */ + move a0, t1 /* a0 <-- destination addr */ + sub a1, t2, t0 /* a1 <-- size */ + /* On the purple board we copy the code earlier in a special way * in order to solve flash problems */ @@ -342,9 +351,14 @@ relocate_code: /* If caches were enabled, we would have to flush them here. */ + /* a0 & a1 are already set up for flush_cache(start, size) */ + la t9, flush_cache + jalr t9 + nop + /* Jump to where we've relocated ourselves. */ - addi t0, a2, in_ram - _start + addi t0, s2, in_ram - _start jr t0 nop @@ -371,7 +385,7 @@ in_ram: 1: lw t1, 0(t4) beqz t1, 2f - add t1, t6 + add t1, s1 sw t1, 0(t4) 2: addi t2, 1 @@ -382,8 +396,8 @@ in_ram: */ lw t1, -12(t0) /* t1 <-- uboot_end_data */ lw t2, -8(t0) /* t2 <-- uboot_end */ - add t1, t6 /* adjust pointers */ - add t2, t6 + add t1, s1 /* adjust pointers */ + add t2, s1 sub t1, 4 1: @@ -391,10 +405,10 @@ in_ram: bltl t1, t2, 1b sw zero, 0(t1) /* delay slot */ - move a0, a1 + move a0, s0 /* a0 <-- gd */ la t9, board_init_r jr t9 - move a1, a2 /* delay slot */ + move a1, s2 /* delay slot */ .end relocate_code -- cgit v1.1 From 5b67a1439a73ba6c34007d9ff60a2c6aa90265df Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Wed, 10 Dec 2008 15:12:56 +0100 Subject: ppc4xx: Fix Ethernet PHY LED configuration on PMC440 boards Signed-off-by: Matthias Fuchs --- board/esd/pmc440/pmc440.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/board/esd/pmc440/pmc440.c b/board/esd/pmc440/pmc440.c index 8563d7d..4d81c33 100644 --- a/board/esd/pmc440/pmc440.c +++ b/board/esd/pmc440/pmc440.c @@ -755,17 +755,31 @@ int post_hotkeys_pressed(void) #ifdef CONFIG_RESET_PHY_R void reset_phy(void) { + char *s; + unsigned short val_method, val_behavior; + + /* special LED setup for NGCC/CANDES */ + if ((s = getenv("bd_type")) && + ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) { + val_method = 0x0e0a; + val_behavior = 0x0cf2; + } else { + /* PMC440 standard type */ + val_method = 0x0e10; + val_behavior = 0x0cf0; + } + if (miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0001) == 0) { miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0010); - miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0df0); - miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, 0x0e10); + miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, val_behavior); + miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, val_method); miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0000); } if (miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) { miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0010); - miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0df0); - miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, 0x0e10); + miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, val_behavior); + miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, val_method); miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0000); } } -- cgit v1.1 From 19ef4f7a6ef3b725aa9fe4b4f5fb676a84160172 Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Wed, 10 Dec 2008 15:13:32 +0100 Subject: ppc4xx: Disable EEPROM write access on PMC440 boards This patch disables EEPROM wrtie access by default on PMC440 board. Signed-off-by: Matthias Fuchs --- board/esd/pmc440/pmc440.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/esd/pmc440/pmc440.c b/board/esd/pmc440/pmc440.c index 4d81c33..3824105 100644 --- a/board/esd/pmc440/pmc440.c +++ b/board/esd/pmc440/pmc440.c @@ -107,7 +107,7 @@ int board_early_init_f(void) * Setup the GPIO pins * TODO: setup GPIOs via CONFIG_SYS_4xx_GPIO_TABLE in board's config file */ - out32(GPIO0_OR, 0x40000002); + out32(GPIO0_OR, 0x40000102); out32(GPIO0_TCR, 0x4c90011f); out32(GPIO0_OSRL, 0x28051400); out32(GPIO0_OSRH, 0x55005000); -- cgit v1.1 From cd6734510a9ff0f41c4a73567d4080ea0033d2c1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 24 Nov 2008 13:33:51 +0100 Subject: Fix FIT and FDT support to have CONFIG_OF_LIBFDT and CONFIG_FIT independent FDT support is used for both FIT style images and for architectures that can pass a fdt blob to an OS (ppc, m68k, sparc). For other architectures and boards which do not pass a fdt blob to an OS but want to use the new uImage format, we just need FIT support. Now we can have the 4 following configurations : 1) FIT only CONFIG_FIT 2) fdt blob only CONFIG_OF_LIBFDT 3) both CONFIG_OF_LIBFDT & CONFIG_FIT 4) none none Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- common/image.c | 2 ++ include/image.h | 4 ---- libfdt/Makefile | 8 ++++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/common/image.c b/common/image.c index 866edf6..daa68bc 100644 --- a/common/image.c +++ b/common/image.c @@ -1071,6 +1071,7 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } +#endif /* defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) */ #ifdef CONFIG_OF_LIBFDT static void fdt_error (const char *msg) @@ -1575,6 +1576,7 @@ error: } #endif /* CONFIG_OF_LIBFDT */ +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt diff --git a/include/image.h b/include/image.h index 5433555..4609200 100644 --- a/include/image.h +++ b/include/image.h @@ -50,10 +50,6 @@ #endif /* USE_HOSTCC */ -#if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) -#error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" -#endif - #include #if defined(CONFIG_FIT) diff --git a/libfdt/Makefile b/libfdt/Makefile index ca2ad76..d6e2830 100644 --- a/libfdt/Makefile +++ b/libfdt/Makefile @@ -27,9 +27,13 @@ LIB = $(obj)libfdt.a SOBJS = -COBJS-$(CONFIG_OF_LIBFDT) += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o +COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o -COBJS := $(COBJS-y) +COBJS-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt) +COBJS-$(CONFIG_FIT) += $(COBJS-libfdt) + + +COBJS := $(sort $(COBJS-y)) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -- cgit v1.1 From 0e0c862efe7279e9609db74d758cd1b84c6c7209 Mon Sep 17 00:00:00 2001 From: Sergei Poselenov Date: Fri, 19 Sep 2008 12:07:34 +0200 Subject: Remove compiler warning: target CPU does not support interworking This warning is issued by modern ARM-EABI GCC on non-thumb targets. Signed-off-by: Vladimir Panfilov Signed-off-by: Sergei Poselenov --- cpu/arm720t/config.mk | 1 + cpu/arm920t/config.mk | 1 + cpu/arm925t/config.mk | 1 + cpu/arm926ejs/config.mk | 1 + cpu/arm946es/config.mk | 1 + cpu/arm_intcm/config.mk | 1 + cpu/lh7a40x/config.mk | 1 + cpu/pxa/config.mk | 1 + cpu/s3c44b0/config.mk | 1 + cpu/sa1100/config.mk | 1 + 10 files changed, 10 insertions(+) diff --git a/cpu/arm720t/config.mk b/cpu/arm720t/config.mk index 641b91c..3cae1dc 100644 --- a/cpu/arm720t/config.mk +++ b/cpu/arm720t/config.mk @@ -32,4 +32,5 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi # # ========================================================================= PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm920t/config.mk b/cpu/arm920t/config.mk index 8db4adb..38718a3 100644 --- a/cpu/arm920t/config.mk +++ b/cpu/arm920t/config.mk @@ -31,4 +31,5 @@ PLATFORM_CPPFLAGS += -march=armv4 # # ========================================================================= PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm925t/config.mk b/cpu/arm925t/config.mk index 8db4adb..38718a3 100644 --- a/cpu/arm925t/config.mk +++ b/cpu/arm925t/config.mk @@ -31,4 +31,5 @@ PLATFORM_CPPFLAGS += -march=armv4 # # ========================================================================= PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm926ejs/config.mk b/cpu/arm926ejs/config.mk index 84b68ae..a57d03a 100644 --- a/cpu/arm926ejs/config.mk +++ b/cpu/arm926ejs/config.mk @@ -31,4 +31,5 @@ PLATFORM_CPPFLAGS += -march=armv5te # # ========================================================================= PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm946es/config.mk b/cpu/arm946es/config.mk index f774c7e..6190e16 100644 --- a/cpu/arm946es/config.mk +++ b/cpu/arm946es/config.mk @@ -31,4 +31,5 @@ PLATFORM_CPPFLAGS += -march=armv4 # # ========================================================================= PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm_intcm/config.mk b/cpu/arm_intcm/config.mk index f774c7e..6190e16 100644 --- a/cpu/arm_intcm/config.mk +++ b/cpu/arm_intcm/config.mk @@ -31,4 +31,5 @@ PLATFORM_CPPFLAGS += -march=armv4 # # ========================================================================= PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/lh7a40x/config.mk b/cpu/lh7a40x/config.mk index 10e755b..32fd1d1 100644 --- a/cpu/lh7a40x/config.mk +++ b/cpu/lh7a40x/config.mk @@ -31,4 +31,5 @@ PLATFORM_CPPFLAGS += -march=armv4 # # ======================================================================== PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/pxa/config.mk b/cpu/pxa/config.mk index f0b86b7..af910e2 100644 --- a/cpu/pxa/config.mk +++ b/cpu/pxa/config.mk @@ -32,4 +32,5 @@ PLATFORM_CPPFLAGS += -march=armv5te -mtune=xscale # # ======================================================================== PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/s3c44b0/config.mk b/cpu/s3c44b0/config.mk index 6dc9c46..01e7040 100644 --- a/cpu/s3c44b0/config.mk +++ b/cpu/s3c44b0/config.mk @@ -32,4 +32,5 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi -msoft-float # # ======================================================================== PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/sa1100/config.mk b/cpu/sa1100/config.mk index 5be7dfb..9ef4a19 100644 --- a/cpu/sa1100/config.mk +++ b/cpu/sa1100/config.mk @@ -32,4 +32,5 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=strongarm1100 # # ======================================================================== PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -- cgit v1.1 From 3aed3aa2c128ce9fb39ca3f4e9385a7499e93dbf Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 14 Dec 2008 10:29:39 +0100 Subject: Fix new found CFG_ Also fix some minor typos. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Wolfgang Denk --- board/esd/pmc440/cmd_pmc440.c | 2 +- board/xilinx/ppc405-generic/u-boot-ram.lds | 2 +- board/xilinx/ppc405-generic/u-boot-rom.lds | 2 +- cpu/arm926ejs/at91/usb.c | 2 +- cpu/mpc86xx/release.S | 2 +- include/configs/PMC440.h | 8 ++++---- include/configs/afeb9260.h | 4 ++-- include/configs/at91cap9adk.h | 2 +- include/configs/at91sam9260ek.h | 2 +- include/configs/at91sam9263ek.h | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/board/esd/pmc440/cmd_pmc440.c b/board/esd/pmc440/cmd_pmc440.c index 3f0dca0..16c9c7e 100644 --- a/board/esd/pmc440/cmd_pmc440.c +++ b/board/esd/pmc440/cmd_pmc440.c @@ -364,7 +364,7 @@ int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) base -= LOGBUFF_LEN + LOGBUFF_OVERHEAD; #endif /* - * gd->bd->bi_memsize == physical ram size - CFG_MEM_TOP_HIDE + * gd->bd->bi_memsize == physical ram size - CONFIG_SYS_MEM_TOP_HIDE */ param = base - (pram << 10); printf("PARAM: @%08x\n", param); diff --git a/board/xilinx/ppc405-generic/u-boot-ram.lds b/board/xilinx/ppc405-generic/u-boot-ram.lds index 0004d61..6bbd3bd 100644 --- a/board/xilinx/ppc405-generic/u-boot-ram.lds +++ b/board/xilinx/ppc405-generic/u-boot-ram.lds @@ -127,7 +127,7 @@ SECTIONS *(COMMON) } - ppcenv_assert = ASSERT(. < 0xFFFFB000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CFG_MONITOR_BASE, CFG_MONITOR_LEN and TEXT_BASE may need to be modified."); + ppcenv_assert = ASSERT(. < 0xFFFFB000, ".bss section too big, overlaps .ppcenv section. Please update your configuration: CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN and TEXT_BASE may need to be modified."); _end = . ; PROVIDE (end = .); diff --git a/board/xilinx/ppc405-generic/u-boot-rom.lds b/board/xilinx/ppc405-generic/u-boot-rom.lds index d2bac9f..d094006 100644 --- a/board/xilinx/ppc405-generic/u-boot-rom.lds +++ b/board/xilinx/ppc405-generic/u-boot-rom.lds @@ -137,7 +137,7 @@ SECTIONS *(COMMON) } - ppcenv_assert = ASSERT(. < 0xFFFFB000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CFG_MONITOR_BASE, CFG_MONITOR_LEN and TEXT_BASE may need to be modified."); + ppcenv_assert = ASSERT(. < 0xFFFFB000, ".bss section too big, overlaps .ppcenv section. Please update your configuration: CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN and TEXT_BASE may need to be modified."); _end = . ; PROVIDE (end = .); diff --git a/cpu/arm926ejs/at91/usb.c b/cpu/arm926ejs/at91/usb.c index 2f5c337..a15ab16 100644 --- a/cpu/arm926ejs/at91/usb.c +++ b/cpu/arm926ejs/at91/usb.c @@ -35,7 +35,7 @@ int usb_cpu_init(void) #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ defined(CONFIG_AT91SAM9263) /* Enable PLLB */ - at91_sys_write(AT91_CKGR_PLLBR, CFG_AT91_PLLB); + at91_sys_write(AT91_CKGR_PLLBR, CONFIG_SYS_AT91_PLLB); while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB) ; #endif diff --git a/cpu/mpc86xx/release.S b/cpu/mpc86xx/release.S index b524e50..95efbb4 100644 --- a/cpu/mpc86xx/release.S +++ b/cpu/mpc86xx/release.S @@ -125,7 +125,7 @@ invl2: mtspr HID0, r5 /* enable + invalidate */ mtspr HID0, r3 /* enable */ sync -#ifdef CFG_L2 +#ifdef CONFIG_SYS_L2 sync lis r3, L2_ENABLE@h ori r3, r3, L2_ENABLE@l diff --git a/include/configs/PMC440.h b/include/configs/PMC440.h index 7219bb8..d0e3cda 100644 --- a/include/configs/PMC440.h +++ b/include/configs/PMC440.h @@ -219,8 +219,8 @@ #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) #define CONFIG_DDR_DATA_EYE /* use DDR2 optimization */ #endif -#define CFG_MEM_TOP_HIDE (4 << 10) /* don't use last 4kbytes */ - /* 440EPx errata CHIP 11 */ +#define CONFIG_SYS_MEM_TOP_HIDE (4 << 10) /* don't use last 4kbytes */ + /* 440EPx errata CHIP 11 */ /*----------------------------------------------------------------------- * I2C @@ -490,8 +490,8 @@ #endif /* Memory Bank 1 (RESET) initialization */ -#define CFG_EBC_PB1AP 0x7f817200 //0x03017200 -#define CFG_EBC_PB1CR (CFG_RESET_BASE | 0x1c000) +#define CONFIG_SYS_EBC_PB1AP 0x7f817200 //0x03017200 +#define CONFIG_SYS_EBC_PB1CR (CONFIG_SYS_RESET_BASE | 0x1c000) /* Memory Bank 4 (FPGA / 32Bit) initialization */ #define CONFIG_SYS_EBC_PB4AP 0x03840f40 /* BME=0,TWT=7,CSN=1,TH=7,RE=1,SOR=0,BEM=1 */ diff --git a/include/configs/afeb9260.h b/include/configs/afeb9260.h index f077ad9..90e553d 100644 --- a/include/configs/afeb9260.h +++ b/include/configs/afeb9260.h @@ -29,7 +29,7 @@ /* ARM asynchronous clock */ #define AT91_MAIN_CLOCK 18429952 /* from 18.432 MHz crystal */ #define AT91_MASTER_CLOCK 89999598 /* peripheral = main / 2 */ -#define CFG_AT91_PLLB 0x107c3e18 /* PLLB settings for USB */ +#define CONFIG_SYS_AT91_PLLB 0x107c3e18 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ @@ -150,7 +150,7 @@ #define CONFIG_SYS_CBSIZE 256 #define CONFIG_SYS_MAXARGS 16 #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) -#define CFG_LONGHELP 1 +#define CONFIG_SYS_LONGHELP 1 #define CONFIG_CMDLINE_EDITING 1 #define ROUND(A, B) (((A) + (B)) & ~((B) - 1)) diff --git a/include/configs/at91cap9adk.h b/include/configs/at91cap9adk.h index aeb06ac..363df67 100644 --- a/include/configs/at91cap9adk.h +++ b/include/configs/at91cap9adk.h @@ -32,7 +32,7 @@ #define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ -#define CFG_AT91_PLLB 0x10073e01 /* PLLB settings for USB */ +#define CONFUG_SYS_AT91_PLLB 0x10073e01 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91sam9260ek.h b/include/configs/at91sam9260ek.h index 2df8d54..1538929 100644 --- a/include/configs/at91sam9260ek.h +++ b/include/configs/at91sam9260ek.h @@ -32,7 +32,7 @@ #define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ -#define CFG_AT91_PLLB 0x107c3e18 /* PLLB settings for USB */ +#define CONFIG_SYS_AT91_PLLB 0x107c3e18 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index fc7c941..d9ebc87 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -32,7 +32,7 @@ #define AT91_MAIN_CLOCK 16367660 /* 16.367 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ -#define CFG_AT91_PLLB 0x133a3e8d /* PLLB settings for USB */ +#define CONFIG_SYS_AT91_PLLB 0x133a3e8d /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ -- cgit v1.1 From d16da93430520d3e46c1ab52eedacf36ab7a2311 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 24 Nov 2008 11:54:47 -0600 Subject: cmd_mem: Remove unused variable Signed-off-by: Peter Tyser --- common/cmd_mem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/common/cmd_mem.c b/common/cmd_mem.c index d7666c2..400cfd7 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -1175,7 +1175,6 @@ int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { unsigned long src, dst; unsigned long src_len = ~0UL, dst_len = ~0UL; - int err; switch (argc) { case 4: -- cgit v1.1 From ba490b7761c62b549c222a9723e532dc801a3899 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 1 Dec 2008 16:22:45 -0600 Subject: Remove unused CONFIG_ADDR_STREAMING defines Signed-off-by: Peter Tyser --- include/configs/ATUM8548.h | 1 - include/configs/MPC8536DS.h | 1 - include/configs/MPC8540ADS.h | 1 - include/configs/MPC8540EVAL.h | 1 - include/configs/MPC8541CDS.h | 1 - include/configs/MPC8544DS.h | 1 - include/configs/MPC8548CDS.h | 1 - include/configs/MPC8555CDS.h | 1 - include/configs/MPC8560ADS.h | 1 - include/configs/MPC8568MDS.h | 1 - include/configs/MPC8572DS.h | 1 - include/configs/PM854.h | 1 - include/configs/PM856.h | 1 - include/configs/SBC8540.h | 1 - include/configs/TQM85xx.h | 1 - include/configs/sbc8548.h | 1 - include/configs/sbc8560.h | 1 - include/configs/socrates.h | 1 - include/configs/stxgp3.h | 1 - include/configs/stxssa.h | 1 - 20 files changed, 20 deletions(-) diff --git a/include/configs/ATUM8548.h b/include/configs/ATUM8548.h index 1b74526..7ee05e5 100644 --- a/include/configs/ATUM8548.h +++ b/include/configs/ATUM8548.h @@ -67,7 +67,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_CLEAR_LAW0 /* Clear LAW0 in cpu_init_r */ /* diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index 5a99d5f..532c3df 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -70,7 +70,6 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_ENABLE_36BIT_PHYS 1 diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index 0b8fe6a..f22b752 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -79,7 +79,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_SYS_MEMTEST_START 0x00200000 /* memtest region */ #define CONFIG_SYS_MEMTEST_END 0x00400000 diff --git a/include/configs/MPC8540EVAL.h b/include/configs/MPC8540EVAL.h index 21cf965..5ac1916 100644 --- a/include/configs/MPC8540EVAL.h +++ b/include/configs/MPC8540EVAL.h @@ -62,7 +62,6 @@ /* below can be toggled for performance analysis. otherwise use default */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #undef CONFIG_BTB /* toggle branch predition */ -#undef CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_PRE_INIT 1 /* Call board_pre_init */ diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index eaa737b..399189c 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -63,7 +63,6 @@ extern unsigned long get_clock_freq(void); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_SYS_MEMTEST_START 0x00200000 /* memtest works on */ #define CONFIG_SYS_MEMTEST_END 0x00400000 diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index b31c2bb..9b1b34c 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -66,7 +66,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ /* * Only possible on E500 Version 2 or newer cores. diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 7a7e5a1..e1bd45e 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -69,7 +69,6 @@ extern unsigned long get_clock_freq(void); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_CLEAR_LAW0 /* Clear LAW0 in cpu_init_r */ /* diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index 40b40ed..c92f82d 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -63,7 +63,6 @@ extern unsigned long get_clock_freq(void); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_SYS_MEMTEST_START 0x00200000 /* memtest works on */ #define CONFIG_SYS_MEMTEST_END 0x00400000 diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index 2b5b2c1..bf4bd2c 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -73,7 +73,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_SYS_INIT_DBCR DBCR_IDM /* Enable Debug Exceptions */ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index 8bdec65..da1f454 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -61,7 +61,6 @@ extern unsigned long get_clock_freq(void); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ /* * Only possible on E500 Version 2 or newer cores. diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 9a66ca8..37c3f42 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -71,7 +71,6 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_ENABLE_36BIT_PHYS 1 diff --git a/include/configs/PM854.h b/include/configs/PM854.h index 1cc80ad..41e290d 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -71,7 +71,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ diff --git a/include/configs/PM856.h b/include/configs/PM856.h index 698ad2d..6b4e2dd 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -72,7 +72,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ diff --git a/include/configs/SBC8540.h b/include/configs/SBC8540.h index 2853fba..3419631 100644 --- a/include/configs/SBC8540.h +++ b/include/configs/SBC8540.h @@ -75,7 +75,6 @@ /* below can be toggled for performance analysis. otherwise use default */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #undef CONFIG_BTB /* toggle branch predition */ -#undef CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */ diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h index 300f490..6d205a7 100644 --- a/include/configs/TQM85xx.h +++ b/include/configs/TQM85xx.h @@ -106,7 +106,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_SYS_INIT_DBCR DBCR_IDM /* Enable Debug Exceptions */ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 5ce4dac..528c810 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -59,7 +59,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_CLEAR_LAW0 /* Clear LAW0 in cpu_init_r */ /* diff --git a/include/configs/sbc8560.h b/include/configs/sbc8560.h index e1d3a52..d4e9d74 100644 --- a/include/configs/sbc8560.h +++ b/include/configs/sbc8560.h @@ -69,7 +69,6 @@ /* below can be toggled for performance analysis. otherwise use default */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #undef CONFIG_BTB /* toggle branch predition */ -#undef CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */ diff --git a/include/configs/socrates.h b/include/configs/socrates.h index e89b5a3..cbf04e3 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -82,7 +82,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_SYS_INIT_DBCR DBCR_IDM /* Enable Debug Exceptions */ diff --git a/include/configs/stxgp3.h b/include/configs/stxgp3.h index a0f2ed0..ae6f45a 100644 --- a/include/configs/stxgp3.h +++ b/include/configs/stxgp3.h @@ -64,7 +64,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ diff --git a/include/configs/stxssa.h b/include/configs/stxssa.h index f0990c6..c312f1a 100644 --- a/include/configs/stxssa.h +++ b/include/configs/stxssa.h @@ -64,7 +64,6 @@ */ #define CONFIG_L2_CACHE /* toggle L2 cache */ #define CONFIG_BTB /* toggle branch predition */ -#define CONFIG_ADDR_STREAMING /* toggle addr streaming */ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */ -- cgit v1.1 From 22525779cb51f1bbe4e96fea7b778de1935a5a69 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Wed, 6 Aug 2008 14:44:05 +0300 Subject: Fix a typo in fw_env.config Reported-by: Martin Michlmayr Signed-off-by: Wolfgang Denk --- tools/env/fw_env.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config index 0fe37c9..c8f12cf 100644 --- a/tools/env/fw_env.config +++ b/tools/env/fw_env.config @@ -1,5 +1,5 @@ # Configuration file for fw_(printenv/saveenv) utility. -# Up to two entries are valid, in this case the redundand +# Up to two entries are valid, in this case the redundant # environment sector is assumed present. # Notice, that the "Number of sectors" is ignored on NOR. -- cgit v1.1 From 45845301af3de8675c1f7bbc815c6de35452605a Mon Sep 17 00:00:00 2001 From: Yuri Tikhonov Date: Sun, 7 Dec 2008 22:12:50 +0100 Subject: POST Make: fix the sub-dir dependencies missing. Signed-off-by: Yuri Tikhonov --- post/Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/post/Makefile b/post/Makefile index a402e6a..666a896 100644 --- a/post/Makefile +++ b/post/Makefile @@ -45,7 +45,12 @@ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) LIB := $(obj)$(LIB) -all: $(LIB) +all: postdeps $(LIB) + +postdeps: + @for lib in $(SPLIB-y) ; do \ + $(MAKE) -C `dirname $$lib` all ; \ + done # generic POST library $(GPLIB): $(obj).depend $(OBJS) -- cgit v1.1 From 65e43a10631537dcb92c302d36301a12308216c3 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Sat, 13 Dec 2008 17:20:27 -0600 Subject: Introduce virt_to_phys() virt_to_phys() returns the physical address given a virtual. In most cases this will be just the input value as the vast majority of systems run in a 1:1 mode. However in systems that are not running this way it should report the physical address or ~0 if no mapping exists for the given virtual address. Signed-off-by: Kumar Gala --- include/asm-arm/io.h | 5 +++++ include/asm-avr32/io.h | 5 +++++ include/asm-blackfin/io.h | 5 +++++ include/asm-i386/io.h | 5 +++++ include/asm-m68k/io.h | 5 +++++ include/asm-microblaze/io.h | 5 +++++ include/asm-mips/io.h | 2 +- include/asm-nios/io.h | 5 +++++ include/asm-nios2/io.h | 5 +++++ include/asm-ppc/io.h | 5 +++++ include/asm-sh/io.h | 5 +++++ include/asm-sparc/io.h | 5 +++++ 12 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index f4ae307..fec3a7e 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -57,6 +57,11 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + /* * Generic virtual read/write. Note that we don't support half-word * read/writes. We define __arch_*[bl] here, and leave __arch_*w diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h index 06e52b1..d22cd35 100644 --- a/include/asm-avr32/io.h +++ b/include/asm-avr32/io.h @@ -125,4 +125,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long len) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif /* __ASM_AVR32_IO_H */ diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h index da58914..6806494 100644 --- a/include/asm-blackfin/io.h +++ b/include/asm-blackfin/io.h @@ -64,6 +64,11 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + /* * These are for ISA/PCI shared memory _only_ and should never be used * on any other type of memory, including Zorro memory. They are meant to diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index 2c57140..9b757d4 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -229,4 +229,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h index 1fccc12..50ea087 100644 --- a/include/asm-m68k/io.h +++ b/include/asm-m68k/io.h @@ -251,4 +251,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif /* __ASM_M68K_IO_H__ */ diff --git a/include/asm-microblaze/io.h b/include/asm-microblaze/io.h index 8804724..7e190d1 100644 --- a/include/asm-microblaze/io.h +++ b/include/asm-microblaze/io.h @@ -155,4 +155,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif /* __MICROBLAZE_IO_H__ */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 3a0f33f..031186d 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -118,7 +118,7 @@ static inline void set_io_port_base(unsigned long base) * Change virtual addresses to physical addresses and vv. * These are trivial on the 1:1 Linux/MIPS mapping */ -extern inline unsigned long virt_to_phys(volatile void * address) +extern inline phys_addr_t virt_to_phys(void * address) { return CPHYSADDR(address); } diff --git a/include/asm-nios/io.h b/include/asm-nios/io.h index 8b78806..899682c 100644 --- a/include/asm-nios/io.h +++ b/include/asm-nios/io.h @@ -133,4 +133,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif /* __ASM_NIOS_IO_H_ */ diff --git a/include/asm-nios2/io.h b/include/asm-nios2/io.h index 2f1ec26..01d11ef 100644 --- a/include/asm-nios2/io.h +++ b/include/asm-nios2/io.h @@ -53,6 +53,11 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + extern unsigned char inb (unsigned char *port); extern unsigned short inw (unsigned short *port); extern unsigned inl (unsigned port); diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index c349681..c00de45 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -298,4 +298,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h index adc3f81..ca598a6 100644 --- a/include/asm-sh/io.h +++ b/include/asm-sh/io.h @@ -261,5 +261,10 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif /* __KERNEL__ */ #endif /* __ASM_SH_IO_H */ diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h index 5f8d05c..0c5d86c 100644 --- a/include/asm-sparc/io.h +++ b/include/asm-sparc/io.h @@ -90,4 +90,9 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) } +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + #endif -- cgit v1.1 From 63240ba88cd6a220057a0f28e5bf97f5b17ac84b Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Sat, 13 Dec 2008 17:20:28 -0600 Subject: Introduce addr_map library Add a library that helps in translating between virtual and physical addresses. This library can be useful as a simple means to implement map_physmem() and virt_to_phys() for platforms that need functionality beyond the simple 1:1 mapping. Signed-off-by: Kumar Gala --- include/addr_map.h | 29 ++++++++++++++++++ lib_generic/Makefile | 1 + lib_generic/addr_map.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 include/addr_map.h create mode 100644 lib_generic/addr_map.c diff --git a/include/addr_map.h b/include/addr_map.h new file mode 100644 index 0000000..d55f5f6 --- /dev/null +++ b/include/addr_map.h @@ -0,0 +1,29 @@ +#ifndef __ADDR_MAP_H +#define __ADDR_MAP_H + +/* + * Copyright 2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +extern phys_addr_t addrmap_virt_to_phys(void *vaddr); +extern unsigned long addrmap_phys_to_virt(phys_addr_t paddr); +extern void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, + phys_size_t size, int idx); + +#endif diff --git a/lib_generic/Makefile b/lib_generic/Makefile index d62c39b..3f04022 100644 --- a/lib_generic/Makefile +++ b/lib_generic/Makefile @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libgeneric.a +COBJS-$(CONFIG_ADDR_MAP) += addr_map.o COBJS-y += bzlib.o COBJS-y += bzlib_crctable.o COBJS-y += bzlib_decompress.o diff --git a/lib_generic/addr_map.c b/lib_generic/addr_map.c new file mode 100644 index 0000000..ff8532c --- /dev/null +++ b/lib_generic/addr_map.c @@ -0,0 +1,81 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +static struct { + phys_addr_t paddr; + phys_size_t size; + unsigned long vaddr; +} address_map[CONFIG_SYS_NUM_ADDR_MAP]; + +phys_addr_t addrmap_virt_to_phys(void * vaddr) +{ + int i; + + for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) { + u64 base, upper, addr; + + if (address_map[i].size == 0) + continue; + + addr = (u64)((u32)vaddr); + base = (u64)(address_map[i].vaddr); + upper = (u64)(address_map[i].size) + base - 1; + + if (addr >= base && addr <= upper) { + return addr - address_map[i].vaddr + address_map[i].paddr; + } + } + + return (phys_addr_t)(~0); +} + +unsigned long addrmap_phys_to_virt(phys_addr_t paddr) +{ + int i; + + for (i = 0; i < CONFIG_SYS_NUM_ADDR_MAP; i++) { + u64 base, upper, addr; + + if (address_map[i].size == 0) + continue; + + addr = (u64)paddr; + base = (u64)(address_map[i].paddr); + upper = (u64)(address_map[i].size) + base - 1; + + if (addr >= base && addr <= upper) { + return paddr - address_map[i].paddr + address_map[i].vaddr; + } + } + + return (unsigned long)(~0); +} + +void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr, + phys_size_t size, int idx) +{ + if (idx > CONFIG_SYS_NUM_ADDR_MAP) + return; + + address_map[idx].vaddr = vaddr; + address_map[idx].paddr = paddr; + address_map[idx].size = size; +} -- cgit v1.1 From e39cd81c44740d7355d277ed3d38536cbe1e003d Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Fri, 5 Dec 2008 15:36:14 +0800 Subject: lib_ppc: rework the flush_cache - It is possible to miss flush/invalidate the last cache line, we fix it at here. - add the volatile and memory clobber. They are pointed by Scott Wood. Signed-off-by: Dave Liu --- lib_ppc/cache.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib_ppc/cache.c b/lib_ppc/cache.c index 72c838e..1292b71 100644 --- a/lib_ppc/cache.c +++ b/lib_ppc/cache.c @@ -25,29 +25,27 @@ #include #include -void flush_cache (ulong start_addr, ulong size) +void flush_cache(ulong start_addr, ulong size) { #ifndef CONFIG_5xx - ulong addr, end_addr = start_addr + size; + ulong addr, start, end; - if (CONFIG_SYS_CACHELINE_SIZE) { - addr = start_addr & (CONFIG_SYS_CACHELINE_SIZE - 1); - for (addr = start_addr; - addr < end_addr; - addr += CONFIG_SYS_CACHELINE_SIZE) { - asm ("dcbst 0,%0": :"r" (addr)); - WATCHDOG_RESET(); - } - asm ("sync"); /* Wait for all dcbst to complete on bus */ + start = start_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1); + end = start_addr + size - 1; - for (addr = start_addr; - addr < end_addr; - addr += CONFIG_SYS_CACHELINE_SIZE) { - asm ("icbi 0,%0": :"r" (addr)); - WATCHDOG_RESET(); - } + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { + asm volatile("dcbst 0,%0" : : "r" (addr) : "memory"); + WATCHDOG_RESET(); } - asm ("sync"); /* Always flush prefetch queue in any case */ - asm ("isync"); + /* wait for all dcbst to complete on bus */ + asm volatile("sync" : : : "memory"); + + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { + asm volatile("icbi 0,%0" : : "r" (addr) : "memory"); + WATCHDOG_RESET(); + } + asm volatile("sync" : : : "memory"); + /* flush prefetch queue */ + asm volatile("isync" : : : "memory"); #endif } -- cgit v1.1 From ecf5f077c8e77454f532eaac3e3afb7cfc48c62d Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Wed, 3 Dec 2008 11:28:30 -0600 Subject: i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions All implementations of the functions i2c_reg_read() and i2c_reg_write() are identical. We can save space and simplify the code by converting these functions into inlines and putting them in i2c.h. Signed-off-by: Timur Tabi Acked-By: Jean-Christophe PLAGNIOL-VILLARD --- cpu/arm920t/at91rm9200/i2c.c | 14 ---------- cpu/arm926ejs/davinci/i2c.c | 17 ------------ cpu/blackfin/i2c.c | 16 ----------- cpu/mpc512x/i2c.c | 17 ------------ cpu/mpc5xxx/i2c.c | 16 ----------- cpu/mpc8220/i2c.c | 16 ----------- cpu/mpc824x/drivers/i2c/i2c.c | 14 ---------- cpu/mpc8260/i2c.c | 16 ----------- cpu/mpc8xx/i2c.c | 33 ----------------------- cpu/ppc4xx/i2c.c | 20 -------------- cpu/pxa/i2c.c | 15 ----------- drivers/i2c/fsl_i2c.c | 16 ----------- drivers/i2c/soft_i2c.c | 19 ------------- include/i2c.h | 62 +++++++++++++++++++++++++++++++++++++++++-- 14 files changed, 60 insertions(+), 231 deletions(-) diff --git a/cpu/arm920t/at91rm9200/i2c.c b/cpu/arm920t/at91rm9200/i2c.c index b68c5dd..9fd72d3 100644 --- a/cpu/arm920t/at91rm9200/i2c.c +++ b/cpu/arm920t/at91rm9200/i2c.c @@ -189,20 +189,6 @@ i2c_init(int speed, int slaveaddr) return; } -uchar i2c_reg_read(uchar i2c_addr, uchar reg) -{ - unsigned char buf; - - i2c_read(i2c_addr, reg, 1, &buf, 1); - - return(buf); -} - -void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) -{ - i2c_write(i2c_addr, reg, 1, &val, 1); -} - int i2c_set_bus_speed(unsigned int speed) { return -1; diff --git a/cpu/arm926ejs/davinci/i2c.c b/cpu/arm926ejs/davinci/i2c.c index d220a4c..3ba20ef 100644 --- a/cpu/arm926ejs/davinci/i2c.c +++ b/cpu/arm926ejs/davinci/i2c.c @@ -331,21 +331,4 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) return(0); } - -u_int8_t i2c_reg_read(u_int8_t chip, u_int8_t reg) -{ - u_int8_t tmp; - - i2c_read(chip, reg, 1, &tmp, 1); - return(tmp); -} - - -void i2c_reg_write(u_int8_t chip, u_int8_t reg, u_int8_t val) -{ - u_int8_t tmp; - - i2c_write(chip, reg, 1, &tmp, 1); -} - #endif /* CONFIG_DRIVER_DAVINCI_I2C */ diff --git a/cpu/blackfin/i2c.c b/cpu/blackfin/i2c.c index 60f03d4..2a3e223 100644 --- a/cpu/blackfin/i2c.c +++ b/cpu/blackfin/i2c.c @@ -425,20 +425,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len) } -uchar i2c_reg_read(uchar chip, uchar reg) -{ - uchar buf; - - PRINTD("i2c_reg_read: chip=0x%02x, reg=0x%02x\n", chip, reg); - i2c_read(chip, reg, 0, &buf, 1); - return (buf); -} - -void i2c_reg_write(uchar chip, uchar reg, uchar val) -{ - PRINTD("i2c_reg_write: chip=0x%02x, reg=0x%02x, val=0x%02x\n", chip, - reg, val); - i2c_write(chip, reg, 0, &val, 1); -} - #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc512x/i2c.c b/cpu/mpc512x/i2c.c index 77a6f0d..4f6bc86 100644 --- a/cpu/mpc512x/i2c.c +++ b/cpu/mpc512x/i2c.c @@ -382,23 +382,6 @@ Done: return ret; } -uchar i2c_reg_read (uchar chip, uchar reg) -{ - uchar buf; - - i2c_read (chip, reg, 1, &buf, 1); - - return buf; -} - -void i2c_reg_write (uchar chip, uchar reg, uchar val) -{ - i2c_write (chip, reg, 1, &val, 1); - - return; -} - - int i2c_set_bus_num (unsigned int bus) { if (bus >= I2C_BUS_CNT) { diff --git a/cpu/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c index 4d16bbe..7d76274 100644 --- a/cpu/mpc5xxx/i2c.c +++ b/cpu/mpc5xxx/i2c.c @@ -380,20 +380,4 @@ Done: return ret; } -uchar i2c_reg_read(uchar chip, uchar reg) -{ - uchar buf; - - i2c_read(chip, reg, 1, &buf, 1); - - return buf; -} - -void i2c_reg_write(uchar chip, uchar reg, uchar val) -{ - i2c_write(chip, reg, 1, &val, 1); - - return; -} - #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc8220/i2c.c b/cpu/mpc8220/i2c.c index d67936d..76ecdf1 100644 --- a/cpu/mpc8220/i2c.c +++ b/cpu/mpc8220/i2c.c @@ -387,20 +387,4 @@ int i2c_write (uchar chip, uint addr, int alen, uchar * buf, int len) return ret; } -uchar i2c_reg_read (uchar chip, uchar reg) -{ - uchar buf; - - i2c_read (chip, reg, 1, &buf, 1); - - return buf; -} - -void i2c_reg_write (uchar chip, uchar reg, uchar val) -{ - i2c_write (chip, reg, 1, &val, 1); - - return; -} - #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc824x/drivers/i2c/i2c.c b/cpu/mpc824x/drivers/i2c/i2c.c index 854345e..637ae4c 100644 --- a/cpu/mpc824x/drivers/i2c/i2c.c +++ b/cpu/mpc824x/drivers/i2c/i2c.c @@ -267,18 +267,4 @@ int i2c_probe (uchar chip) return i2c_read (chip, 0, 1, (uchar *) &tmp, 1); } -uchar i2c_reg_read (uchar i2c_addr, uchar reg) -{ - uchar buf[1]; - - i2c_read (i2c_addr, reg, 1, buf, 1); - - return (buf[0]); -} - -void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) -{ - i2c_write (i2c_addr, reg, 1, &val, 1); -} - #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c index c124639..35cf8f1 100644 --- a/cpu/mpc8260/i2c.c +++ b/cpu/mpc8260/i2c.c @@ -753,22 +753,6 @@ i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) return 0; } -uchar -i2c_reg_read(uchar chip, uchar reg) -{ - uchar buf; - - i2c_read(chip, reg, 1, &buf, 1); - - return (buf); -} - -void -i2c_reg_write(uchar chip, uchar reg, uchar val) -{ - i2c_write(chip, reg, 1, &val, 1); -} - #if defined(CONFIG_I2C_MULTI_BUS) /* * Functions for multiple I2C bus handling diff --git a/cpu/mpc8xx/i2c.c b/cpu/mpc8xx/i2c.c index 29c7c71..338caba 100644 --- a/cpu/mpc8xx/i2c.c +++ b/cpu/mpc8xx/i2c.c @@ -42,19 +42,6 @@ DECLARE_GLOBAL_DATA_PTR; /* define to enable debug messages */ #undef DEBUG_I2C -/*----------------------------------------------------------------------- - * Set default values - */ -#ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED 50000 -#endif - -#ifndef CONFIG_SYS_I2C_SLAVE -#define CONFIG_SYS_I2C_SLAVE 0xFE -#endif -/*----------------------------------------------------------------------- - */ - /* tx/rx timeout (we need the i2c early, so we don't use get_timer()) */ #define TOUT_LOOP 1000000 @@ -717,24 +704,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) return 0; } -uchar -i2c_reg_read(uchar i2c_addr, uchar reg) -{ - uchar buf; - - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - - i2c_read(i2c_addr, reg, 1, &buf, 1); - - return (buf); -} - -void -i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) -{ - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - - i2c_write(i2c_addr, reg, 1, &val, 1); -} - #endif /* CONFIG_HARD_I2C */ diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 9073ee2..9d416ca 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -419,26 +419,6 @@ int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len) return (i2c_transfer(0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0); } -/*----------------------------------------------------------------------- - * Read a register - */ -uchar i2c_reg_read(uchar i2c_addr, uchar reg) -{ - uchar buf; - - i2c_read(i2c_addr, reg, 1, &buf, 1); - - return (buf); -} - -/*----------------------------------------------------------------------- - * Write a register - */ -void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) -{ - i2c_write(i2c_addr, reg, 1, &val, 1); -} - #if defined(CONFIG_I2C_MULTI_BUS) /* * Functions for multiple I2C bus handling diff --git a/cpu/pxa/i2c.c b/cpu/pxa/i2c.c index 08042be..6b72ba1 100644 --- a/cpu/pxa/i2c.c +++ b/cpu/pxa/i2c.c @@ -455,19 +455,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) } -uchar i2c_reg_read (uchar chip, uchar reg) -{ - uchar buf; - - PRINTD(("i2c_reg_read(chip=0x%02x, reg=0x%02x)\n",chip,reg)); - i2c_read(chip, reg, 1, &buf, 1); - return (buf); -} - -void i2c_reg_write(uchar chip, uchar reg, uchar val) -{ - PRINTD(("i2c_reg_write(chip=0x%02x, reg=0x%02x, val=0x%02x)\n",chip,reg,val)); - i2c_write(chip, reg, 1, &val, 1); -} - #endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 3b5c06b..ce646fd 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -367,22 +367,6 @@ i2c_probe(uchar chip) return i2c_read(chip, 0, 0, NULL, 0); } -uchar -i2c_reg_read(uchar i2c_addr, uchar reg) -{ - uchar buf[1]; - - i2c_read(i2c_addr, reg, 1, buf, 1); - - return buf[0]; -} - -void -i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) -{ - i2c_write(i2c_addr, reg, 1, &val, 1); -} - int i2c_set_bus_num(unsigned int bus) { #ifdef CONFIG_SYS_I2C2_OFFSET diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index d2a5142..f12dedf 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -435,22 +435,3 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) return(failures); } -/*----------------------------------------------------------------------- - * Read a register - */ -uchar i2c_reg_read(uchar i2c_addr, uchar reg) -{ - uchar buf; - - i2c_read(i2c_addr, reg, 1, &buf, 1); - - return(buf); -} - -/*----------------------------------------------------------------------- - * Write a register - */ -void i2c_reg_write(uchar i2c_addr, uchar reg, uchar val) -{ - i2c_write(i2c_addr, reg, 1, &val, 1); -} diff --git a/include/i2c.h b/include/i2c.h index 8d6f867..fad2d57 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -76,6 +76,20 @@ # define I2C_SOFT_DECLARATIONS # endif #endif + +#ifdef CONFIG_8xx +/* Set default values for the I2C bus speed and slave address on 8xx. In the + * future, we'll define these in all 8xx board config files. + */ +#ifndef CONFIG_SYS_I2C_SPEED +#define CONFIG_SYS_I2C_SPEED 50000 +#endif + +#ifndef CONFIG_SYS_I2C_SLAVE +#define CONFIG_SYS_I2C_SLAVE 0xFE +#endif +#endif + /* * Initialization, must be called once on start up, may be called * repeatedly to change the speed and slave addresses. @@ -132,8 +146,52 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len); /* * Utility routines to read/write registers. */ -uchar i2c_reg_read (uchar chip, uchar reg); -void i2c_reg_write(uchar chip, uchar reg, uchar val); +static inline u8 i2c_reg_read(u8 addr, u8 reg) +{ + u8 buf; + +#ifdef CONFIG_8xx + /* MPC8xx needs this. Maybe one day we can get rid of it. */ + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif + +#ifdef DEBUG + printf("%s: addr=0x%02x, reg=0x%02x\n", __func__, addr, reg); +#endif + +#ifdef CONFIG_BLACKFIN + /* This ifdef will become unneccessary in a future version of the + * blackfin I2C driver. + */ + i2c_read(addr, reg, 0, &buf, 1); +#else + i2c_read(addr, reg, 1, &buf, 1); +#endif + + return buf; +} + +static inline void i2c_reg_write(u8 addr, u8 reg, u8 val) +{ +#ifdef CONFIG_8xx + /* MPC8xx needs this. Maybe one day we can get rid of it. */ + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +#endif + +#ifdef DEBUG + printf("%s: addr=0x%02x, reg=0x%02x, val=0x%02x\n", + __func__, addr, reg, val); +#endif + +#ifdef CONFIG_BLACKFIN + /* This ifdef will become unneccessary in a future version of the + * blackfin I2C driver. + */ + i2c_write(addr, reg, 0, &val, 1); +#else + i2c_write(addr, reg, 1, &val, 1); +#endif +} /* * Functions for setting the current I2C bus and its speed -- cgit v1.1 From 5b3375ac8c36c29c87abb132fede0509eb21e5c9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 11 Dec 2008 06:23:37 -0500 Subject: env_sf: support embedded environments If both CONFIG_ENV_SECT_SIZE and CONFIG_ENV_SIZE are defined, and the sect size is larger than the env size, then it means the env is embedded in a block. So we have to save/restore the part of the sector which is not the environment. Previously, saving the environment in SPI flash in this setup would probably brick the board as the rest of the sector tends to contain actual U-Boot data/code. Signed-off-by: Mike Frysinger Acked-by: Haavard Skinnemoen --- common/env_sf.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/common/env_sf.c b/common/env_sf.c index 1bbf93f..2f52e25 100644 --- a/common/env_sf.c +++ b/common/env_sf.c @@ -27,6 +27,7 @@ */ #include #include +#include #include #ifndef CONFIG_ENV_SPI_BUS @@ -60,13 +61,30 @@ uchar env_get_char_spec(int index) int saveenv(void) { + u32 saved_size, saved_offset; + char *saved_buffer = NULL; u32 sector = 1; + int ret; if (!env_flash) { puts("Environment SPI flash not initialized\n"); return 1; } + /* Is the sector larger than the env (i.e. embedded) */ + if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { + saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; + saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; + saved_buffer = malloc(saved_size); + if (!saved_buffer) { + ret = 1; + goto done; + } + ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); + if (ret) + goto done; + } + if (CONFIG_ENV_SIZE > CONFIG_ENV_SECT_SIZE) { sector = CONFIG_ENV_SIZE / CONFIG_ENV_SECT_SIZE; if (CONFIG_ENV_SIZE % CONFIG_ENV_SECT_SIZE) @@ -74,15 +92,28 @@ int saveenv(void) } puts("Erasing SPI flash..."); - if (spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE)) - return 1; + ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); + if (ret) + goto done; puts("Writing to SPI flash..."); - if (spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr)) - return 1; + ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, env_ptr); + if (ret) + goto done; + + if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { + ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); + if (ret) + goto done; + } + ret = 0; puts("done\n"); - return 0; + + done: + if (saved_buffer) + free(saved_buffer); + return ret; } void env_relocate_spec(void) -- cgit v1.1 From 84bc72d90c505fec3ef4b693995407a0bd4064e5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 11 Dec 2008 18:39:08 -0500 Subject: spi/stmicro: fix debug() display of cmd The stmicro_wait_ready() func tries to show the actual opcode that was sent to the device, but instead it displays the array pointer. Fix it to pull out the opcode from the start of the array. Signed-off-by: Mike Frysinger --- drivers/mtd/spi/stmicro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c index b8b835a..86324e4 100644 --- a/drivers/mtd/spi/stmicro.c +++ b/drivers/mtd/spi/stmicro.c @@ -137,7 +137,7 @@ static int stmicro_wait_ready(struct spi_flash *flash, unsigned long timeout) ret = spi_xfer(spi, 32, &cmd[0], NULL, SPI_XFER_BEGIN); if (ret) { - debug("SF: Failed to send command %02x: %d\n", cmd, ret); + debug("SF: Failed to send command %02x: %d\n", cmd[0], ret); return ret; } -- cgit v1.1 From 455ae7e87f67c44e6aea68865c83acadd3fcd36c Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 01:02:17 +0100 Subject: Coding style cleanup, update CHANGELOG. Signed-off-by: Wolfgang Denk --- CHANGELOG | 2668 ++++++++++++++++++++++++++++++++++++++++ board/afeb9260/partition.c | 1 - common/cmd_ubi.c | 2 +- cpu/mcf52x2/cpu_init.c | 2 +- cpu/mpc86xx/start.S | 2 - cpu/ppc4xx/cpu.c | 1 - cpu/ppc4xx/start.S | 2 +- drivers/i2c/soft_i2c.c | 1 - drivers/mtd/ubi/crc32.c | 2 +- drivers/mtd/ubi/io.c | 2 +- drivers/mtd/ubi/vmt.c | 2 +- include/configs/PMC440.h | 2 +- include/configs/afeb9260.h | 1 - include/linux/crc32.h | 8 +- include/linux/mtd/partitions.h | 6 +- include/linux/mtd/ubi.h | 2 +- include/ubi_uboot.h | 2 +- 17 files changed, 2684 insertions(+), 22 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5926978..0c9c047 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,2671 @@ +commit 84bc72d90c505fec3ef4b693995407a0bd4064e5 +Author: Mike Frysinger +Date: Thu Dec 11 18:39:08 2008 -0500 + + spi/stmicro: fix debug() display of cmd + + The stmicro_wait_ready() func tries to show the actual opcode that was sent + to the device, but instead it displays the array pointer. Fix it to pull + out the opcode from the start of the array. + + Signed-off-by: Mike Frysinger + +commit 5b3375ac8c36c29c87abb132fede0509eb21e5c9 +Author: Mike Frysinger +Date: Thu Dec 11 06:23:37 2008 -0500 + + env_sf: support embedded environments + + If both CONFIG_ENV_SECT_SIZE and CONFIG_ENV_SIZE are defined, and the sect + size is larger than the env size, then it means the env is embedded in a + block. So we have to save/restore the part of the sector which is not the + environment. Previously, saving the environment in SPI flash in this + setup would probably brick the board as the rest of the sector tends to + contain actual U-Boot data/code. + + Signed-off-by: Mike Frysinger + Acked-by: Haavard Skinnemoen + +commit ecf5f077c8e77454f532eaac3e3afb7cfc48c62d +Author: Timur Tabi +Date: Wed Dec 3 11:28:30 2008 -0600 + + i2c: merge all i2c_reg_read() and i2c_reg_write() into inline functions + + All implementations of the functions i2c_reg_read() and + i2c_reg_write() are identical. We can save space and simplify the + code by converting these functions into inlines and putting them in + i2c.h. + + Signed-off-by: Timur Tabi + Acked-By: Jean-Christophe PLAGNIOL-VILLARD + +commit e39cd81c44740d7355d277ed3d38536cbe1e003d +Author: Dave Liu +Date: Fri Dec 5 15:36:14 2008 +0800 + + lib_ppc: rework the flush_cache + + - It is possible to miss flush/invalidate the last + cache line, we fix it at here. + - add the volatile and memory clobber. + + They are pointed by Scott Wood. + + Signed-off-by: Dave Liu + +commit 63240ba88cd6a220057a0f28e5bf97f5b17ac84b +Author: Kumar Gala +Date: Sat Dec 13 17:20:28 2008 -0600 + + Introduce addr_map library + + Add a library that helps in translating between virtual and physical + addresses. This library can be useful as a simple means to implement + map_physmem() and virt_to_phys() for platforms that need functionality + beyond the simple 1:1 mapping. + + Signed-off-by: Kumar Gala + +commit 65e43a10631537dcb92c302d36301a12308216c3 +Author: Kumar Gala +Date: Sat Dec 13 17:20:27 2008 -0600 + + Introduce virt_to_phys() + + virt_to_phys() returns the physical address given a virtual. In most + cases this will be just the input value as the vast majority of + systems run in a 1:1 mode. + + However in systems that are not running this way it should report the + physical address or ~0 if no mapping exists for the given virtual + address. + + Signed-off-by: Kumar Gala + +commit 45845301af3de8675c1f7bbc815c6de35452605a +Author: Yuri Tikhonov +Date: Sun Dec 7 22:12:50 2008 +0100 + + POST Make: fix the sub-dir dependencies missing. + + Signed-off-by: Yuri Tikhonov + +commit 22525779cb51f1bbe4e96fea7b778de1935a5a69 +Author: Martin Michlmayr +Date: Wed Aug 6 14:44:05 2008 +0300 + + Fix a typo in fw_env.config + + Reported-by: Martin Michlmayr + Signed-off-by: Wolfgang Denk + +commit ba490b7761c62b549c222a9723e532dc801a3899 +Author: Peter Tyser +Date: Mon Dec 1 16:22:45 2008 -0600 + + Remove unused CONFIG_ADDR_STREAMING defines + + Signed-off-by: Peter Tyser + +commit d16da93430520d3e46c1ab52eedacf36ab7a2311 +Author: Peter Tyser +Date: Mon Nov 24 11:54:47 2008 -0600 + + cmd_mem: Remove unused variable + + Signed-off-by: Peter Tyser + +commit 3aed3aa2c128ce9fb39ca3f4e9385a7499e93dbf +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun Dec 14 10:29:39 2008 +0100 + + Fix new found CFG_ + + Also fix some minor typos. + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Wolfgang Denk + +commit 0e0c862efe7279e9609db74d758cd1b84c6c7209 +Author: Sergei Poselenov +Date: Fri Sep 19 12:07:34 2008 +0200 + + Remove compiler warning: target CPU does not support interworking + + This warning is issued by modern ARM-EABI GCC on non-thumb targets. + + Signed-off-by: Vladimir Panfilov + Signed-off-by: Sergei Poselenov + +commit cd6734510a9ff0f41c4a73567d4080ea0033d2c1 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Mon Nov 24 13:33:51 2008 +0100 + + Fix FIT and FDT support to have CONFIG_OF_LIBFDT and CONFIG_FIT independent + + FDT support is used for both FIT style images and for architectures + that can pass a fdt blob to an OS (ppc, m68k, sparc). + + For other architectures and boards which do not pass a fdt blob to an + OS but want to use the new uImage format, we just need FIT support. + + Now we can have the 4 following configurations : + + 1) FIT only CONFIG_FIT + 2) fdt blob only CONFIG_OF_LIBFDT + 3) both CONFIG_OF_LIBFDT & CONFIG_FIT + 4) none none + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 19ef4f7a6ef3b725aa9fe4b4f5fb676a84160172 +Author: Matthias Fuchs +Date: Wed Dec 10 15:13:32 2008 +0100 + + ppc4xx: Disable EEPROM write access on PMC440 boards + + This patch disables EEPROM wrtie access by default on PMC440 board. + + Signed-off-by: Matthias Fuchs + +commit 5b67a1439a73ba6c34007d9ff60a2c6aa90265df +Author: Matthias Fuchs +Date: Wed Dec 10 15:12:56 2008 +0100 + + ppc4xx: Fix Ethernet PHY LED configuration on PMC440 boards + + Signed-off-by: Matthias Fuchs + +commit 71fa0714fe5134bc8718c38d5261d267e88582ba +Author: Stefan Roese +Date: Tue Nov 18 16:36:12 2008 +0100 + + MIPS: Flush data cache upon relocation + + This patch now adds a flush to the data cache upon relocation. The + current implementation is missing this. Only a comment states that it + should be done. So let's really do it now. + + Signed-off-by: Stefan Roese + Signed-off-by: Shinya Kuribayashi + +commit 44174343688dba32571a34550dba08971c65fef1 +Author: Stefan Roese +Date: Tue Nov 18 16:36:22 2008 +0100 + + MIPS: Add CONFIG_SKIP_LOWLEVEL_INIT + + This patch adds the CONFIG_SKIP_LOWLEVEL_INIT option to start.S. This + enables support for boards where the lowlevel initialization is + already done when U-Boot runs (e.g. via OnChip ROM). + + This will be used in the upcoming VCTH board support. + + Signed-off-by: Stefan Roese + Signed-off-by: Shinya Kuribayashi + +commit db08ecaa6eb8176904b3bae103a85ee8f735dc40 +Author: Stefan Roese +Date: Wed Nov 12 13:18:02 2008 +0100 + + MIPS: Add board_early_init_f() to init_sequence + + This patch adds the board_early_init_f() call to the MIPS init + sequence. A weak dummy implementation is also added which can be + overridden by a board specific version. + + This will be used by the upcoming VCTH board support. + + Signed-off-by: Stefan Roese + Signed-off-by: Shinya Kuribayashi + +commit 9d23fc584c4b7b8bb9ecbee48920b1b04b08fa1b +Author: Stefan Roese +Date: Wed Nov 12 13:18:19 2008 +0100 + + MIPS: Add onenand_init() to board.c and move nand_init() + + This patch adds a call to onenand_init() for OneNAND support and moves + the nand_init() call to an earlier place, so that the environment can + be used from NAND and OneNAND. + + Signed-off-by: Stefan Roese + Signed-off-by: Shinya Kuribayashi + +commit d8bbc51c7ba9b737a20984333d19fe28a3526431 +Author: Nobuhiro Iwamatsu +Date: Tue Dec 9 11:32:46 2008 +0900 + + sh: Update sh2/sh2a timer + + Renesas SH2/SH2A timer broken. + This patch fix timer function. + + Signed-off-by: Nobuhiro Iwamatsu + Signed-off-by: Nobuhiro Iwamatsu + +commit a319f1496210117b73198e3d889ffffaf6825d00 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Fri Dec 5 07:27:37 2008 +0100 + + sh: r2dplus fix register access + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit 4d4a96055f6917335a89dbdf2e5556fa5ac329f6 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Dec 2 07:40:03 2008 +0100 + + sh: r2dplus/lowlevel_init: coding style fix + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit c54b9a42d8f5ab5b2a039b3a2e6fde8b427745e5 +Author: Nobuhiro Iwamatsu +Date: Tue Nov 25 11:05:19 2008 +0900 + + sh: Changed value of CACHE_OC_NUM_ENTRIES and CACHE_OC_WAY_SHIFT + + SH4 is different a value of CACHE_OC_NUM_ENTRIES and + CACHE_OC_WAY_SHIFT every CPU. + This patch corrects these values. + + Signed-off-by: Nobuhiro Iwamatsu + Signed-off-by: Nobuhiro Iwamatsu + +commit e9d5f35497885b3c65d494d09a525d443dcccd3b +Author: Nobuhiro Iwamatsu +Date: Thu Nov 20 16:44:42 2008 +0900 + + sh: Update sh timer function + + Change to write/readX function and fix timer problem. + + Signed-off-by: Nobuhiro Iwamatsu + Signed-off-by: Nobuhiro Iwamatsu + +commit b81786cff476c41e332eaeb679158f6527cd67d4 +Author: Nobuhiro Iwamatsu +Date: Tue Nov 4 11:58:58 2008 +0900 + + sh: Migo-R: Update BSC value + + A value of BSC CS4 was wrong, Fixed it. + + Signed-off-by: Nobuhiro Iwamatsu + Signed-off-by: Nobuhiro Iwamatsu + +commit 5783758fd260a02f44566ad8f29f899565cd0403 +Author: Nobuhiro Iwamatsu +Date: Mon Nov 17 16:52:09 2008 +0900 + + sh: Update ms7722se board config + + Signed-off-by: Nobuhiro Iwamatsu + Signed-off-by: Nobuhiro Iwamatsu + +commit 15e2697c9f7fb2ba672a1a70f07cd6d9d4e92b51 +Author: Nobuhiro Iwamatsu +Date: Mon Nov 17 16:53:09 2008 +0900 + + sh: Update SuperH serial driver + + The address of SCFSR register is wrong at SH7720/SH7721. + This patch fix this. + + Signed-off-by: Nobuhiro Iwamatsu + Signed-off-by: Nobuhiro Iwamatsu + +commit 9a1d3557dcd47365c12eeab584b822e57d994352 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Nov 11 22:20:15 2008 +0100 + + sh: fix rsk7203 and MigoR out of tree build + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit 1951f847f0a851853871b613ad7cf21a5242226c +Author: Matthias Fuchs +Date: Wed Dec 10 14:41:25 2008 +0100 + + ppc4xx: Update TEXT_BASE for CPCI405 boards + + This patch fixes building U-Boot for CPCI405 boards. + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit 8c92af7b2fbd60ae87379477f93c7ec9441b7452 +Author: Stefan Roese +Date: Tue Dec 9 20:08:01 2008 +0100 + + ppc4xx: Remove some features from ALPR to fit into 256k again + + Signed-off-by: Stefan Roese + +commit 3b089e4f889a2902449d55e081c886ae607cae89 +Author: Stefan Roese +Date: Wed Dec 10 10:32:59 2008 +0100 + + UBI: Set ubi_dev.type back to DEV_TYPE_NONE upon failing initialization + + With this patch we set the type back to NONE upon failing UBI partition + initialization. Otherwise further calls to the UBI subsystem would try + to really access the non-existing UBI partition. + + Thanks to Michael Lawnick for pointing this out. + + Signed-off-by: Stefan Roese + +commit 817329351639a8895cd9b87b33aeff043f3d5a44 +Author: Stefan Roese +Date: Wed Dec 10 10:28:33 2008 +0100 + + UBI: Return -ENOMEM upon failing malloc + + Return with correct error code (-ENOMEM) from ubi_attach_mtd_dev() upon + failing malloc(). + + Signed-off-by: Stefan Roese + +commit 2145188bea2df8f2b47a87ec3071b55027e8d0ae +Author: Ben Warren +Date: Tue Dec 9 23:34:15 2008 -0800 + + Fix compile error in building MBX860T. + + Signed-off-by: Ben Warren + +commit 8fab49ea911fe925392fa5afcc9bc7373a3d0cee +Author: Michal Simek +Date: Tue Nov 25 11:42:20 2008 +0100 + + microblaze: Remove XUPV2P board + + --- + + Microblaze platforms use generic settings and to have + many platforms is confusing that's why I decided to remove this + platform from U-BOOT. ml401 tree is sufficient for covering + all Microblaze platforms. + + This change will go through microblaze custodian tree. + +commit 99ba6f353582720defff6e6e6761dc455a207d31 +Author: Michal Simek +Date: Mon Nov 24 18:25:41 2008 +0100 + + microblaze: Remove CONFIG_LIBFDT due to error in common files + +commit e7d591e823a991513833af7030468409e25a3b13 +Author: Michal Simek +Date: Mon Nov 24 11:43:00 2008 +0100 + + microblaze: Fix ml401 uart16550 setting + + Signed-off-by: Michal Simek + +commit c85ff0553a8cfbcca51c15b947e1ed55d3810a39 +Author: Michal Simek +Date: Mon Nov 24 11:38:22 2008 +0100 + + microblaze: Set up relocation is done + +commit bcb6dd9187d4b23c748704767bd12d20c829e996 +Author: Mike Frysinger +Date: Tue Dec 9 23:20:31 2008 -0500 + + tools/netconsole: new script for working with netconsole over UDP + + While the doc/README.NetConsole does have a snippet for people to + create their own netcat script, it's a lot easier to make a simple + dedicated script and tell people to use it. + + Also spruce it up a bit to make it user friendly. + + Signed-off-by: Mike Frysinger + +commit 8c5170a7d088601d5f30d85093388dab1f1e8ec0 +Author: Sonic Zhang +Date: Tue Dec 9 23:20:18 2008 -0500 + + fs/fat: handle FAT on SATA + + The FAT file system driver should also handle FAT on SATA devices. + + Signed-off-by: Sonic Zhang + Signed-off-by: Mike Frysinger + +commit 97a24a78ee6f34b89b821cb70eda1cf34aa11d97 +Author: Jerry Van Baren +Date: Mon Nov 24 08:15:02 2008 -0500 + + libfdt: Fix redefined uintptr_t warning for USE_HOSTCC + + Compiling U-Boot in an old OS environment (RedHat-7.3 :-) gives the + following warnings from FDT: + + include/libfdt_env.h:50: warning: redefinition of 'uintptr_t' + /usr/include/stdint.h:129: warning: 'uintptr_t' previously declared here + + Fix: Protect the definition of uintptr_t when compiling on the host + system. + + Signed-off-by: Gerald Van Baren + +commit 1fc2b165c51d6f40c8d505f1b3eaefdb6599b17b +Author: Graeme Russ +Date: Sat Nov 22 08:43:29 2008 +1100 + + Moved sc520 PCI definitions to stand-alone file + + Signed Off By: Graeme Russ + +commit 1f5070c0c18fa5684bfce09c8abdf10c04ed48fa +Author: Graeme Russ +Date: Sat Nov 22 08:43:21 2008 +1100 + + Fixed path to sc520 SSI include file + + Signed Off By: Graeme Russ + +commit d4f70da544c33db3e4fce6473dea4ecca4322545 +Author: Graeme Russ +Date: Fri Nov 21 06:28:05 2008 +1100 + + Fixed build error due to #define of _LINUX_STRING_H_ in 82559_eeprom.c + + Signed-off-by: Graeme Russ + +commit c034075a713b60e654c64e88e87da29440f31bb4 +Author: Stefan Roese +Date: Wed Nov 12 13:30:10 2008 +0100 + + serial: Add vcth UART driver + + This patch adds the UART driver for the upcoming VCTH board support. + + Signed-off-by: Stefan Roese + +commit 142a80ffc3b537a9c45acd2444a42a77f147c602 +Author: Ilya Yanok +Date: Thu Nov 13 19:49:36 2008 +0300 + + jffs2: cache data_crc results + + As we moved data_crc() invocation from jffs2_1pass_build_lists() to + jffs2_1pass_read_inode() data_crc is going to be calculated on each + inode access. This patch adds caching of data_crc() results. There + is no significant improvement in speed (because of flash access + caching added in previous patch I think, crc in RAM is really fast) + but this patch impacts memory usage -- every b_node structure uses + 12 bytes instead of 8. + + Signed-off-by: Alexey Neyman + Signed-off-by: Ilya Yanok + +commit 9b7076229ec6a958bd835ab70745f7676297ce82 +Author: Ilya Yanok +Date: Thu Nov 13 19:49:35 2008 +0300 + + jffs2: summary support + + This patch adds support for reading fs information from summary + node instead of scanning full eraseblock. + + Signed-off-by: Ilya Yanok + +commit 70741004dc28946cd82c7af6789c4ddb3fc94526 +Author: Ilya Yanok +Date: Thu Nov 13 19:49:34 2008 +0300 + + jffs2: add buffer to cache flash accesses + + With this patch JFFS2 code allocates memory buffer of max_totlen size + (size of the largest node, calculated during scan time) and uses it to + store entire node. Speeds up loading. If malloc fails we use old ways + to do things. + + Signed-off-by: Alexey Neyman + Signed-off-by: Ilya Yanok + +commit 8a36d31f72411144ac0412ee7e1880e801acd754 +Author: Ilya Yanok +Date: Thu Nov 13 19:49:33 2008 +0300 + + jffs2: rewrite jffs2 scanning code based on Linux one + + Rewrites jffs2_1pass_build_lists() function in style of Linux's + jffs2_scan_medium() and jffs2_scan_eraseblock(). + This includes: + - Caching flash acceses + - Smart dealing with free space + + Signed-off-by: Alexey Neyman + Signed-off-by: Ilya Yanok + +commit e0b5532579eda8b4629f1b4f6e49c3cc60f52237 +Author: Ilya Yanok +Date: Thu Nov 13 19:49:32 2008 +0300 + + jffs2: add sector_size field to part_info structure + + This patch adds sector_size field to part_info structure (used + by new JFFS2 code). + + Signed-off-by: Ilya Yanok + +commit f73846956778a7dfee83403ef9747aff77198848 +Author: Ilya Yanok +Date: Thu Nov 13 19:49:31 2008 +0300 + + jffs2: fix searching for latest version in jffs2_1pass_list_inodes() + + We need to update i_version inside cycle to find really latest version + inside jffs2_1pass_list_inodes(). With that fixed we can use isize inside + dump_inode() instead of calling expensive jffs2_1pass_read_inode(). + + Signed-off-by: Alexey Neyman + Signed-off-by: Ilya Yanok + +commit 1113cb764b3da256ef8a1f9539f4efbe221ff3c4 +Author: Wolfgang Denk +Date: Tue Dec 9 23:13:51 2008 +0100 + + evb64260: fix "cast to pointer from integer of different size" warnings + + Signed-off-by: Wolfgang Denk + +commit d2776827315c3d469b8cb4cec14d58877798daa2 +Author: Stefan Althoefer +Date: Sun Dec 7 19:39:11 2008 +0100 + + USB: descriptor handling + + Hi, + + I found a bug when working with the u-boot USB subsystem on IXP425 processor + (big endian Xscale aka ARMv5). + I recognized that the second usb_endpoint_descriptor of the attached memory + stick was corrupted. + + The reason for this are the packed structures below (either u-boot and + u-boot-usb): + + -------------- + /* Endpoint descriptor */ + struct usb_endpoint_descriptor { + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; + + } __attribute__ ((packed)); + /* Interface descriptor */ + struct usb_interface_descriptor { + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; + + unsigned char no_of_ep; + unsigned char num_altsetting; + unsigned char act_altsetting; + struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS]; + } __attribute__ ((packed)); + ------------ + + As usb_endpoint_descriptor is only 7byte in length, the start of all + odd ep_desc[] structures is not word aligned. This makes wMaxPacketSize + of these structures also not word aligned. + + ARMv5 Architecture however does not support non-aligned multibyte + data type (see A2.8 of ARM Architecture Reference Manual). + + Signed-off-by: Stefan Althoefer + Signed-off-by: Remy Böhmer + +commit 4c253fdb2a175ea3472c38a1455a16faa58e81f0 +Author: Kumar Gala +Date: Tue Dec 9 10:27:33 2008 -0600 + + drivers/fsl_pci_init: Fix compile warning + + fsl_pci_init.c: In function 'fsl_pci_setup_inbound_windows': + fsl_pci_init.c:122: warning: comparison is always true due to limited range of data type + + The check only makes sense if we are CONFIG_PHYS_64BIT + + Signed-off-by: Kumar Gala + +commit dedacc18a8c2b3951581eb721fa055a4e0ac4845 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun Dec 7 09:45:35 2008 +0100 + + usbtty/omap: update to current API + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Remy Böhmer + +commit ee2e9ba917a62cc2e3a484bb79c8da0e01cb93ed +Author: Anatolij Gustschin +Date: Tue Dec 9 17:52:05 2008 +0100 + + video: fix FADS823 and RRvision compiling issues + + Since commit 561858ee building for FADS823 and RRvision + doesn't work. Let's include version.h and timestamp.h + unconditionally to fix the problem. + + Signed-off-by: Anatolij Gustschin + +commit 2d2e05727fe4013f807ffa814dff0e75259a1db4 +Author: Stefan Roese +Date: Tue Dec 2 10:53:47 2008 +0100 + + UBI: Fix size parsing in "ubi create" + + Signed-off-by: Stefan Roese + +commit 2ee951ba2ac9874d2a93d52e7a187d3184be937e +Author: Stefan Roese +Date: Thu Nov 27 14:07:09 2008 +0100 + + UBI: Enable re-initializing of the "ubi part" command + + With this patch now, the user can call "ubi part" multiple times to + re-connect the UBI device to another MTD partition. + + Signed-off-by: Stefan Roese + +commit 9def12cae33d2d3ea2dd56b197fd3dfb3ad60bf4 +Author: Stefan Roese +Date: Thu Nov 27 14:05:15 2008 +0100 + + MTD: Fix problem based on non-working relocation (list head mtd_partitions) + + Don't use LIST_HEAD() but initialize the struct via INIT_LIST_HEAD() upon + first call of add_mtd_partitions(). Otherwise this won't work on platforms + where the relocation is broken (like MIPS or PPC). + + Signed-off-by: Stefan Roese + +commit 5e3ab68e9acf9edf304b8aa32ad7e005483a2c47 +Author: Trent Piepho +Date: Wed Nov 12 17:29:48 2008 -0800 + + Section name should be ".data", not "data" + + Signed-off-by: Trent Piepho + Signed-off-by: Wolfgang Denk + +commit 7fa6a2f3b66579dea8bc1a9177646e1141731b15 +Author: Wolfgang Denk +Date: Tue Dec 9 00:39:08 2008 +0100 + + MAKEALL: Automatically use parallel builds + + Add logic to the MAKEALL script to determine the number of CPU cores + on the system, and run a parallel build if there is more than one. + Usually this significantrly accelerates builds. + + Allow to manually adjust the number of parallel make jobs by using + the "BUILD_NCPUS" environment variable. + + Signed-off-by: Wolfgang Denk + +commit 268405fa7c44156c5192a70779920c70906af8d6 +Author: Wolfgang Denk +Date: Tue Dec 9 00:24:30 2008 +0100 + + vxworks.h: Fix build problem introduced by commits 29a4c24d/e9084b23 + + Signed-off-by: Wolfgang Denk + +commit 153176a9414120ca1736f3cc4951623d6e14e6af +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Nov 11 06:08:59 2008 +0100 + + avr32/bootm: remove unused variable 'ret' + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Acked-by: Haavard Skinnemoen + +commit 434c51a5e62f608a2a78ed5398ac43a1c77cc183 +Author: Peter Tyser +Date: Wed Nov 12 13:06:48 2008 -0600 + + Remove unneeded CONFIG_SHELL references + + Make should be using the bash shell by default which makes + CONFIG_SHELL unnecessary + + Signed-off-by: Peter Tyser + +commit cf7a7b99794bac936899819b95539be1dbd71708 +Author: Peter Tyser +Date: Wed Nov 12 12:33:20 2008 -0600 + + Use bash for default GNU Make shell application + + Some Make script commands rely on bash-specific features like brace + expansion, so default to bash for the SHELL variable with a fallback + to the standard sh shell + + Signed-off-by: Peter Tyser + +commit 4b530018764934ad5689196e9aa5714a6f4d1a6c +Author: Heiko Schocher +Date: Wed Nov 12 09:50:45 2008 +0100 + + jffs2: rename devices_init () in common/jffs2.c + + rename devices_init () in common/jffs2.c to + jffs2_devices_init (), because there is also a + devices_init () in common/devices.c. + + Signed-off-by: Heiko Schocher + +commit af5eb847a10f1037590001355d88bab3fe7be48b +Author: Daniel Hellstrom +Date: Mon Nov 10 12:46:20 2008 +0000 + + SPARC: Fixed compiler error introduced by commit c160a9544743 + + This patch fixes a build error for the SPARC platform. It was + introduced by commit c160a9544743e80e8889edb2275538e7764ce334. + + Signed-off-by: Daniel Hellstrom + +commit 4c60259899aa00f59db0d936b8807f9a26411c0f +Author: Gary Jennejohn +Date: Sun Nov 9 12:50:59 2008 +0100 + + mgsuvd add the board-specific part of the HDLC driver + + Signed-off-by: Gary Jennejohn + +commit 534a4359666af48bd69a3743d8a8c2bdb1d3ec70 +Author: Gary Jennejohn +Date: Sun Nov 9 12:45:03 2008 +0100 + + mgcoge add the board-specific part of the HDLC driver + + Signed-off-by: Gary Jennejohn + +commit 135f5534538bb8ea4f38a7030da12187d22ef7e0 +Author: Gary Jennejohn +Date: Sun Nov 9 12:36:15 2008 +0100 + + keymile add the common parts of the HDLC driver + + This implements the ICN protocol used across the backplane and is + needed by all the keymile boards. + + Signed-off-by: Gary Jennejohn + +commit 1cb82a9207a550557399eabc7fe47f21bbd9ddf8 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Fri Nov 7 22:46:22 2008 +0100 + + drivers/bios_emulator: Move conditional compilation to Makefile + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit bcdf1d2cf6b24fb905fd7da80da4b3c65a7995b5 +Author: Richard Retanubun +Date: Thu Nov 6 14:01:51 2008 -0500 + + common/cmd_ide.c: Corrected endian order printing for compact flash serial number. + + Corrected endian order printing for compact flash serial number. + + Signed-off-by: Richard Retanubun + +commit 16a28ef219c27423a1ef502f19070c4d375079b8 +Author: Gary Jennejohn +Date: Thu Nov 6 15:04:23 2008 +0100 + + IOMUX: Add console multiplexing support. + + Modifications to support console multiplexing. This is controlled using + CONFIG_SYS_CONSOLE_MUX in the board configuration file. + + This allows a user to specify multiple console devices in the environment + with a command like this: setenv stdin serial,nc. As a result, the user can + enter text on both the serial and netconsole interfaces. + + All devices - stdin, stdout and stderr - can be set in this manner. + + 1) common/iomux.c and include/iomux.h contain the environment setting + implementation. + 2) doc/README.iomux contains a somewhat more detailed description. + 3) The implementation in (1) is called from common/cmd_nvedit.c to + handle setenv and from common/console.c to handle initialization of + input/output devices at boot time. + 4) common/console.c also contains the code needed to poll multiple console + devices for input and send output to all devices registered for output. + 5) include/common.h includes iomux.h and common/Makefile generates iomux.o + when CONFIG_SYS_CONSOLE_MUX is set. + + Signed-off-by: Gary Jennejohn + +commit 774ce72026f74ac9641bcbbc588b20f2e13f7ab8 +Author: Mike Frysinger +Date: Tue Nov 4 16:03:46 2008 -0500 + + strings: use puts() rather than printf() + + When running `strings` on really long strings, the stack tends to get + smashed due to printf(). Switch to puts() instead since we're only passing + the data through. + + Signed-off-by: Mike Frysinger + +commit b03150b52e3c491a86a3cc0945274f0e8f9872e7 +Author: Niklaus Giger +Date: Mon Nov 3 22:16:18 2008 +0100 + + Use new CONFIG_SYS_VXWORKS parameters for Netstal boards + + Signed-off-by: Niklaus Giger + +commit 29a4c24de99d8cb4ac32991c04cab87ed94ca1f9 +Author: Niklaus Giger +Date: Mon Nov 3 22:15:34 2008 +0100 + + cmd_elf.c: Cleanup bootvx and handle new CONFIG_SYS_VXWORKS parameters + + - fix size too small by one in sprintf + - changed old (pre 2004) device name ibmEmac to emac + - boot device may be overriden in board config + - servername may be defined in board config + - additional parameters may be defined in board config + - fixed some line wrappings + - replaced redundant MAX define by max + + Signed-off-by: Niklaus Giger + +commit e9084b23d16102f44ace24379a1c0c352497ef80 +Author: Niklaus Giger +Date: Mon Nov 3 22:14:36 2008 +0100 + + Add vxworks.h to handle CONFIG_SYS_VXWORKS parameters + + Signed-off-by: Niklaus Giger + +commit 0b2f4ecad473d785959c7976f20d2a00bd0ee01f +Author: Niklaus Giger +Date: Mon Nov 3 22:13:47 2008 +0100 + + README: Document CONFIG_SYS parameters for vxworks + + Signed-off-by: Niklaus Giger + +commit ace514837cac656e29c37a19569cb8ea83071126 +Author: Peter Tyser +Date: Fri Oct 31 11:12:38 2008 -0500 + + lcd: Let the board code show board-specific info cleanup + + remove unneeded version.h from lcd.c + + Signed-off-by: Peter Tyser + Signed-off-by: Wolfgang Denk + +commit 561858ee7d0274c3e89dc98d4d0698cb6fcf6fd9 +Author: Peter Tyser +Date: Mon Nov 3 09:30:59 2008 -0600 + + Update U-Boot's build timestamp on every compile + + Use the GNU 'date' command to auto-generate a new U-Boot + timestamp on every compile. + + Signed-off-by: Peter Tyser + +commit 83ad179e2f0f625b88adb8ef5696709e46fb9077 +Author: Remy Bohmer +Date: Thu Dec 4 22:25:57 2008 +0100 + + Remove redundant armv4 flag from arm926ejs compile flags + + Currently the arm926ejs tree has the armv4 option set during compilation. + This flag does not belong here because a arm926 CPU is always a armv5 CPU. + + Signed-off-by: Remy Bohmer + +commit 89a7a87f084c657f8e32b513a77b50eca07e17ec +Author: Nicolas Ferre +Date: Sat Dec 6 13:11:14 2008 +0100 + + at91: Choose environment variables location within make config target + + This patch adds the possiblity to choose the media where the environment will + be located. This allow to choose this fundamental configuration without editing + config files. + + Documentation file added. + + Signed-off-by: Nicolas Ferre + Acked-by: Stelian Pop + Acked-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 1450c4a6682378567030414a9f1198c39b7730c7 +Author: Anatolij Gustschin +Date: Mon Nov 3 15:30:34 2008 +0100 + + lwmon, tqm8xx: Fix build errors + + Commit 6b59e03e0237a40a2305ea385defdfd92000978b + lcd: Let the board code show board-specific info + + introduced some bugs which prevent U-Boot building + for lwmon board if CONFIG_LCD_INFO_BELOW_LOGO will + be defined in the board configuration. + + Also "LCD enabled" building for TQM823L doesn't work + since this commit. + + This patch fixes above-mentioned issues. + + Signed-off-by: Anatolij Gustschin + +commit bfa0af6b22ff25b0719a8910f9b6d1f975aa6fb0 +Author: Mike Frysinger +Date: Sun Nov 2 01:18:18 2008 -0400 + + ignore .gdb_history files + + When using gdb, history files will often get generated. So ignore them. + + Signed-off-by: Mike Frysinger + +commit c8aa7dfc18f7cc90d0aea6c7becbb67dfc5bba4b +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Fri Oct 31 12:26:55 2008 +0100 + + FPGA: move fpga drivers to drivers/fpga + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 6a86bb6c25376f0358478219fa28d7c84dd01ed0 +Author: Peter Tyser +Date: Mon Dec 1 16:29:38 2008 -0600 + + net: Fix TftpStart() ip:filename bug + + The TftpStart() function modifies the 'BootFile' + string when 'BootFile' contains both an IP address + and filename (eg 1.2.3.4:/path/file). This causes + subsequent calls to TftpStart to incorrectly parse + the TFTP filename and server IP address to use. + For example: + + => tftp 0x100000 10.52.0.62:/home/ptyser/non_existant + Speed: 100, half duplex + Using eTSEC1 device + TFTP from server 10.52.0.62; our IP address is 10.52.253.79 + ^^^^^^^^^^ CORRECT + Filename '/home/ptyser/non_existant'. + ^^^^^^^^^^^^^^^^^^^^^^^^^ CORRECT + Load address: 0x100000 + Loading: * + TFTP error: 'File not found' (1) + Starting again + + eTSEC2: No link. + Speed: 100, half duplex + Using eTSEC1 device + TFTP from server 10.52.0.33; our IP address is 10.52.253.79 + ^^^^^^^^^^ WRONG + Filename '10.52.0.62'. + ^^^^^^^^^^ WRONG + Load address: 0x100000 + Loading: * + TFTP error: 'File not found' (1) + Starting again + + TftpStart() was modified to not modify the 'BootFile' string. + + Signed-off-by: Peter Tyser + Signed-off-by: Ben Warren + +commit d32c5be50bf0600bfdc54223ef341ee9c63db445 +Author: Peter Tyser +Date: Mon Dec 1 16:26:21 2008 -0600 + + net: Add additional IP fragmentation check + + Ignore IP packets which have the "more fragments" flag bit + set. This flag indicates the IP packet is fragmented and + must be ignored by U-Boot. + + Signed-off-by: Peter Tyser + Signed-off-by: Ben Warren + +commit e0c07b868cab405ab4b5335a0247899bfc5ea0b6 +Author: Peter Tyser +Date: Mon Dec 1 16:26:20 2008 -0600 + + net: Define IP flag field values + + These defines were pulled from the "Add simple + IP/UDP fragmentation support" patch from Frank + Haverkamp . + + Signed-off-by: Peter Tyser + Signed-off-by: Ben Warren + +commit 23afaba65ec5206757e589ef334a8b38168c045f +Author: Anatolij Gustschin +Date: Tue Dec 2 10:31:04 2008 +0100 + + net: tsec: Fix Marvell 88E1121R phy init + + This patch tries to ensure that phy interrupt pin + won't be asserted after booting. We experienced + following issues with current 88E1121R phy init: + + Marvell 88E1121R phy can be hardware-configured + to share MDC/MDIO and interrupt pins for both ports + P0 and P1 (e.g. as configured on socrates board). + Port 0 interrupt pin will be shared by both ports + in such configuration. After booting Linux and + configuring eth0 interface, port 0 phy interrupts + are enabled. After rebooting without proper eth0 + interface shutdown port 0 phy interrupts remain + enabled so any change on port 0 (link status, etc.) + cause assertion of the interrupt. Now booting Linux + and configuring eth1 interface will cause permanent + phy interrupt storm as the registered phy 1 interrupt + handler doesn't acknowledge phy 0 interrupts. This + of course should be fixed in Linux driver too. + + Signed-off-by: Anatolij Gustschin + Acked-by: Andy Fleming + Signed-off-by: Ben Warren + +commit 2e4970d8109d690adcf615d9e3cac7b5b2e8eaed +Author: Peter Tyser +Date: Tue Dec 2 12:59:51 2008 -0600 + + net: Fix download command parsing + + When CONFIG_SYS_HUSH_PARSER is defined network download + commands with 1 argument in the format 'tftp "/path/file"' + do not work as expected. The hush command parser strips + the quotes from "/path/file" which causes the network + commands to interpret "/path/file" as an address + instead of the intended filename. + + The previous check for a leading quote in netboot_common() + was replaced with a check which ensures only valid + numbers are treated as addresses. + + Signed-off-by: Peter Tyser + Signed-off-by: Ben Warren + +commit 3c2c2f427905040c1513d0c51d637689cba48346 +Author: Remy Bohmer +Date: Thu Nov 27 22:30:27 2008 +0100 + + Remove non-ascii characters from fat code + + This code contains some non-ascii characters in comment lines and code. + Most editors do not display those characters properly and editing those + files results always in diffs at these places which are usually not required + to be changed at all. This is error prone. + + So, remove those weird characters and replace them by normal C-style + equivalents for which the proper defines were already in the header. + + Signed-off-by: Remy Bohmer + +commit dc889e865356497d3e495570118c2245ebce2631 +Author: Dave Liu +Date: Fri Nov 28 20:16:58 2008 +0800 + + 85xx: fix the wrong DDR settings for MPC8572DS + + The default DDR freq is 400MHz or 800M data rate, + the old settings is pure wrong for the default case. + + Signed-off-by: Dave Liu + Acked-by: Andy Fleming + +commit 9df59533f77de2829b4b66e5b7620e04edaa391c +Author: Kumar Gala +Date: Mon Nov 24 10:29:26 2008 -0600 + + 85xx: init gd as early as possible + + Moved up the initialization of GD so C code like set_tlb() can use + gd->flags to determine if we've relocated or not in the future. + + Signed-off-by: Kumar Gala + Acked-by: Andy Fleming + +commit aed461af81012a398a205e9be67ab37667491838 +Author: Kumar Gala +Date: Mon Nov 24 10:29:25 2008 -0600 + + 85xx: Fix relocation of CCSRBAR + + If the virtual address for CCSRBAR is the same after relocation but + the physical address is changing we'd end up having two TLB entries with + the same VA. Instead we new us the new CCSRBAR virt address + 4k as a + temp virt address to access the old CCSRBAR to relocate it. + + Signed-off-by: Kumar Gala + Acked-by: Andy Fleming + +commit ea154a1781135d822eedee7567cc156089eae93c +Author: Kumar Gala +Date: Mon Nov 24 10:25:14 2008 -0600 + + FSL: Moved BR_PHYS_ADDR for localbus to common header + + The BR_PHYS_ADDR macro is useful on all machines that have local bus + which is pretty much all 83xx/85xx/86xx chips. + + Additionally most 85xx & 86xx will need it if they want to support + 36-bit physical addresses. + + Signed-off-by: Kumar Gala + Acked-by: Andy Fleming + +commit 9427ccde0355a2ebf47454e8e1be59f5b9864e08 +Author: Peter Tyser +Date: Mon Dec 1 13:47:12 2008 -0600 + + 85xx: Add PORDEVSR_PCI1 define + + Add define used to determine if PCI1 interface is in PCI or PCIX mode. + + Convert users of the old PORDEVSR_PCI constant to use MPC85xx_PORDEVSR_PCI1 + + Signed-off-by: Peter Tyser + Signed-off-by: Andy Fleming + +commit 35db1c6d34b57ae15e99cf03c8e8f8a6148d74f3 +Author: Becky Bruce +Date: Fri Nov 21 19:24:22 2008 -0600 + + drivers/fsl_pci_init: Fix inbound window mapping bug + + The current code will cause the creation of a 4GB window + starting at 0 if we have more than 4GB of RAM installed, + which overlaps with PCI_MEM space and causes pci_bus_to_phys() + to return erroneous information. Limit the size to 4GB - 1; + which causes the code to create one 2GB and one 1GB window + instead. + + Signed-off-by: Becky Bruce + Signed-off-by: Kumar Gala + Acked-by: Andy Fleming + +commit 5a105a333dab6a23e92d763ce76d6f31d57f45df +Author: Jon Loeliger +Date: Thu Nov 20 15:36:48 2008 -0600 + + Removed unused CONFIG_L1_INIT_RAM symbol. + + Prevent further viral propogation of the unused + symbol CONFIG_L1_INIT_RAM by just removing it. + + Signed-off-by: Jon Loeliger + Acked-by: Andy Fleming + +commit 7008d26a40a76f90cae5824c812cfed449fb97b8 +Author: Ed Swarthout +Date: Wed Oct 29 09:21:44 2008 -0500 + + fsl ddr skip interleaving if not supported. + + Removed while(1) hang if memctl_intlv_ctl is set wrong. + Remove embedded tabs from strings. + + Signed-off-by: Ed Swarthout + Acked-by: Kumar Gala + Acked-by: Andy Fleming + +commit dd332e18d082de75eca3fc2c7c778f5d4571a096 +Author: Anatolij Gustschin +Date: Thu Nov 13 18:08:57 2008 +0100 + + 85xx: socrates: fix DDR SDRAM tlb entry configuration + + since commit be0bd8234b9777ecd63c4c686f72af070d886517 + tlb entry for socrates DDR SDRAM will be reconfigured + by setup_ddr_tlbs() from initdram() causing an + inconsistency with previously configured DDR SDRAM tlb + entry from tlb_table: + + socrates>l2cam 7 9 + IDX PID EPN SIZE V TS RPN U0-U3 WIMGE UUUSSS + 7 : 00 00000000 256MB V 0 -> 0_00000000 0000 -I-G- ---RWX + 8 : 00 00000000 256MB V 0 -> 0_00000000 0000 ----- ---RWX + 9 : 00 10000000 256MB V 0 -> 0_10000000 0000 ----- ---RWX + + This patch makes the presence of the DDR SDRAM tlb entry in + the tlb_table dependent on CONFIG_SPD_EEPROM to avoid this + inconsistency. + + Signed-off-by: Anatolij Gustschin + Acked-by: Andy Fleming + +commit a2cd50ed6ef0ac6b127b3d6db756979a8336718d +Author: Peter Tyser +Date: Tue Nov 11 10:17:10 2008 -0600 + + 85xx: Add CPU 2 errata workaround to all 8548 boards + + All mpc8548-based boards should implement the suggested workaround + to CPU 2 errata. Without the workaround, its possible for the + 8548's core to hang while executing a msync or mbar 0 instruction + and a snoopable transaction from an I/O master tagged to make + quick forward progress is present. + + Signed-off-by: Peter Tyser + Acked-by: Andy Fleming + +commit e57f0fa1333cdf3ca36110aac2900712a5f82976 +Author: Dave Liu +Date: Tue Oct 28 17:53:45 2008 +0800 + + 85xx: the DDR tlb is missed for the !CONFIG_SPD_EEPROM case + + we need TLB entry for DDR at !SPD case. + + Signed-off-by: Dave Liu + Acked-by: Andy Fleming + +commit 9b0ad1b1c7a15ff674978705c7c52264978dc5d8 +Author: Dave Liu +Date: Tue Oct 28 17:53:38 2008 +0800 + + 85xx: remove the unused ddr_enable_ecc in the board file + + The DDR controller of 8548/8544/8568/8572/8536 processors + have the ECC data init feature, and the new DDR code is + using the feature, and we don't need the way with DMA to + init memory any more. + + Signed-off-by: Dave Liu + Acked-by: Andy Fleming + +commit 4a129a57d923f7c15aa1f567028a80a32d66a100 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun Nov 30 19:36:53 2008 +0100 + + at91rm9200dk: Fix typo + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit ed3b18e05c9a8ffa5fb643da9bcec7452e5d5e01 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun Nov 30 19:36:50 2008 +0100 + + AT91: remove non supported board AT91RM9200DF macro + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit bd876772ee04095e5dd943d97515a1f14bad4b1c +Author: Ilko Iliev +Date: Tue Dec 2 17:27:54 2008 +0100 + + mtd/dataflash.c: fix a problem with the last partition + + This patch fix the problem that only the [NB_DATAFLASH_AREA - 1] dataflash + partition can be defined to use the area to the end of dataflash size. + Now it is possible to have only one dataflash partition from 0 to the end + of of dataflash size. + + Signed-off-by: Ilko Iliev + +commit 03f797793b124dccaae145b977d15d6cb9e74504 +Author: Ilko Iliev +Date: Tue Dec 2 17:20:17 2008 +0100 + + fix some coding style violations. + + This patch fix some coding style violations. + + Signed-off-by: Ilko Iliev + +commit 5e46b1e54112f4b7fd5185665e571510132c12a7 +Author: Stefan Roese +Date: Thu Nov 27 14:11:37 2008 +0100 + + OneNAND: Add missing mtd info struct before calling onenand_erase() + + Without this patch "saveenv" crashes when MTD partitions are enabled (e.g. + for use in UBI) via CONFIG_MTD_PARTITIONS. + + Signed-off-by: Stefan Roese + Signed-off-by: Scott Wood + +commit 29382d4064fbaff5daacff4c3209370fa5713966 +Author: Becky Bruce +Date: Thu Nov 20 16:43:52 2008 -0600 + + mpc8641: Fix error in README + + I made some updates to the code that didn't make it into the + README - fix this + + Signed-off-by: Becky Bruce + +commit 801a194616d95e6fc426a176d9615ccbf9876c7f +Author: Jon Loeliger +Date: Thu Nov 20 12:01:02 2008 -0600 + + Removed unused CONFIG_L1_INIT_RAM symbol. + + Prevent further viral propogation of the unused + symbol CONFIG_L1_INIT_RAM by just removing it. + + Signed-off-by: Jon Loeliger + +commit f698738e46cb461e28c2d58228bb34a2fcf5a475 +Author: Jon Loeliger +Date: Thu Nov 20 14:02:56 2008 -0600 + + 86xx: Fix non-64-bit compilation problems. + + Introducing 64-bit (36-bit) support for the MPC8641HPCN + failed to accomodate the other two 86xx boards. + Introduce definitions for CONFIG_SYS_CCSRBAR_PHYS_{LOW,HIGH} + CONFIG_SYS_CCSR_DEFAULT_DBAT{U,L} and CONFIG_SYS_CCSR_DEFAULT_IBAT{U,L} + with nominal 32-bit values. + + Signed-off-by: Jon Loeliger + Acked-by: Becky Bruce + +commit bebfc6ef3ec994c8e18783269b1d8d41f8e38afd +Author: Michael Trimarchi +Date: Wed Nov 26 17:40:37 2008 +0100 + + Remove obsolete command (apply afte USB style patch, 80 chars strict) + + Remove USB obsolete commmand + + Signed-off-by: Michael Trimarchi + Signed-off-by: Remy Böhmer + +commit de39f8c19d7c12017248c49d432dcb81db68f724 +Author: Michael Trimarchi +Date: Wed Nov 26 17:41:34 2008 +0100 + + USB style patch, 80 chars strict + + USB Code style patch + + Signed-off-by: Michael Trimarchi + Signed-off-by: Remy Böhmer + +commit d10c5a87cb8affbb4d35a311370316d4383d598e +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Fri Nov 7 22:46:21 2008 +0100 + + drivers/usb: Move conditional compilation to Makefile + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Remy Böhmer + +commit 2077e348c2a84901022ad95311b47b70361e6daa +Author: Scott Wood +Date: Tue Nov 25 10:47:02 2008 -0600 + + NAND: Fix misplaced return statement in nand_{read,write}_skip_bad(). + + This caused the operation to be needlessly repeated if there were + no bad blocks and no errors. + + Signed-off-by: Valeriy Glushkov + Signed-off-by: Scott Wood + +commit 89295028e7d8f7a524f485328279d72fdb102385 +Author: Michal Simek +Date: Mon Nov 24 12:09:50 2008 +0100 + + ppc4xx: ml300 remove Xilinx BSP from ml300 folder + + This BSP should be outside u-boot source tree. + The second reason is that xilinx ppc405 was moved to generic platform. + + Signed-off-by: Michal Simek + Signed-off-by: Stefan Roese + +commit 24eea623d4974a169026a975ba12fb23d48154b1 +Author: Matthias Fuchs +Date: Mon Nov 24 15:11:10 2008 +0100 + + ppc4xx: Remove unused features + + This patch disables some unused features from the PCI405 configuration + to keep U-Boot image size below 192k. + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit 0c2385c3bb51f5d3911fce1ec4720db86b534c2b +Author: Matthias Fuchs +Date: Mon Nov 24 15:11:09 2008 +0100 + + ppc4xx: Use correct io accessors for PCI405 + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit 348c849d86a6f0785752b9bc497a34658713d1d1 +Author: Matthias Fuchs +Date: Mon Nov 24 15:11:08 2008 +0100 + + ppc4xx: Remove unused code from PCI405 code + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit 58c696eed839af894e0265064669c402dc28b371 +Author: Wolfgang Denk +Date: Mon Nov 24 21:50:59 2008 +0100 + + AT91RM9200DK: fix broken boot from NOR flash + + Signed-off-by: Wolfgang Denk + +commit 8052352f20b33bef8f9872fc983eac73d4693c38 +Author: Jens Scharsig +Date: Tue Nov 18 10:48:46 2008 +0100 + + at91rm9200: fix broken boot from nor flash + + This patch fix the broken boot from NOR Flash on AT91RM9200 boards, if + CONFIG_AT91RM9200 is defined and nor preloader is used. + + Signed-off-by: Jens Scharsig + +commit 25ea652e907516a283b38237e83712a918f125d7 +Author: Piotr Ziecik +Date: Mon Nov 17 15:58:00 2008 +0100 + + UBI: Add proof-of-concept CFI flash support + + With this patch UBI can be used on CFI flash chips. + + Signed-off-by: Piotr Ziecik + Signed-off-by: Stefan Roese + +commit e6a7edbc1778d27431ac663b40a71dafa5d20578 +Author: Piotr Ziecik +Date: Mon Nov 17 15:57:59 2008 +0100 + + mtd: Remove a printf() from add_mtd_device(). + + Remove a printf() from add_mtd_device(), which produces spurious output. + + Signed-off-by: Piotr Ziecik + Signed-off-by: Stefan Roese + +commit 91809ed51d8327a8dbbf29aa98a091154c282171 +Author: Piotr Ziecik +Date: Mon Nov 17 15:57:58 2008 +0100 + + cfi-mtd: Add cfi-mtd driver. + + Add cfi-mtd driver, which exports CFI flash to MTD layer. + This allows CFI flash devices to be used from MTD layer. + + Building of the new driver is controlled by CONFIG_FLASH_CFI_MTD + option. Initialization is done by calling cfi_mtd_init() from + flash_init(). + + Signed-off-by: Piotr Ziecik + Signed-off-by: Stefan Roese + +commit 6ea808efdf9aa5d9067fbfac32acde8539129ed2 +Author: Piotr Ziecik +Date: Mon Nov 17 15:49:32 2008 +0100 + + cfi_flash: Add interface for flash verbosity control + + Add interface for flash verbosity control. It allows + to disable output from low-level flash API. It is useful + when calling these low-level functions from context other + than flash commands (for example the MTD/CFI interface + implmentation). + + Signed-off-by: Piotr Ziecik + Signed-off-by: Stefan Roese + +commit ebc9784ce6528385bb8d2558e783622d4bbf20f8 +Author: Piotr Ziecik +Date: Thu Nov 20 15:17:38 2008 +0100 + + cfi_flash: Export flash_sector_size() function. + + Export flash_sector_size() function from drivers/mtd/cfi_flash.c, + so that it can be used in the upcoming cfi-mtd driver. + + Signed-off-by: Piotr Ziecik + Signed-off-by: Stefan Roese + +commit 45aa5a7f4d5bcb79927ddfc896c1d7c4326e235d +Author: Stefan Roese +Date: Mon Nov 17 14:45:22 2008 +0100 + + cfi_flash: Make all flash access functions weak + + This patch defines all flash access functions as weak so that + they can be overridden by board specific versions. + + This will be used by the upcoming VCTH board support where the NOR + FLASH unfortunately can't be accessed memory-mapped. Special + accessor functions are needed here. + + To enable this weak functions you need to define + CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS in your board config header. + Otherwise the "old" default functions will be used resulting + in smaller code. + + Signed-off-by: Stefan Roese + Acked-by: Haavard Skinnemoen + +commit a5c4067017631d903e1afa6ad615f0ce19fea517 +Author: Stefan Roese +Date: Mon Nov 24 08:31:16 2008 +0100 + + UBI: Change parsing of size in commands to default to hex + + Currently the size parameters of the UBI commands (e.g. "ubi write") are + decoded as decimal instead of hex as default. This patch now interprets + all these values consistantly as hex, as all other standard U-Boot commands + do. + + Signed-off-by: Stefan Roese + +commit de01c76c3ccc4e6c5989228eed58e955a3a1a968 +Author: Stefan Roese +Date: Fri Nov 21 13:06:06 2008 +0100 + + ppc4xx: ML2 shouldn't include the 4xx EMAC driver + + Signed-off-by: Stefan Roese + +commit 1a6a00dcc5bdfc6e9b4b00f39c1f583a7f96fc7f +Author: Yuri Tikhonov +Date: Fri Nov 14 16:19:19 2008 +0300 + + ppc4xx: katmai: Change default config + + This patch enables support for EXT2, and increases the + CONFIG_SYS_BOOTMAPSZ size for the default configuration + of the katmai boards to use them as the RAID-reference + AMCC setups. + + EXT2 enabling allows one to boot kernels from the EXT2 + formatted Compact Flash cards. + + CONFIG_SYS_BOOTMAPSZ increasing allows one to boot the + Linux kernels, which use PAGE_SIZE of 256KB. Otherwise, + the memory area with DTB file (which is placed at the + end of the bootmap area) will turn out to be overlapped + with the BSS segment of the 256KB kernel, and zeroed + in early_init() of Linux. + + Actually, increasing of the bootmap size could be done + via setting of the bootm_size U-Boot variable, but it looks + like the current U-Boot implementation have some bootm_size- + related functionality lost. In many places through the U-Boot + code the CONFIG_SYS_BOOTMAPSZ definition is used directly + (instead of trying to read the corresponding value from the + environment). The same is truth for the boot_jump_linux() + function in lib_ppc/bootm.c, where U-Boot transfers control + to Linux passing the CONFIG_SYS_BOOTMAPSZ (not bootm_size) + value to the booting kernel. + + Signed-off-by: Yuri Tikhonov + Signed-off-by: Ilya Yanok + Signed-off-by: Stefan Roese + +commit ddf45cc758d394591fb9bcdcbe96530f733f2bce +Author: Dave Mitchell +Date: Thu Nov 20 14:09:50 2008 -0600 + + ppc4xx: Changed 460EX/GT OCM TLB and internal SRAM initialization + + Expanded OCM TLB to allow access to 64K OCM as well as 256K of + internal SRAM. + + Adjusted internal SRAM initialization to match updated user + manual recommendation. + + OCM & ISRAM are now mapped as follows: + physical virtual size + ISRAM 0x4_0000_0000 0xE300_0000 256k + OCM 0x4_0004_0000 0xE304_0000 64k + + A single TLB was used for this mapping. + + Signed-off-by: Dave Mitchell + Signed-off-by: Stefan Roese + +commit b14ca4b61a681f75f3125676e09d7ce6af66e927 +Author: Dave Mitchell +Date: Thu Nov 20 14:00:49 2008 -0600 + + ppc4xx: Added ppc4xx-isram.h for internal SRAM and L2 cache DCRs + + Added include/asm-ppc/ppc4xx-isram.h and moved internal SRAM and + L2 cache DCRs from ppc440.h to this new header. + + Also converted these DCR defines from lowercase to uppercase and + modified referencing modules to use them. + + Signed-off-by: Dave Mitchell + Signed-off-by: Stefan Roese + +commit 711e2b2af820d21d9931d4cf8057d3894600fd54 +Author: Steven A. Falco +Date: Thu Nov 20 14:37:57 2008 -0500 + + ppc4xx: Delete unused definitions for SDR0_DDRCFG from ppc4xx.h + + The definitions of bits in SDR_CFG are incorrect, and not used within + U-Boot. Therefore, they can be removed. + + The naming of the sdr_ddrdl/sdr_cfg registers do not follow conventions, + and are unused, so they can be removed too. + + A definition for SDR0_DDRCFG is added. + + Signed-off-by: Steven A. Falco + Signed-off-by: Stefan Roese + +commit e23c7c95a96eb0f068efe5c532215a10a1512a95 +Author: Dirk Behme +Date: Mon Nov 10 20:15:25 2008 +0100 + + ARM: OMAP: Convert IO macros + + Convert IO macros to readx/writex. + + Signed-off-by: Dirk Behme + +commit 263b749e2e25473a48776d317bd2a7e2ddcdd212 +Author: Ilko Iliev +Date: Sun Nov 9 15:53:14 2008 +0100 + + lib_arm: do_bootm_linux() - correct a small mistake + + This patch corrects a small bug in the "if" condition: + the parameter "flag" is 0 and the "if" condition is always true. + The result is - the boom command doesn't start the kernel. + Affected targets: all arm based. + + Signed-off-by: Ilko Iliev + +commit 3e0cda071a67cb5709e3fa4faf6b31a731859acc +Author: Stelian Pop +Date: Sun Nov 9 00:14:46 2008 +0100 + + AT91: Enable PLLB for USB + + At least some (old ?) versions of the AT91Bootstrap do not set up the + PLLB correctly to 48 MHz in order to make USB host function correctly. + + This patch sets up the PLLB to the same values Linux uses, and makes USB + work ok on the following CPUs: + - AT91CAP9 + - AT91SAM9260 + - AT91SAM9263 + + This patch also defines CONFIG_USB_STORAGE and CONFIG_CMD_FAT for all + the relevant AT91CAP9/AT91SAM9 atmel boards. + + Signed-off-by: Stelian Pop + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit ad229a44e162af0f65e57e4e3dc133d5f0364ecb +Author: Stelian Pop +Date: Fri Nov 7 13:55:14 2008 +0100 + + AT91: Use AT91_CPU_CLOCK in displays + + Introduce AT91_CPU_CLOCK and use it for displaying the CPU + speed in the LCD driver. + + Also make AT91_MAIN_CLOCK and AT91_MASTER_CLOCK reflect the + corresponding board clocks. + + Signed-off-by: Stelian Pop + +commit 25fb4eaaeab3f8866020818f4729d990dcc91cf0 +Author: Stefan Roese +Date: Thu Nov 20 11:46:20 2008 +0100 + + ppc4xx: Clear all potentially pending exceptions in MCSR + + This is needed on Canyonlands which still has an exception pending + while running relocate_code(). This leads to a failure after trap_init() + is moved to the top of board_init_r(). + + Signed-off-by: Stefan Roese + +commit facdad5f2602e899a01746916beddbf9e856b5ee +Author: Heiko Schocher +Date: Wed Nov 19 10:10:30 2008 +0100 + + powerpc: 83xx: add missing TIMING_CFG1_CASLAT_* defines + + Signed-off-by: Heiko Schocher + Signed-off-by: Kim Phillips + +commit 2f2a5c3714d17f4ead18b713128b7226e0e822f4 +Author: Howard Gregory +Date: Tue Nov 4 14:55:33 2008 +0800 + + mpc83xx: Improve the performance of DDR memory + + modify the CAS timings. my understanding is that these + settings decrease various wait times in the DDR interface. + Because these wait times are in clock cycles, and the DDR + clock on the 8315 RDB runs slower than on some other 83xx + platforms, we can dial down these values without a problem, + thereby decreasing the latency of memory a little. + + Signed-off-by: Howard Gregory + Signed-off-by: Dave Liu + Signed-off-by: Kim Phillips + +commit 8000b086b33a5a81f3f390f37e178db7956dc08b +Author: Kyungmin Park +Date: Fri Oct 24 14:55:33 2008 +0200 + + ARM: Add Apollon UBI support + + To enable UBI on Apollon you need to uncomment the CONFIG_SYS_USE_UBI + macro. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 694a0b3f1c0accd0de94b89555155d69f8022824 +Author: Kyungmin Park +Date: Wed Nov 19 11:47:05 2008 +0100 + + UBI: Add UBI command support + + This patch adds these UBI commands: + + ubi part [nand|onenand] [part] - Show or set current partition + ubi info [l[ayout]] -Display volume and UBI layout information + ubi create[vol] volume [size] [type] - Create volume name with size + ubi write[vol] address volume size - Write volume from address with size + ubi read[vol] address volume [size] - Read volume to address with size + ubi remove[vol] volume - Remove volume + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 58be3a1056d88c6d05f3e914389282807e69923a +Author: Kyungmin Park +Date: Wed Nov 19 16:38:24 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 8/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 47ae6693f54f80455ae32c2e0d995e0e4bdc15b9 +Author: Kyungmin Park +Date: Wed Nov 19 16:36:36 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 7/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 7e6ee7ad27de5216db1baef76f38c3429c8f4a2a +Author: Kyungmin Park +Date: Wed Nov 19 16:32:36 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 6/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit c91a719daa331b5856109313371e4ece5ec06d96 +Author: Kyungmin Park +Date: Wed Nov 19 16:28:06 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 5/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit f412fefa079c6aa9a9763f6869bf787ea6bf6e1b +Author: Kyungmin Park +Date: Wed Nov 19 16:27:23 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 4/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 2d262c4853cb5b6ddce1a28a9641f2de3688d7ea +Author: Kyungmin Park +Date: Wed Nov 19 16:26:54 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 3/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 961df83361aff9a14f226214224eb8a06e05ba24 +Author: Kyungmin Park +Date: Wed Nov 19 16:25:44 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 2/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit f399d4a281713d5ef2d764f05d545fe61e3bd569 +Author: Kyungmin Park +Date: Wed Nov 19 16:23:06 2008 +0100 + + UBI: Add basic UBI support to U-Boot (Part 1/8) + + This patch adds basic UBI (Unsorted Block Image) support to U-Boot. + It's based on the Linux UBI version and basically has a "OS" + translation wrapper that defines most Linux specific calls + (spin_lock() etc.) into no-ops. Some source code parts have been + uncommented by "#ifdef UBI_LINUX". This makes it easier to compare + this version with the Linux version and simplifies future UBI + ports/bug-fixes from the Linux version. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit e29c22f5abe6e0f4baa6251efed6074cdfc3db79 +Author: Kyungmin Park +Date: Wed Nov 19 16:20:36 2008 +0100 + + MTD: Add MTD paritioning infrastructure + + This MTD part infrastructure will be used by the upcoming + UBI support. + + Signed-off-by: Kyungmin Park + Signed-off-by: Stefan Roese + +commit 9b827cf1720acda2473afa516956eab6f7cca9a1 +Author: Selvamuthukumar +Date: Thu Oct 16 22:54:03 2008 +0530 + + Align end of bss by 4 bytes + + Most of the bss initialization loop increments 4 bytes + at a time. And the loop end is checked for an 'equal' + condition. Make the bss end address aligned by 4, so + that the loop will end as expected. + + Signed-off-by: Selvamuthukumar + Signed-off-by: Wolfgang Denk + +commit 3f510db522d160179dff3ddcce9b18f6241c2c24 +Author: Becky Bruce +Date: Mon Nov 10 19:45:35 2008 -0600 + + mpc8641: fix address-cells default in old .dts detection + + address-cells defaults to 2, not 1; so in the unlikely + event that it isn't specified, this patch is required + for correct operation. + + Signed-off-by: Becky Bruce + +commit d025aa4b20a0618a2bada0132a9a0a4afb717f1a +Author: Becky Bruce +Date: Fri Oct 31 17:14:39 2008 -0500 + + lib_ppc: Move trap_init to occur earlier + + Doing trap_init immediately once we're running from RAM + means we're no longer dependent on the physical location of + the flash on non-BookE platforms. Before trap_init, those + platforms switch to real mode and go to 0xfff00100 on exception. + After the switch, they go to 0x00000100 This makes it easier to + move the flash location. + + Signed-off-by: Becky Bruce + +commit d52082b12c6e545705a19433a2f4142526536189 +Author: Becky Bruce +Date: Fri Nov 7 13:46:19 2008 -0600 + + mpc8641: Try to detect old .dts files + + Since we've changed the memory map of the board, be nice and + add some checking to try to catch out-of-date .dts files. We do + this by checking the CCSRBAR location in the .dts and comparing + it to the CCSRBAR location in u-boot. If they don't match, a + warning msg is printed. This isn't foolproof, but it's simple and + will catch most of the cases where an out-of-date .dts is present, + including all of the cases where a new u-boot is used with an old + standard MPC8641 .dts file as supplied with Linux. + + Signed-off-by: Becky Bruce + +commit 8db0400a27839f91c047dcb83f4a0f09e054a180 +Author: Becky Bruce +Date: Thu Nov 6 13:04:09 2008 -0600 + + toplevel Makefile: Add MPC8641HPCN_36BIT target + + This will enable CONFIG_PHYS_36BIT for MPC8641HPCN. + + Signed-off-by: Becky Bruce + +commit 3111d32c494e8251b90917447796a7206b757e1e +Author: Becky Bruce +Date: Thu Nov 6 17:37:35 2008 -0600 + + mpc8641: Support 36-bit physical addressing + + This patch creates a memory map with all the devices + in 36-bit physical space, in addition to the 32-bit map. + The CCSR relocation is moved (again, sorry) to + allow for the physical address to be 36 bits - this + requires translation to be enabled. With 36-bit physical + addressing enabled, we are no longer running with VA=PA + translations. This means we have to distinguish between + the two in the config file. The existing region name is + used to indicate the virtual address, and a _PHYS variety + is created to represent the physical address. + + Large physical addressing is not enabled by default. + Set CONFIG_PHYS_64BIT in the config file to turn this on. + + Signed-off-by: Becky Bruce + +commit c759a01a0022de9378a3a761f49786f87684c916 +Author: Becky Bruce +Date: Thu Nov 6 17:36:04 2008 -0600 + + mpc8641: Change 32-bit memory map + + The memory map on the 8641hpcn is modified to look more like + the 85xx boards; this is a step towards a more standardized + layout going forward. As part of this change, we now relocate + the flash. + + The regions for some of the mappings were far larger than they + needed to be. I have reduced the mappings to match the + actual sizes supported by the hardware. + + In addition I have removed the comments at the head + of the BAT blocks in the config file, rather than updating + them. These get horribly out of date, and it's a simple + matter to look at the defines to see what they are set to + since everything is right here in the same file. + + Documentation has been changed to reflect the new map, as this + change is user visible, and affects the OS which runs post-uboot. + + Signed-off-by: Becky Bruce + +commit bf9a8c34309ed9276258295db9e9212aabb2531a +Author: Becky Bruce +Date: Wed Nov 5 14:55:35 2008 -0600 + + mpc86xx: Change early FLASH mapping to 1M at CONFIG_MONITOR_BASE_EARLY + + We define CONFIG_MONITOR_BASE_EARLY to define the initial location + of the bootpage in flash. Use this to create an early mapping + definition for the FLASH, and change the early_bats code to use this. + + This change facilitates the relocation of the flash since the early + mappings are no longer tied to the final location of the flash. + + Signed-off-by: Becky Bruce + +commit c1e1cf69547b138173f87a7f81c42a5d8dbfde3d +Author: Becky Bruce +Date: Wed Nov 5 14:55:34 2008 -0600 + + mpc86xx: Use SRR0/1/rfi to enable address translation, not blr + + Using a mtmsr/blr means that you have to be executing at the + same virtual address once you enable translation. This is + unnecessarily restrictive, and is not really how this is + usually done. Change it to use the more common mtspr SRR0/SRR1 + and rfi method. + + Signed-off-by: Becky Bruce + +commit 6bf98b1362f0cb237620355ed3e6762fff82388d +Author: Becky Bruce +Date: Wed Nov 5 14:55:33 2008 -0600 + + mpc8641: make DIAG_ADDR == FLASH_BASE + + Currently, that's what it is, but it's hardcoded. + + Signed-off-by: Becky Bruce + +commit 170deacb1ddc39164bdb68f3963e0c0456a5369b +Author: Becky Bruce +Date: Wed Nov 5 14:55:32 2008 -0600 + + mpc8641: Drop imaginary second flash bank, map 8MB + + There's a lot of setup and foo for the second flash + bank. The problem is, this board doesn't actually have one. + Clean this up. Also, the flash is 8M in size. Get rid + of the confusing aliased overmapping, and just map 8M. + + Signed-off-by: Becky Bruce + +commit 0f2d66027bfc60dc7eea2f096af8891988c5abe4 +Author: Becky Bruce +Date: Wed Nov 5 14:55:31 2008 -0600 + + mpc8641: only define CONFIG_ENV_SIZE once + + It's currently defined twice inside in an if/else block, but + both halves set the same value. Move the define outside + the if. + + Signed-off-by: Becky Bruce + +commit 24bfb48c35fed6ad1f047e3e4a27df302482cd93 +Author: Becky Bruce +Date: Wed Nov 5 14:55:30 2008 -0600 + + mpc86xx: Move setup_bats into cpu_init_f + + In order to later allow for a physical relocation of the + flash, setup_bats, which sets up the final BAT mapping + for the board, needs to happen *after* init_laws(). + Otherwise, there will be no window programmed for the flash + at the new physical location at the point when we change + the mmu translation. + + Signed-off-by: Becky Bruce + +commit 05df3e5a638be8c5b0899eae1766bbe8e4b92c17 +Author: Becky Bruce +Date: Wed Nov 5 14:55:29 2008 -0600 + + mpc8641: Remove extra "0" from BR2 define + + Signed-off-by: Becky Bruce + +commit edf3fe7d39a1ee07353128af5221422ce9ccfad6 +Author: Richard Retanubun +Date: Thu Oct 23 09:08:18 2008 -0400 + + drivers/qe/uec_phy.c: Added PHY-less (fixed PHY) driver. + + Copied over the fixed PHY driver as used in pp4xx/4xx_enet.c. + This adds support for PHY-less MAC connections to the UEC. + + Signed-off-by: Richard Retanubun + Signed-off-by: Ben Warren + +commit 54bdcc9fb6670afde9c26dcf364f582879bf21d6 +Author: TsiChung Liew +Date: Thu Oct 23 16:27:24 2008 +0000 + + ColdFire: Add mii driver in drivers/net + + All CF platforms' mii.c are consolidated into one + + Signed-off-by: TsiChung Liew + Signed-off-by: Ben Warren + +commit 25a859066b3af1070eb69f12022113c0a91bd813 +Author: Ben Warren +Date: Mon Oct 27 23:53:17 2008 -0700 + + Moved initialization of PPC4xx EMAC to cpu_eth_init() + + Removed initialization of the driver from net/eth.c + + Signed-off-by: Ben Warren + Acked-by: Stefan Roese + +commit 4d03a4e20e58552cb96d61a0e8b56cdb6cc60126 +Author: Ben Warren +Date: Sun Nov 9 21:29:23 2008 -0800 + + Moved PPC4xx EMAC driver to drivers/net + + Also changed path in all linker scripts that reference this driver + + Signed-off-by: Ben Warren + Acked-by: Stefan Roese + +commit 96e21f86e8266ed40759e5495ee461265d7f6d28 +Author: Ben Warren +Date: Mon Oct 27 23:50:15 2008 -0700 + + Changed PPC4xx EMAC driver to require CONFIG_PPC4xx_EMAC + + All in-tree IBM/AMCC PPC4xx boards using the EMAC get this new CONFIG + + Signed-off-by: Ben Warren + Acked-by: Stefan Roese + +commit 9eb79bd8856bcab896ed5e1f1bca159807a124dd +Author: Ben Warren +Date: Thu Oct 23 22:02:49 2008 -0700 + + Moved initialization of MPC8XX SCC to cpu_eth_init() + + Removed initialization of the driver from net/eth.c + + Signed-off-by: Ben Warren + +commit a9bec96d6359ac9f90a852962bf3040cad9e0256 +Author: Ben Warren +Date: Wed Oct 22 23:47:51 2008 -0700 + + Moved initialization of MPC8220 FEC to cpu_eth_init() + + Removed initialization of the driver from net/eth.c + + Signed-off-by: Ben Warren + +commit 0e8454e990385a58f708c2fc26d31ac041c7a6c5 +Author: Ben Warren +Date: Wed Oct 22 23:32:48 2008 -0700 + + Moved initialization of QE Ethernet controller to cpu_eth_init() + + Removed initialization of the driver from net/eth.c + + Signed-off-by: Ben Warren + +commit 3456a148276d5494b53ee40242efb6462d163504 +Author: Ben Warren +Date: Wed Oct 22 23:20:29 2008 -0700 + + Moved initialization of FCC Ethernet controller to cpu_eth_init + + Affected boards: + Several MPC8xx boards + Several MPC8260/MPC8272 boards + Several MPC85xx boards + + Removed initialization of the driver from net/eth.c + + Signed-off-by: Ben Warren + +commit 62e15b497f5c6334c059512678c8db7940ae4c61 +Author: Ben Warren +Date: Thu Oct 30 22:15:35 2008 -0700 + + Fix typo in cpu/mpc85xx/cpu.c + + CONFIG_MPC85xx_FEC -> CONFIG_MPC85XX_FEC + + Signed-off-by: Ben Warren + +commit 5dfb3ee3f54e2382a08d72906f0e79ecf944f6e3 +Author: Shinya Kuribayashi +Date: Sun Oct 19 12:08:50 2008 +0900 + + net: Move initialization of Au1x00 SoC ethernet MAC to cpu_eth_init + + This patch will move au1x00_eth_initialize from net/eth.c to cpu_eth_init + as a part of ongoing eth_initialize cleanup work. The function ret value + is also fixed as it should be negative on fail. + + Signed-off-by: Shinya Kuribayashi + Signed-off-by: Ben Warren + +commit cc94074ecac1885d18ddb683eb934b3c0268aa5b +Author: Ben Warren +Date: Fri Sep 5 01:55:22 2008 -0400 + + Moved initialization of IXP4XX_NPE Ethernet controller to cpu_eth_init() + + Also, removed the driver initialization from net/eth.c + + Signed-off-by: Ben Warren + +commit f2a7806fc23e82d30c8548911369e0c530607354 +Author: Clive Stubbings +Date: Mon Oct 27 15:05:00 2008 +0000 + + xilinx_emaclite buffer overrun + + Patch to fix buffer allocation size and alignment. Buffer needs to be u32 aligned and + PKTSIZE_ALIGN bytes long. + + Acked-by: Michal Simek + + Signed-off-by: Ben Warren + +commit 0115b1953718a2969f6469d3d5da51ba11e12d42 +Author: richardretanubun +Date: Fri Sep 26 08:59:12 2008 -0400 + + NET: QE: UEC: Make uec_miiphy_read() and uec_miiphy_write() use the devname arg. + + The current uec_miiphy_read and uec_miiphy_write hardcode access devlist[0] + This patch makes these function use the devname argument that is passed in to + allow access to the phy registers of other devices in devlist[]. + + Signed-of-by: Richard Retanubun + + Signed-off-by: Ben Warren + +commit 44dcb7332033db8de2810f2fffcae3084f15c8d4 +Author: richardretanubun +Date: Mon Oct 6 15:31:43 2008 -0400 + + Adds two more ethernet interface to 83xx + + Fixed compiler warning "declared but unused" eth5_uec_info and eth6_uec_info. + Signed-off-by: Richard Retanubun + Signed-off-by: Ben Warren + +commit d8003fa03733901b73d6c4667b4d80fc8eb1ddd3 +Author: Stelian Pop +Date: Fri Nov 7 13:54:31 2008 +0100 + + AT91: Replace AT91_BASE_EMAC by the board specific values. + + AT91_BASE_EMAC is never used outside the board specific files, + so replace its usage by the board specific AT91xxx_BASE_EMAC. + + Signed-off-by: Stelian Pop + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit c91e17affa175ce06afa89b04752301eb4a61666 +Author: Stelian Pop +Date: Fri Nov 7 12:09:21 2008 +0100 + + AT91: Replace (undefined) AT91_ID_US* by the board specific values. + + AT91_ID_US0 / AT91_ID_US1 / AT91_ID_US2 were used but never defined. + Since they are never used outside the board specific files, they can + be replaced by the board specific AT91xxx_ID_US0 / AT91xxx_ID_US1 / + AT91xxx_ID_US2. + + Bug spotted by Jesus Alvarez . + + Signed-off-by: Stelian Pop + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 28962f5a2de81bc0eed1c0b08c6bfaa1cc134ea2 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Nov 1 10:47:59 2008 +0100 + + Makefile/at91sam9: move some at91sam9 to the correct subsection for arm926ejs + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 1079432e04ccf71aa3684181186182cd63512f19 +Author: Sergey Lapin +Date: Fri Oct 31 12:28:43 2008 +0100 + + Custom AFEB9260 board support + + This patch provides support for AFEB9260 board, a product of + OpenSource hardware and software. Some commertial projects + are made with this design. A board is basically AT91SAM9260-EK + with some modifications and different peripherals and different + parts used. Main purpose of this project is to gain experience in + hardware design. + More info: http://groups.google.com/group/arm9fpga-evolution-board + (In Russian only, sorry). + Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb + + Signed-off-by: Sergey Lapin + +commit 26eecd24f97130e56e9c2c2af0e714e05bce6e00 +Author: Tomohiro Masubuchi +Date: Tue Oct 21 13:17:16 2008 +0900 + + Change to use "do_div" macro + + Signed-off-by: Tomohiro Masubuchi + +commit e352495318d8056a00faa21b633b3e4374bfbf52 +Author: Roman Mashak +Date: Wed Oct 22 16:00:26 2008 -0400 + + ARM926EJ-S: relocate OMAP specific 'cpuinfo.c' into OMAP directory + + OMAP identification is implemented in 'cpuinfo.c' and located in ARM926EJ-S directory. + It makes sense to place this file in OMAP specific subdirectory, i.e. cpu/arm926ejs/omap + + Signed-off-by: Roman Mashak + +commit 248b2c367210c06dbd5fbdecf27e97fbe9d05fdb +Author: Roman Mashak +Date: Tue Oct 21 03:01:41 2008 -0700 + + ARM/Versatile port: Removed unused functions + + Removal of never used functions. + + Signed-off-by: Roman Mashak + +commit 1266df887781c779deaf6d05eea2ef90a470cb34 +Author: Becky Bruce +Date: Mon Nov 3 15:44:01 2008 -0600 + + powerpc: change 86xx SMP boot method + + We put the bootpg for the secondary cpus into memory and use + BPTR to get to it. This is a step towards converting to the + ePAPR boot methodology. Also, the code is written to + deal properly with more than 4GB of RAM. + + Signed-off-by: Becky Bruce + +commit b5431560682d8f318fbc49db87cfe13ab41d2ee4 +Author: Becky Bruce +Date: Fri Oct 31 17:13:49 2008 -0500 + + 8641HPCN: Config file cleanup + + There are several items in the config file that were hardcoded + but that should really be based on other config options, since + the regions are contiguous and depend on being so. This cleans + that up a bit. Also, add BR_PHYS_ADDR() macro to convert + addresses into the proper format for BR registers. + + Signed-off-by: Becky Bruce + +commit 4c77de3f144ca088c3867bd6240718c10f5a9d69 +Author: Becky Bruce +Date: Fri Oct 31 17:13:32 2008 -0500 + + 86xx: Make dram_size a phys_size_t + + It's currently a long and should be phys_size_t. + + Signed-off-by: Becky Bruce + +commit 104992fc541302a6bac74448e01e7fdad20abca0 +Author: Becky Bruce +Date: Sun Nov 2 18:19:32 2008 -0600 + + powerpc 86xx: Handle CCSR relocation earlier + + Currently, the CCSR gets relocated while translation is + enabled, meaning we need 2 BAT translations to get to both the + old location and the new location. Also, the DEFAULT + CCSR location has a dependency on the BAT that maps the + FLASH region. Moving the relocation removes this unnecessary + dependency. This makes it easier and more intutive to + modify the board's memory map. + + Swap BATs 3 and 4 on 8610 so that all 86xx boards use the same + BAT for CCSR space. + + Signed-off-by: Becky Bruce + +commit af5d100e8d5cd49d69d52d20f1181eb06ddb4ddf +Author: Becky Bruce +Date: Fri Oct 31 17:14:14 2008 -0500 + + mpc8641: Make PCI and RIO mutually exclusive, fix non-PCI build + + You can't actually have both, and with some coming changes to + change the memory map for the board and support 36-bit physical, + we need the extra BAT that is being consumed by having both. + + I also make non-PCI configs build cleanly, for the sake of sanity. + + Signed-off-by: Becky Bruce + +commit 98693b85d42ff438375dc6d6dcadc70eb7b050bb +Author: Becky Bruce +Date: Fri Oct 31 17:14:00 2008 -0500 + + mpc8641: Stop supporting non-PCI_PNP configs + + We don't actually ever do this, remove the code so we + can stop maintaining it. + + Signed-off-by: Becky Bruce + +commit e4f69d1bd21a12049744989d2dd6b5199c9b8f23 +Author: TsiChung Liew +Date: Fri Oct 24 12:59:12 2008 +0000 + + ColdFire: Fix M5329EVB and M5373EVB nand issue + + Fix compilation issue caused by a few mismatches. + Provide proper nand chip select enable/disable in + nand_hwcontrol() rather than in board_nand_init() + just enable once. Remove redundant local nand driver + functions - nand_read_byte(), nand_write_byte() and + nand_dev_ready() to use common nand driver. + + Signed-off-by: TsiChung Liew + +commit 1b2708442224a551a0b865b52710306333888932 +Author: TsiChung Liew +Date: Wed Oct 22 11:55:30 2008 +0000 + + ColdFire: Fix compilation error + + The error was caused by the change for strmhz() in cpu.c. + A few of them were one extra close parenthesis. + + Signed-off-by: TsiChung Liew + +commit 536e7dac16769954915a484e682a2efb28699133 +Author: TsiChung Liew +Date: Wed Oct 22 11:38:21 2008 +0000 + + ColdFire: Add MCF5301x CPU and M53017EVB support + + Signed-off-by: TsiChung Liew + +commit a21d0c2cc9add8894d971ab791f4032f077db817 +Author: TsiChung Liew +Date: Tue Oct 21 15:37:02 2008 +0000 + + ColdFire: Add SBF support for M52277EVB + + Add serial boot support + + Signed-off-by: TsiChung Liew + +commit b202816c61042c183fe67d097a5893b0f2dafba0 +Author: TsiChung Liew +Date: Tue Oct 21 14:19:26 2008 +0000 + + ColdFire: Use CFI driver for M5272C3 + + Signed-off-by: TsiChung Liew + +commit f3962d3f574e5a1cffacd4e9bc48713060a2a314 +Author: TsiChung Liew +Date: Tue Oct 21 13:47:54 2008 +0000 + + ColdFire: Relocate FEC's GPIO and mii functions protocols + + Place FEC pin assignments in cpu_init.c from platform's + mii.c + + Signed-off-by: TsiChung Liew + +commit 6e80f5aa09f8d41bac50b38dc7488ecd22107802 +Author: TsiChung Liew +Date: Tue Oct 21 12:15:44 2008 +0000 + + ColdFire: Remove platforms mii.c file + + Will use mcfmii.c driver in drivers/net rather than + keep creating new mii.c for each future platform. + Remove EB+MCF-EV123, cobra5272, idmr, M5235EVB, + M5271EVB, M5272C3, M5275EVB, M5282EVB, M5329EVB, + M5373EVB, M54451EVB, M54455EVB, M547xEVB, and M548xEVB's + mii.c + + Signed-off-by: TsiChung Liew + +commit 012522fef3b382469125beb46a315ab4dee02fb0 +Author: TsiChung Liew +Date: Tue Oct 21 10:03:07 2008 +0000 + + ColdFire: Modules header files cleanup + + Consolidate ATA, ePORT, QSPI, FlexCan, PWM, RNG, + MDHA, SKHA, INTC, and FlexBus structures and + definitions in immap_5xxx.h to more unify modules + header files. Append DSPI support for m547x_8x. + SSI cleanup. Remove USB Host structure from immap_539.h. + Apply changes to use FlexBus structures in mcf52x2's + cpu_init.c and platform configuration files. + + Signed-off-by: TsiChung Liew + +commit ac2331aee99ad36be0fcfed8c49922e3c61b576d +Author: TsiChung Liew +Date: Tue Oct 21 08:52:36 2008 +0000 + + ColdFire: Remove linker file + + Each different build for M54455EVB and M5235EVB will + create a u-boot.lds linker file. It is redundant to + keep the u-boot.lds + + Signed-off-by: TsiChung Liew + +commit 0829323073c505556ed5f5073f91adb504584d45 +Author: Peter Tyser +Date: Fri Oct 31 11:26:44 2008 -0500 + + ppc: Fix compile warnings when !CONFIG_OF_LIBFDT + + Signed-off-by: Peter Tyser + +commit a80b21d5127583171d6e9bc7f722947641898012 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Fri Oct 31 12:12:12 2008 +0100 + + common/Makefile: create others group for non core, environment and command files + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 60c68d9c1c6d18ce02c862a05718fd94f97c13d0 +Author: Wolfgang Denk +Date: Fri Oct 31 01:13:37 2008 +0100 + + TQM8260: use CFI flash driver instead of custom driver. + + Signed-off-by: Wolfgang Denk + +commit 20d04774f4ef3f6e38974636e0e36ae0f0b5501f +Author: Andy Fleming +Date: Thu Oct 30 17:35:30 2008 -0500 + + Consolidate MAX/MIN definitions + + There were several, now there is one (two if you count the lower-case + versions). + + Signed-off-by: Andy Fleming + +commit 298e476c66fd88d0bc4f0371118652d2b5de4e8a +Author: Heiko Schocher +Date: Thu Oct 30 09:23:09 2008 +0100 + + mgsuvd: remove unused defines in config file. + + Signed-off-by: Heiko Schocher + +commit 3cbd823116ea8b7c654e275a8c2fca87cd1f5dc5 +Author: Wolfgang Denk +Date: Sun Nov 2 16:14:22 2008 +0100 + + Coding Style cleanup, update CHANGELOG + + Signed-off-by: Wolfgang Denk + commit a47f957ab523019992fdef857af01bd71c58a4da Author: Alessandro Rubini Date: Fri Oct 31 22:33:21 2008 +0100 diff --git a/board/afeb9260/partition.c b/board/afeb9260/partition.c index 0b5dc5e..be08f29 100644 --- a/board/afeb9260/partition.c +++ b/board/afeb9260/partition.c @@ -34,4 +34,3 @@ dataflash_protect_t area_list[NB_DATAFLASH_AREA] = { {0x00004200, 0x000083FF, FLAG_PROTECT_CLEAR, 0, "Environment"}, {0x00008400, 0x00041FFF, FLAG_PROTECT_CLEAR, 0, "U-Boot"}, }; - diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index 4c35892..5c31f7b 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -601,7 +601,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD(ubi, 6, 1, do_ubi, "ubi - ubi commands\n", - "part [nand|nor|onenand] [part]" + "part [nand|nor|onenand] [part]" " - Show or set current partition\n" "ubi info [l[ayout]]" " - Display volume and ubi layout information\n" diff --git a/cpu/mcf52x2/cpu_init.c b/cpu/mcf52x2/cpu_init.c index 18308c8..66f9164 100644 --- a/cpu/mcf52x2/cpu_init.c +++ b/cpu/mcf52x2/cpu_init.c @@ -131,7 +131,7 @@ void cpu_init_f(void) mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */ mbar2_writeByte(MCFSIM_SPURVEC, 0x00); - /*mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); *//* Enable a 1 cycle pre-drive cycle on CS1 */ + /*mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); */ /* Enable a 1 cycle pre-drive cycle on CS1 */ /* FlexBus Chipselect */ init_fbcs(); diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S index 6645cb8..63cc8db 100644 --- a/cpu/mpc86xx/start.S +++ b/cpu/mpc86xx/start.S @@ -982,5 +982,3 @@ unlock_ram_in_cache: blr #endif #endif - - diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 1f0b56c..d09c4c2 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -706,4 +706,3 @@ int cpu_eth_init(bd_t *bis) #endif return 0; } - diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 4b5349e..f2b8908 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -727,7 +727,7 @@ _start: ori r2,r2,0xffff mfdcr r1,ISRAM1_DPC and r1,r1,r2 /* Disable parity check */ - mtdcr ISRAM1_DPC,r1 + mtdcr ISRAM1_DPC,r1 mfdcr r1,ISRAM1_PMEG and r1,r1,r2 /* Disable pwr mgmt */ mtdcr ISRAM1_PMEG,r1 diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index f12dedf..a27de5a 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -434,4 +434,3 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) send_stop(); return(failures); } - diff --git a/drivers/mtd/ubi/crc32.c b/drivers/mtd/ubi/crc32.c index 5273ca3..a7e26b0 100644 --- a/drivers/mtd/ubi/crc32.c +++ b/drivers/mtd/ubi/crc32.c @@ -97,7 +97,7 @@ u32 crc32_le(u32 crc, unsigned char const *p, size_t len) # else # define DO_CRC(x) crc = tab[ ((crc >> 24) ^ (x)) & 255] ^ (crc<<8) # endif - //printf("Crc32_le crc=%x\n",crc); + /* printf("Crc32_le crc=%x\n",crc); */ crc = __cpu_to_le32(crc); /* Align it */ if((((long)b)&3 && len)){ diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 2d44f23..8423894 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -186,7 +186,7 @@ retry: if (read != len && err == -EBADMSG) { ubi_assert(0); printk("%s[%d] not here\n", __func__, __LINE__); -// err = -EIO; +/* err = -EIO; */ } } else { ubi_assert(len == read); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index a87a2f3..061da64 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -260,7 +260,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) goto out_unlock; } - /* Calculate how many eraseblocks are requested */ + /* Calculate how many eraseblocks are requested */ vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; bytes = req->bytes; if (do_div(bytes, vol->usable_leb_size)) diff --git a/include/configs/PMC440.h b/include/configs/PMC440.h index d0e3cda..f9f1002 100644 --- a/include/configs/PMC440.h +++ b/include/configs/PMC440.h @@ -490,7 +490,7 @@ #endif /* Memory Bank 1 (RESET) initialization */ -#define CONFIG_SYS_EBC_PB1AP 0x7f817200 //0x03017200 +#define CONFIG_SYS_EBC_PB1AP 0x7f817200 /* 0x03017200 */ #define CONFIG_SYS_EBC_PB1CR (CONFIG_SYS_RESET_BASE | 0x1c000) /* Memory Bank 4 (FPGA / 32Bit) initialization */ diff --git a/include/configs/afeb9260.h b/include/configs/afeb9260.h index 90e553d..d63a1a0 100644 --- a/include/configs/afeb9260.h +++ b/include/configs/afeb9260.h @@ -167,4 +167,3 @@ #endif #endif - diff --git a/include/linux/crc32.h b/include/linux/crc32.h index e133157..ac4aed1 100644 --- a/include/linux/crc32.h +++ b/include/linux/crc32.h @@ -6,10 +6,10 @@ #define _LINUX_CRC32_H #include -//#include +/* #include */ extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); -//extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); +/* extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); */ #define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length) @@ -21,7 +21,7 @@ extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); * is in bit nr 0], thus it must be reversed before use. Except for * nics that bit swap the result internally... */ -//#define ether_crc(length, data) bitrev32(crc32_le(~0, data, length)) -//#define ether_crc_le(length, data) crc32_le(~0, data, length) +/* #define ether_crc(length, data) bitrev32(crc32_le(~0, data, length)) */ +/* #define ether_crc_le(length, data) crc32_le(~0, data, length) */ #endif /* _LINUX_CRC32_H */ diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index b41e5f5..1016675 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -76,9 +76,9 @@ struct device; struct device_node; int __devinit of_mtd_parse_partitions(struct device *dev, - struct mtd_info *mtd, - struct device_node *node, - struct mtd_partition **pparts); + struct mtd_info *mtd, + struct device_node *node, + struct mtd_partition **pparts); #endif #endif diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h index a017891..4b3e06c 100644 --- a/include/linux/mtd/ubi.h +++ b/include/linux/mtd/ubi.h @@ -21,7 +21,7 @@ #ifndef __LINUX_UBI_H__ #define __LINUX_UBI_H__ -//#include +/* #include */ #include #include diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index 095dfc1..b415219 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -56,7 +56,7 @@ do { \ #define ubi_sysfs_close(...) do { } while (0) static inline int is_power_of_2(unsigned long n) { - return (n != 0 && ((n & (n - 1)) == 0)); + return (n != 0 && ((n & (n - 1)) == 0)); } /* FIXME */ -- cgit v1.1 From 4a0f7538c5c0805fd9a791967bbabacc41deadd9 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 14:41:02 +0100 Subject: Makefile: fix dependency problem with parallel builds Parallel builds (using "make -jN") would occasionally fail with error messages like include/autoconf.mk:212: *** missing separator. Stop. Line numbers and affected boards were changing. Obviously some Makefiles included autoconf.mk while it was still being written to. As a fix, we now write to a temporary file first and then rename it, so that it is really ready to use as soon as it appears. Signed-off-by: Wolfgang Denk --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d6cd91a..1fd03a0 100644 --- a/Makefile +++ b/Makefile @@ -463,7 +463,8 @@ $(obj)include/autoconf.mk: $(obj)include/config.h set -e ; \ : Extract the config macros ; \ $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \ - sed -n -f tools/scripts/define2mk.sed > $@ + sed -n -f tools/scripts/define2mk.sed > $@.tmp && \ + mv $@.tmp $@ sinclude $(obj)include/autoconf.mk.dep -- cgit v1.1 From aa1bcca3d2e22af4dea9f02132f9b56a30378ded Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 14:44:06 +0100 Subject: post/Makefile: fix dependency problem with parallel builds Parallel builds (using "make -jN") would occasionally fail with error messages like ppc_4xxFP-objdump: string.o: File format not recognized or post/libpost.a(cpu.o): In function `cpu_post_test': /home/wd/git/u-boot/work/post/lib_ppc/cpu.c:130: undefined reference to `cpu_post_test_string' or similar. We now make sure to run the 'postdeps" step before attempting to build the specific POST libraries. Signed-off-by: Wolfgang Denk --- post/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/post/Makefile b/post/Makefile index 666a896..769e9c6 100644 --- a/post/Makefile +++ b/post/Makefile @@ -45,7 +45,7 @@ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) LIB := $(obj)$(LIB) -all: postdeps $(LIB) +all: $(LIB) postdeps: @for lib in $(SPLIB-y) ; do \ @@ -57,7 +57,7 @@ $(GPLIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) # specific POST libraries -$(SPLIB): $(obj).depend +$(SPLIB): $(obj).depend postdeps $(MAKE) -C $(dir $(subst $(obj),,$@)) # the POST lib archive -- cgit v1.1 From 6cdadcb3f1b6eac4a1c4256acaa1438413f95351 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 16:22:50 +0100 Subject: trab: make trab_fkt standalone code independent of libgcc Use our own local functions in lib_arm/ instead. Signed-off-by: Wolfgang Denk --- board/trab/Makefile | 3 ++- board/trab/trab_fkt.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/board/trab/Makefile b/board/trab/Makefile index 6dfcb87..30e5fbb 100644 --- a/board/trab/Makefile +++ b/board/trab/Makefile @@ -51,7 +51,8 @@ $(obj)trab_fkt.srec: $(OBJS_FKT) $(LIB) $(LD) -g -Ttext $(LOAD_ADDR) -o $(<:.o=) -e trab_fkt $^ $(LIB) \ -L$(obj)../../examples -lstubs \ -L$(obj)../../lib_generic -lgeneric \ - -L$(gcclibdir) -lgcc + $(obj)../../lib_arm/div0.o \ + $(obj)../../lib_arm/_*.o $(OBJCOPY) -O srec $(<:.o=) $@ $(obj)trab_fkt.bin: $(obj)trab_fkt.srec diff --git a/board/trab/trab_fkt.c b/board/trab/trab_fkt.c index 93b9490..53cdb5a 100644 --- a/board/trab/trab_fkt.c +++ b/board/trab/trab_fkt.c @@ -294,6 +294,12 @@ int trab_fkt (int argc, char *argv[]) return 1; } +void hang (void) +{ + puts ("### ERROR ### Please RESET the board ###\n"); + for (;;); +} + int do_info (void) { printf ("Stand-alone application for TRAB board function test\n"); -- cgit v1.1 From b1ffecec37b57a59c139042267faac458e5324e9 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Wed, 3 Dec 2008 23:04:37 -0600 Subject: powerpc: fix io.h build warning with CONFIG_PHYS_64BIT Casting a pointer to a phys_addr_t when it's an unsigned long long on a 32-bit system without first casting to a non-pointer type generates a compiler warning. Fix this. Signed-off-by: Becky Bruce --- include/asm-ppc/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index c00de45..64cb746 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -300,7 +300,7 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) static inline phys_addr_t virt_to_phys(void * vaddr) { - return (phys_addr_t)(vaddr); + return (phys_addr_t)((unsigned long)vaddr); } #endif -- cgit v1.1 From 584eedab66d0828f2d571a24b10526c4e65f547b Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Thu, 11 Dec 2008 05:51:57 +0300 Subject: jffs2: include instead of defining own min_t Include header for min_t definition instead of providing our own one. Removes warnings in case of OneNAND support enabled. Although I thinks it's a bit silly to include just for min_t... Signed-off-by: Ilya Yanok Acked-by: Stefan Roese --- fs/jffs2/jffs2_1pass.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index be7c1a1..11b66ab 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -119,6 +119,7 @@ #include #include #include +#include #include "jffs2_private.h" @@ -1408,11 +1409,6 @@ dump_dirents(struct b_lists *pL) } #endif -#define min_t(type, x, y) ({ \ - type __min1 = (x); \ - type __min2 = (y); \ - __min1 < __min2 ? __min1: __min2; }) - #define DEFAULT_EMPTY_SCAN_SIZE 4096 static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) -- cgit v1.1 From ff49ea8977b56916edd5b1766d9939010e30b181 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 16 Dec 2008 14:24:16 -0600 Subject: NAND: Mark the BBT as scanned prior to calling scan_bbt. Otherwise, recursion can occur if scan_bbt does not find a bad block table, and tries to write one, and the attempt to erase the BBT area causes a bad block check. Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ba05b76..94a65d4 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -460,8 +460,8 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, struct nand_chip *chip = mtd->priv; if (!(chip->options & NAND_BBT_SCANNED)) { - chip->scan_bbt(mtd); chip->options |= NAND_BBT_SCANNED; + chip->scan_bbt(mtd); } if (!chip->bbt) -- cgit v1.1 From 45ca04f2377361593151d2d4da51f8ba4832d233 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 22:32:25 +0100 Subject: board/trab/memory.c: Fix compile problems. Apply changes from commit 44b4dbed to board/trab/memory.c, too. Actually we'd need a major cleanup here - as it turns out, board/trab/memory.c is more or less a verbatim copy of post/drivers/memory.c ... but then, trab is EOL anyway,r so this is not worth the effort. Signed-off-by: Wolfgang Denk --- board/trab/memory.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/board/trab/memory.c b/board/trab/memory.c index 8fb3d2c..895b68e 100644 --- a/board/trab/memory.c +++ b/board/trab/memory.c @@ -184,7 +184,7 @@ * * For other processors, let the compiler generate the best code it can. */ -static void move64(unsigned long long *src, unsigned long long *dest) +static void move64(const unsigned long long *src, unsigned long long *dest) { #if defined(CONFIG_MPC8260) || defined(CONFIG_MPC824X) asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */ @@ -231,12 +231,12 @@ static int memory_post_dataline(unsigned long long * pmem) int ret = 0; for ( i = 0; i < num_patterns; i++) { - move64((unsigned long long *)&(pattern[i]), pmem++); + move64(&(pattern[i]), pmem++); /* * Put a different pattern on the data lines: otherwise they * may float long enough to read back what we wrote. */ - move64((unsigned long long *)&otherpattern, pmem--); + move64(&otherpattern, pmem--); move64(pmem, &temp64); #ifdef INJECT_DATA_ERRORS -- cgit v1.1 From 9e2a79b4c585ad31138fb90b68fd0234d64a8da8 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 23:13:46 +0100 Subject: include/configs/at91cap9adk.h: fix typo. Signed-off-by: Wolfgang Denk --- include/configs/at91cap9adk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/at91cap9adk.h b/include/configs/at91cap9adk.h index 363df67..b2baf1b 100644 --- a/include/configs/at91cap9adk.h +++ b/include/configs/at91cap9adk.h @@ -32,7 +32,7 @@ #define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */ #define AT91_MASTER_CLOCK 100000000 /* peripheral */ #define AT91_CPU_CLOCK 200000000 /* cpu */ -#define CONFUG_SYS_AT91_PLLB 0x10073e01 /* PLLB settings for USB */ +#define CONFIG_SYS_AT91_PLLB 0x10073e01 /* PLLB settings for USB */ #define CONFIG_SYS_HZ 1000000 /* 1us resolution */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ -- cgit v1.1 From aced78d852d0b009e8aaa1445af8cb40861ee549 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 16 Dec 2008 23:48:27 +0100 Subject: Prepare 2009.01-rc1 Signed-off-by: Wolfgang Denk --- CHANGELOG | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 6 ++-- 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0c9c047..9af36c1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,105 @@ +commit 9e2a79b4c585ad31138fb90b68fd0234d64a8da8 +Author: Wolfgang Denk +Date: Tue Dec 16 23:13:46 2008 +0100 + + include/configs/at91cap9adk.h: fix typo. + + Signed-off-by: Wolfgang Denk + +commit 45ca04f2377361593151d2d4da51f8ba4832d233 +Author: Wolfgang Denk +Date: Tue Dec 16 22:32:25 2008 +0100 + + board/trab/memory.c: Fix compile problems. + + Apply changes from commit 44b4dbed to board/trab/memory.c, too. + + Actually we'd need a major cleanup here - as it turns out, + board/trab/memory.c is more or less a verbatim copy of + post/drivers/memory.c ... but then, trab is EOL anyway,r + so this is not worth the effort. + + Signed-off-by: Wolfgang Denk + +commit 584eedab66d0828f2d571a24b10526c4e65f547b +Author: Ilya Yanok +Date: Thu Dec 11 05:51:57 2008 +0300 + + jffs2: include instead of defining own min_t + + Include header for min_t definition instead of + providing our own one. Removes warnings in case of OneNAND support + enabled. + + Although I thinks it's a bit silly to include + just for min_t... + + Signed-off-by: Ilya Yanok + Acked-by: Stefan Roese + +commit b1ffecec37b57a59c139042267faac458e5324e9 +Author: Becky Bruce +Date: Wed Dec 3 23:04:37 2008 -0600 + + powerpc: fix io.h build warning with CONFIG_PHYS_64BIT + + Casting a pointer to a phys_addr_t when it's an unsigned long long + on a 32-bit system without first casting to a non-pointer type + generates a compiler warning. Fix this. + + Signed-off-by: Becky Bruce + +commit 6cdadcb3f1b6eac4a1c4256acaa1438413f95351 +Author: Wolfgang Denk +Date: Tue Dec 16 16:22:50 2008 +0100 + + trab: make trab_fkt standalone code independent of libgcc + + Use our own local functions in lib_arm/ instead. + + Signed-off-by: Wolfgang Denk + +commit aa1bcca3d2e22af4dea9f02132f9b56a30378ded +Author: Wolfgang Denk +Date: Tue Dec 16 14:44:06 2008 +0100 + + post/Makefile: fix dependency problem with parallel builds + + Parallel builds (using "make -jN") would occasionally fail with error + messages like + ppc_4xxFP-objdump: string.o: File format not recognized + or + post/libpost.a(cpu.o): In function `cpu_post_test': + /home/wd/git/u-boot/work/post/lib_ppc/cpu.c:130: undefined reference to `cpu_post_test_string' + or similar. We now make sure to run the 'postdeps" step before + attempting to build the specific POST libraries. + + Signed-off-by: Wolfgang Denk + +commit 4a0f7538c5c0805fd9a791967bbabacc41deadd9 +Author: Wolfgang Denk +Date: Tue Dec 16 14:41:02 2008 +0100 + + Makefile: fix dependency problem with parallel builds + + Parallel builds (using "make -jN") would occasionally fail with error + messages like + include/autoconf.mk:212: *** missing separator. Stop. + Line numbers and affected boards were changing. Obviously some + Makefiles included autoconf.mk while it was still being written to. + As a fix, we now write to a temporary file first and then rename it, + so that it is really ready to use as soon as it appears. + + Signed-off-by: Wolfgang Denk + +commit 455ae7e87f67c44e6aea68865c83acadd3fcd36c +Author: Wolfgang Denk +Date: Tue Dec 16 01:02:17 2008 +0100 + + Coding style cleanup, update CHANGELOG. + + Signed-off-by: Wolfgang Denk + commit 84bc72d90c505fec3ef4b693995407a0bd4064e5 Author: Mike Frysinger Date: Thu Dec 11 18:39:08 2008 -0500 diff --git a/Makefile b/Makefile index 1fd03a0..4df4812 100644 --- a/Makefile +++ b/Makefile @@ -21,10 +21,10 @@ # MA 02111-1307 USA # -VERSION = 2008 -PATCHLEVEL = 10 +VERSION = 2009 +PATCHLEVEL = 01 SUBLEVEL = -EXTRAVERSION = +EXTRAVERSION = -rc1 ifneq "$(SUBLEVEL)" "" U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) else -- cgit v1.1 From 13095b2f07dacb1f863772266c1789d47a523a8a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 16 Dec 2008 22:10:30 +0100 Subject: MIPS: qemu_mips: move env storage just after u-boot Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Shinya Kuribayashi --- include/configs/qemu-mips.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h index f028d1a..8444462 100644 --- a/include/configs/qemu-mips.h +++ b/include/configs/qemu-mips.h @@ -150,7 +150,7 @@ #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 #define CONFIG_ENV_IS_IN_FLASH 1 -#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x40000) +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN) /* Address and size of Primary Environment Sector */ #define CONFIG_ENV_SIZE 0x8000 -- cgit v1.1 From 16cdf816779f5b602a9b3b4d2ea4dea05095c35b Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 16 Dec 2008 22:10:31 +0100 Subject: MIPS: qemu_mips: update doc to use all disk and boot linux kernel Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Shinya Kuribayashi --- doc/README.qemu_mips | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/doc/README.qemu_mips b/doc/README.qemu_mips index 2fdd2b0..8fa4907 100644 --- a/doc/README.qemu_mips +++ b/doc/README.qemu_mips @@ -17,12 +17,47 @@ create image: start it: # qemu-system-mips -M mips -pflash flash -monitor null -nographic +Ide Disk + +# dd of=ide bs=1k cout=100k if=/dev/zero + +# sfdisk -C 261 -d ide +# partition table of ide +unit: sectors + + ide1 : start= 63, size= 32067, Id=83 + ide2 : start= 32130, size= 32130, Id=83 + ide3 : start= 64260, size= 4128705, Id=83 + ide4 : start= 0, size= 0, Id= 0 + +# Generate uImage +# tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage +# Copy to Flash +# dd if=uImage bs=1k conv=notrunc seek=224 of=flash +# Copy to ide +# dd if=uImage bs=512 conv=notrunc seek=63 of=ide + +# Generate ext2 on part 2 +# Attached as loop device ide offset = 32130 * 512 +# losetup -o 16450560 -f ide +# Format as ext2 ( arg2 : nb blocks) +# mke2fs /dev/loop0 16065 +# losetup -d /dev/loop0 +# Mount and copy uImage and initrd.gz to it +# mount -o loop,offset=16450560 -t ext2 ide /mnt +# Umount it +# umount /mnt + +Now you can boot from flash, ide, ide+ext2 and tfp + +# qemu-system-mips -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide + II) How to debug U-Boot In order to debug U-Boot you need to start qemu with gdb server support (-s) and waiting the connection to start the CPU (-S) -# qemu-system-mips -S -s -M mips -pflash flash -monitor null -nographic +# qemu-system-mips -S -s -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide in an other console you start gdb -- cgit v1.1 From b616f2b545f73757669b37386f0b37bb61fc6797 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 8 Sep 2008 22:27:18 +0200 Subject: MIPS: qemu_mips: update doc to generate and to use qemu flash, ide file Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Shinya Kuribayashi --- doc/README.qemu_mips | 67 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/doc/README.qemu_mips b/doc/README.qemu_mips index 8fa4907..3985264 100644 --- a/doc/README.qemu_mips +++ b/doc/README.qemu_mips @@ -17,7 +17,28 @@ create image: start it: # qemu-system-mips -M mips -pflash flash -monitor null -nographic -Ide Disk +2) Download kernel + initrd + +On ftp://ftp.denx.de/pub/contrib/Jean-Christophe_Plagniol-Villard/qemu_mips/ +you can downland + +#config to build the kernel +qemu_mips_defconfig +#patch to fix mips interupt init on 2.6.24.y kernel +qemu_mips_kernel.patch +initrd.gz +vmlinux +vmlinux.bin +System.map + +4) Generate uImage + +# tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage + +5) Copy uImage to Flash +# dd if=uImage bs=1k conv=notrunc seek=224 of=flash + +6) Generate Ide Disk # dd of=ide bs=1k cout=100k if=/dev/zero @@ -30,14 +51,12 @@ unit: sectors ide3 : start= 64260, size= 4128705, Id=83 ide4 : start= 0, size= 0, Id= 0 -# Generate uImage -# tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage -# Copy to Flash -# dd if=uImage bs=1k conv=notrunc seek=224 of=flash -# Copy to ide +7) Copy to ide + # dd if=uImage bs=512 conv=notrunc seek=63 of=ide -# Generate ext2 on part 2 +8) Generate ext2 on part 2 on Copy uImage and initrd.gz + # Attached as loop device ide offset = 32130 * 512 # losetup -o 16450560 -f ide # Format as ext2 ( arg2 : nb blocks) @@ -45,10 +64,40 @@ unit: sectors # losetup -d /dev/loop0 # Mount and copy uImage and initrd.gz to it # mount -o loop,offset=16450560 -t ext2 ide /mnt +# mkdir /mnt/boot +# cp {initrd.gz,uImage} /mnt/boot/ # Umount it # umount /mnt -Now you can boot from flash, ide, ide+ext2 and tfp +9) Set Environment + +setenv rd_start 0x80800000 +setenv rd_size 2663940 +setenv kernel BFC38000 +setenv oad_addr 80500000 +setenv load_addr2 80F00000 +setenv kernel_flash BFC38000 +setenv load_addr_hello 80200000 +setenv bootargs 'root=/dev/ram0 init=/bin/sh' +setenv load_rd_ext2 'ide res; ext2load ide 0:2 ${rd_start} /boot/initrd.gz' +setenv load_rd_tftp 'tftp ${rd_start} /initrd.gz' +setenv load_kernel_hda 'ide res; diskboot ${load_addr} 0:2' +setenv load_kernel_ext2 'ide res; ext2load ide 0:2 ${load_addr} /boot/uImage' +setenv load_kernel_tftp 'tftp ${load_addr} /qemu_mips/uImage' +setenv boot_ext2_ext2 'run load_rd_ext2; run load_kernel_ext2; run addmisc; bootm ${load_addr}' +setenv boot_ext2_flash 'run load_rd_ext2; run addmisc; bootm ${kernel_flash}' +setenv boot_ext2_hda 'run load_rd_ext2; run load_kernel_hda; run addmisc; bootm ${load_addr}' +setenv boot_ext2_tftp 'run load_rd_ext2; run load_kernel_tftp; run addmisc; bootm ${load_addr}' +setenv boot_tftp_hda 'run load_rd_tftp; run load_kernel_hda; run addmisc; bootm ${load_addr}' +setenv boot_tftp_ext2 'run load_rd_tftp; run load_kernel_ext2; run addmisc; bootm ${load_addr}' +setenv boot_tftp_flash 'run load_rd_tftp; run addmisc; bootm ${kernel_flash}' +setenv boot_tftp_tftp 'run load_rd_tftp; run load_kernel_tftp; run addmisc; bootm ${load_addr}' +setenv load_hello_tftp 'tftp ${load_addr_hello} /examples/hello_world.bin' +setenv go_tftp 'run load_hello_tftp; go ${load_addr_hello}' +setenv addmisc 'setenv bootargs ${bootargs} console=ttyS0,${baudrate} rd_start=${rd_start} rd_size=${rd_size} ethaddr=${ethaddr}' +setenv bootcmd 'run boot_tftp_flash' + +10) Now you can boot from flash, ide, ide+ext2 and tfp # qemu-system-mips -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide @@ -64,7 +113,7 @@ in an other console you start gdb 1) Debugging of U-Boot Before Relocation Before relocation, the addresses in the ELF file can be used without any problems -buy connecting to the gdb server localhost:1234 +by connecting to the gdb server localhost:1234 # mipsel-unknown-linux-gnu-gdb u-boot GNU gdb 6.6 -- cgit v1.1 From 7a8979591171676417ab36852d8811a8c46accd8 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Wed, 29 Oct 2008 12:39:26 -0500 Subject: pci/fsl_pci_init: Enable inbound PCI config cycles Add fsl_pci_config_unlock() function to enable a PCI/PCIe interface configured in agent/endpoint mode to respond to inbound PCI configuration cycles. Signed-off-by: Peter Tyser --- drivers/pci/fsl_pci_init.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 1db42fd..db68f26 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -37,6 +37,11 @@ DECLARE_GLOBAL_DATA_PTR; #include #include +/* Freescale-specific PCI config registers */ +#define FSL_PCI_PBFR 0x44 +#define FSL_PCIE_CAP_ID 0x4c +#define FSL_PCIE_CFG_RDY 0x4b0 + void pciauto_prescan_setup_bridge(struct pci_controller *hose, pci_dev_t dev, int sub_bus); void pciauto_postscan_setup_bridge(struct pci_controller *hose, @@ -306,6 +311,30 @@ void fsl_pci_init(struct pci_controller *hose) } } +/* Enable inbound PCI config cycles for agent/endpoint interface */ +void fsl_pci_config_unlock(struct pci_controller *hose) +{ + pci_dev_t dev = PCI_BDF(hose->first_busno,0,0); + u8 agent; + u8 pcie_cap; + u16 pbfr; + + pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &agent); + if (!agent) + return; + + pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap); + if (pcie_cap != 0x0) { + /* PCIe - set CFG_READY bit of Configuration Ready Register */ + pci_hose_write_config_byte(hose, dev, FSL_PCIE_CFG_RDY, 0x1); + } else { + /* PCI - clear ACL bit of PBFR */ + pci_hose_read_config_word(hose, dev, FSL_PCI_PBFR, &pbfr); + pbfr &= ~0x20; + pci_hose_write_config_word(hose, dev, FSL_PCI_PBFR, pbfr); + } +} + #ifdef CONFIG_OF_BOARD_SETUP #include #include -- cgit v1.1 From e92739d34e2d6b6aca93b2598248210710897ce8 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Wed, 17 Dec 2008 16:36:21 -0600 Subject: Add support for PCA953x I2C gpio devices Initial support for NXP's 4 and 8 bit I2C gpio expanders (eg pca9537, pca9557, etc). The CONFIG_PCA953X define enables support for the devices while the CONFIG_CMD_PCA953X define enables the pca953x command. The CONFIG_CMD_PCA953X_INFO define enables an 'info' sub-command which provides summary information for the given pca953x device. Signed-off-by: Peter Tyser --- Makefile | 2 + README | 9 ++ drivers/gpio/Makefile | 47 ++++++++++ drivers/gpio/pca953x.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++++ include/pca953x.h | 39 +++++++++ 5 files changed, 324 insertions(+) create mode 100644 drivers/gpio/Makefile create mode 100644 drivers/gpio/pca953x.c create mode 100644 include/pca953x.h diff --git a/Makefile b/Makefile index 4df4812..0fc6490 100644 --- a/Makefile +++ b/Makefile @@ -228,6 +228,7 @@ LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/block/libblock.a LIBS += drivers/dma/libdma.a LIBS += drivers/fpga/libfpga.a +LIBS += drivers/gpio/libgpio.a LIBS += drivers/hwmon/libhwmon.a LIBS += drivers/i2c/libi2c.a LIBS += drivers/input/libinput.a @@ -407,6 +408,7 @@ TAG_SUBDIRS += disk TAG_SUBDIRS += common TAG_SUBDIRS += drivers/bios_emulator TAG_SUBDIRS += drivers/block +TAG_SUBDIRS += drivers/gpio TAG_SUBDIRS += drivers/hwmon TAG_SUBDIRS += drivers/i2c TAG_SUBDIRS += drivers/input diff --git a/README b/README index 2a553c2..eb86eba 100644 --- a/README +++ b/README @@ -621,6 +621,8 @@ The following options need to be configured: CONFIG_CMD_MII * MII utility commands CONFIG_CMD_NAND * NAND support CONFIG_CMD_NET bootp, tftpboot, rarpboot + CONFIG_CMD_PCA953X * PCA953x I2C gpio commands + CONFIG_CMD_PCA953X_INFO * PCA953x I2C gpio info command CONFIG_CMD_PCI * pciinfo CONFIG_CMD_PCMCIA * PCMCIA support CONFIG_CMD_PING * send ICMP ECHO_REQUEST to network @@ -698,6 +700,13 @@ The following options need to be configured: Note that if the RTC uses I2C, then the I2C interface must also be configured. See I2C Support, below. +- GPIO Support: + CONFIG_PCA953X - use NXP's PCA953X series I2C GPIO + CONFIG_PCA953X_INFO - enable pca953x info command + + Note that if the GPIO device uses I2C, then the I2C interface + must also be configured. See I2C Support, below. + - Timestamp Support: When CONFIG_TIMESTAMP is selected, the timestamp diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile new file mode 100644 index 0000000..dd618ed --- /dev/null +++ b/drivers/gpio/Makefile @@ -0,0 +1,47 @@ +# +# Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libgpio.a + +COBJS-$(CONFIG_PCA953X) += pca953x.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################## diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c new file mode 100644 index 0000000..390d99a --- /dev/null +++ b/drivers/gpio/pca953x.c @@ -0,0 +1,227 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Driver for NXP's 4 and 8 bit I2C gpio expanders (eg pca9537, pca9557, etc) + * TODO: support additional devices with more than 8-bits GPIO + */ + +#include +#include +#include + +/* Default to an address that hopefully won't corrupt other i2c devices */ +#ifndef CONFIG_SYS_I2C_PCA953X_ADDR +#define CONFIG_SYS_I2C_PCA953X_ADDR (~0) +#endif + +enum { + PCA953X_CMD_INFO, + PCA953X_CMD_DEVICE, + PCA953X_CMD_OUTPUT, + PCA953X_CMD_INPUT, + PCA953X_CMD_INVERT, +}; + +/* + * Modify masked bits in register + */ +static int pca953x_reg_write(uint8_t chip, uint addr, uint mask, uint data) +{ + uint8_t val; + + if (i2c_read(chip, addr, 1, &val, 1)) + return -1; + + val &= ~mask; + val |= data; + + return i2c_write(chip, addr, 1, &val, 1); +} + +/* + * Set output value of IO pins in 'mask' to corresponding value in 'data' + * 0 = low, 1 = high + */ +int pca953x_set_val(uint8_t chip, uint mask, uint data) +{ + return pca953x_reg_write(chip, PCA953X_OUT, mask, data); +} + +/* + * Set read polarity of IO pins in 'mask' to corresponding value in 'data' + * 0 = read pin value, 1 = read inverted pin value + */ +int pca953x_set_pol(uint8_t chip, uint mask, uint data) +{ + return pca953x_reg_write(chip, PCA953X_POL, mask, data); +} + +/* + * Set direction of IO pins in 'mask' to corresponding value in 'data' + * 0 = output, 1 = input + */ +int pca953x_set_dir(uint8_t chip, uint mask, uint data) +{ + return pca953x_reg_write(chip, PCA953X_CONF, mask, data); +} + +/* + * Read current logic level of all IO pins + */ +int pca953x_get_val(uint8_t chip) +{ + uint8_t val; + + if (i2c_read(chip, 0, 1, &val, 1)) + return -1; + + return (int)val; +} + +#ifdef CONFIG_CMD_PCA953X +#ifdef CONFIG_CMD_PCA953X_INFO +/* + * Display pca953x information + */ +static int pca953x_info(uint8_t chip) +{ + int i; + uint8_t data; + + printf("pca953x@ 0x%x:\n\n", chip); + printf("gpio pins: 76543210\n"); + printf("-------------------\n"); + + if (i2c_read(chip, PCA953X_CONF, 1, &data, 1)) + return -1; + printf("conf: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? 'i' : 'o'); + printf("\n"); + + if (i2c_read(chip, PCA953X_POL, 1, &data, 1)) + return -1; + printf("invert: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? '1' : '0'); + printf("\n"); + + if (i2c_read(chip, PCA953X_IN, 1, &data, 1)) + return -1; + printf("input: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? '1' : '0'); + printf("\n"); + + if (i2c_read(chip, PCA953X_OUT, 1, &data, 1)) + return -1; + printf("output: "); + for (i = 7; i >= 0; i--) + printf("%c", data & (1 << i) ? '1' : '0'); + printf("\n"); + + return 0; +} +#endif /* CONFIG_CMD_PCA953X_INFO */ + +cmd_tbl_t cmd_pca953x[] = { + U_BOOT_CMD_MKENT(device, 3, 0, (void *)PCA953X_CMD_DEVICE, "", ""), + U_BOOT_CMD_MKENT(output, 4, 0, (void *)PCA953X_CMD_OUTPUT, "", ""), + U_BOOT_CMD_MKENT(input, 3, 0, (void *)PCA953X_CMD_INPUT, "", ""), + U_BOOT_CMD_MKENT(invert, 4, 0, (void *)PCA953X_CMD_INVERT, "", ""), +#ifdef CONFIG_CMD_PCA953X_INFO + U_BOOT_CMD_MKENT(info, 2, 0, (void *)PCA953X_CMD_INFO, "", ""), +#endif +}; + +int do_pca953x(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + static uint8_t chip = CONFIG_SYS_I2C_PCA953X_ADDR; + int val; + ulong ul_arg2 = 0; + ulong ul_arg3 = 0; + cmd_tbl_t *c; + + c = find_cmd_tbl(argv[1], cmd_pca953x, ARRAY_SIZE(cmd_pca953x)); + + /* All commands but "device" require 'maxargs' arguments */ + if (!c || !((argc == (c->maxargs)) || + (((int)c->cmd == PCA953X_CMD_DEVICE) && + (argc == (c->maxargs - 1))))) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + /* arg2 used as chip number or pin number */ + if (argc > 2) + ul_arg2 = simple_strtoul(argv[2], NULL, 16); + + /* arg3 used as pin or invert value */ + if (argc > 3) + ul_arg3 = simple_strtoul(argv[3], NULL, 16) & 0x1; + + switch ((int)c->cmd) { +#ifdef CONFIG_CMD_PCA953X_INFO + case PCA953X_CMD_INFO: + return pca953x_info(chip); +#endif + case PCA953X_CMD_DEVICE: + if (argc == 3) + chip = (uint8_t)ul_arg2; + printf("Current device address: 0x%x\n", chip); + return 0; + case PCA953X_CMD_INPUT: + pca953x_set_dir(chip, (1 << ul_arg2), + PCA953X_DIR_IN << ul_arg2); + val = (pca953x_get_val(chip) & (1 << ul_arg2)) != 0; + + printf("chip 0x%02x, pin 0x%lx = %d\n", chip, ul_arg2, val); + return val; + case PCA953X_CMD_OUTPUT: + pca953x_set_dir(chip, (1 << ul_arg2), + (PCA953X_DIR_OUT << ul_arg2)); + return pca953x_set_val(chip, (1 << ul_arg2), + (ul_arg3 << ul_arg2)); + case PCA953X_CMD_INVERT: + return pca953x_set_pol(chip, (1 << ul_arg2), + (ul_arg3 << ul_arg2)); + default: + /* We should never get here */ + return 1; + } +} + +U_BOOT_CMD( + pca953x, 5, 1, do_pca953x, + "pca953x - pca953x gpio access\n", + "device [dev]\n" + " - show or set current device address\n" +#ifdef CONFIG_CMD_PCA953X_INFO + "pca953x info\n" + " - display info for current chip\n" +#endif + "pca953x output pin 0|1\n" + " - set pin as output and drive low or high\n" + "pca953x invert pin 0|1\n" + " - disable/enable polarity inversion for reads\n" + "pca953x intput pin\n" + " - set pin as input and read value\n" +); + +#endif /* CONFIG_CMD_PCA953X */ diff --git a/include/pca953x.h b/include/pca953x.h new file mode 100644 index 0000000..6c2b58c --- /dev/null +++ b/include/pca953x.h @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __PCA953X_H_ +#define __PCA953X_H_ + +#define PCA953X_IN 0x00 +#define PCA953X_OUT 0x01 +#define PCA953X_POL 0x02 +#define PCA953X_CONF 0x03 + +#define PCA953X_OUT_LOW 0 +#define PCA953X_OUT_HIGH 1 +#define PCA953X_POL_NORMAL 0 +#define PCA953X_POL_INVERT 1 +#define PCA953X_DIR_OUT 0 +#define PCA953X_DIR_IN 1 + +int pca953x_set_val(u8 chip, uint mask, uint data); +int pca953x_set_pol(u8 chip, uint mask, uint data); +int pca953x_set_dir(u8 chip, uint mask, uint data); +int pca953x_get_val(u8 chip); + +#endif /* __PCA953X_H_ */ -- cgit v1.1 From ccf0fdd02b97323f8caae18d06cc9daeac2f192f Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Wed, 17 Dec 2008 16:36:23 -0600 Subject: XPedite5370 board support Initial support for Extreme Engineering Solutions XPedite5370 - a MPC8572-based 3U VPX single board computer with a PMC/XMC site. Signed-off-by: Peter Tyser --- MAINTAINERS | 3 + MAKEALL | 1 + Makefile | 3 + board/xes/common/Makefile | 56 ++++ board/xes/common/fsl_8572_clk.c | 51 ++++ board/xes/common/fsl_85xx_ddr.c | 93 ++++++ board/xes/common/fsl_85xx_pci.c | 265 ++++++++++++++++ board/xes/xpedite5370/Makefile | 45 +++ board/xes/xpedite5370/config.mk | 35 +++ board/xes/xpedite5370/ddr.c | 270 +++++++++++++++++ board/xes/xpedite5370/law.c | 54 ++++ board/xes/xpedite5370/tlb.c | 94 ++++++ board/xes/xpedite5370/u-boot.lds | 145 +++++++++ board/xes/xpedite5370/xpedite5370.c | 128 ++++++++ include/configs/XPEDITE5370.h | 589 ++++++++++++++++++++++++++++++++++++ 15 files changed, 1832 insertions(+) create mode 100644 board/xes/common/Makefile create mode 100644 board/xes/common/fsl_8572_clk.c create mode 100644 board/xes/common/fsl_85xx_ddr.c create mode 100644 board/xes/common/fsl_85xx_pci.c create mode 100644 board/xes/xpedite5370/Makefile create mode 100644 board/xes/xpedite5370/config.mk create mode 100644 board/xes/xpedite5370/ddr.c create mode 100644 board/xes/xpedite5370/law.c create mode 100644 board/xes/xpedite5370/tlb.c create mode 100644 board/xes/xpedite5370/u-boot.lds create mode 100644 board/xes/xpedite5370/xpedite5370.c create mode 100644 include/configs/XPEDITE5370.h diff --git a/MAINTAINERS b/MAINTAINERS index f048795..be10eb4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -411,6 +411,9 @@ Rune Torgersen MPC8266ADS MPC8266 +Peter Tyser + + XPEDITE5370 MPC8572 David Updegraff diff --git a/MAKEALL b/MAKEALL index cc49a98..a136bad 100755 --- a/MAKEALL +++ b/MAKEALL @@ -385,6 +385,7 @@ LIST_85xx=" \ TQM8548 \ TQM8555 \ TQM8560 \ + XPEDITE5370 \ " ######################################################################### diff --git a/Makefile b/Makefile index 0fc6490..752a370 100644 --- a/Makefile +++ b/Makefile @@ -2463,6 +2463,9 @@ TQM8560_config: unconfig echo "#define CONFIG_BOARDNAME \"TQM$${CTYPE}\"">>$(obj)include/config.h; @$(MKCONFIG) -a TQM85xx ppc mpc85xx tqm85xx tqc +XPEDITE5370_config: unconfig + @$(MKCONFIG) $(@:_config=) ppc mpc85xx xpedite5370 xes + ######################################################################### ## MPC86xx Systems ######################################################################### diff --git a/board/xes/common/Makefile b/board/xes/common/Makefile new file mode 100644 index 0000000..c5cd633 --- /dev/null +++ b/board/xes/common/Makefile @@ -0,0 +1,56 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)board/$(VENDOR)/common) +endif + +LIB = $(obj)lib$(VENDOR).a + +COBJS-$(CONFIG_MPC8572) += fsl_8572_clk.o +COBJS-$(CONFIG_MPC85xx) += fsl_85xx_ddr.o +COBJS-$(CONFIG_FSL_PCI_INIT) += fsl_85xx_pci.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/xes/common/fsl_8572_clk.c b/board/xes/common/fsl_8572_clk.c new file mode 100644 index 0000000..f5df2da --- /dev/null +++ b/board/xes/common/fsl_8572_clk.c @@ -0,0 +1,51 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +/* + * Return SYSCLK input frequency - 50 MHz or 66 MHz depending on POR config + */ +unsigned long get_board_sys_clk(ulong dummy) +{ + volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 gpporcr = gur->gpporcr; + + if (gpporcr & 0x10000) + return 66666666; + else + return 50000000; +} + +/* + * Return DDR input clock - synchronous with SYSCLK or 66 MHz + */ +unsigned long get_board_ddr_clk(ulong dummy) +{ + volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 ddr_ratio = ((gur->porpllsr) & 0x00003e00) >> 9; + + if (ddr_ratio == 0x7) + return get_board_sys_clk(dummy); + + return 66666666; +} diff --git a/board/xes/common/fsl_85xx_ddr.c b/board/xes/common/fsl_85xx_ddr.c new file mode 100644 index 0000000..30b4767 --- /dev/null +++ b/board/xes/common/fsl_85xx_ddr.c @@ -0,0 +1,93 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) +extern void ddr_enable_ecc(unsigned int dram_size); +#endif + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size = fsl_ddr_sdram(); + + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + + dram_size *= 0x100000; + +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + /* Initialize and enable DDR ECC */ + ddr_enable_ecc(dram_size); +#endif + + return dram_size; +} + +#if defined(CONFIG_DDR_ECC) || (CONFIG_NUM_DDR_CONTROLLERS > 1) +void board_add_ram_info(int use_default) +{ +#if (CONFIG_NUM_DDR_CONTROLLERS > 1) + volatile ccsr_ddr_t *ddr1 = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR); +#endif + + puts(" ("); + +#if (CONFIG_NUM_DDR_CONTROLLERS > 1) + /* Print interleaving information */ + if (ddr1->cs0_config & 0x20000000) { + switch ((ddr1->cs0_config >> 24) & 0xf) { + case 0: + puts("cache line"); + break; + case 1: + puts("page"); + break; + case 2: + puts("bank"); + break; + case 3: + puts("super-bank"); + break; + default: + puts("invalid"); + break; + } + } else { + puts("no"); + } + + puts(" interleaving"); +#endif + +#if (CONFIG_NUM_DDR_CONTROLLERS > 1) && defined(CONFIG_DDR_ECC) + puts(", "); +#endif + +#if defined(CONFIG_DDR_ECC) + puts("ECC enabled"); +#endif + + puts(")"); +} +#endif /* CONFIG_DDR_ECC || CONFIG_NUM_DDR_CONTROLLERS > 1 */ diff --git a/board/xes/common/fsl_85xx_pci.c b/board/xes/common/fsl_85xx_pci.c new file mode 100644 index 0000000..b8e363e --- /dev/null +++ b/board/xes/common/fsl_85xx_pci.c @@ -0,0 +1,265 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2007-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +extern int fsl_pci_setup_inbound_windows(struct pci_region *r); +extern void fsl_pci_init(struct pci_controller *hose); + +int first_free_busno = 0; + +#ifdef CONFIG_PCIE1 +static struct pci_controller pcie1_hose; +#endif +#ifdef CONFIG_PCIE2 +static struct pci_controller pcie2_hose; +#endif +#ifdef CONFIG_PCIE3 +static struct pci_controller pcie3_hose; +#endif + +/* Correlate host/agent POR bits to usable info. Table 4-14 */ +struct host_agent_cfg_t { + uchar pcie_root[3]; + uchar rio_host; +} host_agent_cfg[8] = { + {{0, 0, 0}, 0}, + {{0, 1, 1}, 1}, + {{1, 0, 1}, 0}, + {{1, 1, 0}, 1}, + {{0, 0, 1}, 0}, + {{0, 1, 0}, 1}, + {{1, 0, 0}, 0}, + {{1, 1, 1}, 1} +}; + +/* Correlate port width POR bits to usable info. Table 4-15 */ +struct io_port_cfg_t { + uchar pcie_width[3]; + uchar rio_width; +} io_port_cfg[16] = { + {{0, 0, 0}, 0}, + {{0, 0, 0}, 0}, + {{4, 0, 0}, 0}, + {{4, 4, 0}, 0}, + {{0, 0, 0}, 0}, + {{0, 0, 0}, 0}, + {{0, 0, 0}, 4}, + {{4, 2, 2}, 0}, + {{0, 0, 0}, 0}, + {{0, 0, 0}, 0}, + {{0, 0, 0}, 0}, + {{4, 0, 0}, 4}, + {{4, 0, 0}, 4}, + {{0, 0, 0}, 4}, + {{0, 0, 0}, 4}, + {{8, 0, 0}, 0}, +}; + +void pci_init_board(void) +{ + struct pci_controller *hose; + volatile ccsr_fsl_pci_t *pci; + int width; + int host; + volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + uint devdisr = gur->devdisr; + uint io_sel = (gur->pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19; + uint host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16; + struct pci_region *r; + + debug(" pci_init_board: devdisr=%x, io_sel=%x, host_agent=%x\n", + devdisr, io_sel, host_agent); + +#ifdef CONFIG_PCIE1 + pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR; + hose = &pcie1_hose; + host = host_agent_cfg[host_agent].pcie_root[0]; + width = io_port_cfg[io_sel].pcie_width[0]; + r = hose->regions; + + if (width && !(devdisr & MPC85xx_DEVDISR_PCIE)) { + printf("\n PCIE1 connected as %s (x%d)", + host ? "Root Complex" : "End Point", width); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug(" with errors. Clearing. Now 0x%08x", + pci->pme_msg_det); + } + printf("\n"); + + /* inbound */ + r += fsl_pci_setup_inbound_windows(r); + + /* outbound memory */ + pci_set_region(r++, + CONFIG_SYS_PCIE1_MEM_BASE, + CONFIG_SYS_PCIE1_MEM_PHYS, + CONFIG_SYS_PCIE1_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(r++, + CONFIG_SYS_PCIE1_IO_BASE, + CONFIG_SYS_PCIE1_IO_PHYS, + CONFIG_SYS_PCIE1_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = r - hose->regions; + + hose->first_busno = first_free_busno; + pci_setup_indirect(hose, (int)&pci->cfg_addr, + (int) &pci->cfg_data); + + fsl_pci_init(hose); + + first_free_busno = hose->last_busno+1; + printf(" PCIE1 on bus %02x - %02x\n", + hose->first_busno, hose->last_busno); + } +#else + gur->devdisr |= MPC85xx_DEVDISR_PCIE; /* disable */ +#endif /* CONFIG_PCIE1 */ + +#ifdef CONFIG_PCIE2 + pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR; + hose = &pcie2_hose; + host = host_agent_cfg[host_agent].pcie_root[1]; + width = io_port_cfg[io_sel].pcie_width[1]; + r = hose->regions; + + if (width && !(devdisr & MPC85xx_DEVDISR_PCIE2)) { + printf("\n PCIE2 connected as %s (x%d)", + host ? "Root Complex" : "End Point", width); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug(" with errors. Clearing. Now 0x%08x", + pci->pme_msg_det); + } + printf("\n"); + + /* inbound */ + r += fsl_pci_setup_inbound_windows(r); + + /* outbound memory */ + pci_set_region(r++, + CONFIG_SYS_PCIE2_MEM_BASE, + CONFIG_SYS_PCIE2_MEM_PHYS, + CONFIG_SYS_PCIE2_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(r++, + CONFIG_SYS_PCIE2_IO_BASE, + CONFIG_SYS_PCIE2_IO_PHYS, + CONFIG_SYS_PCIE2_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = r - hose->regions; + + hose->first_busno = first_free_busno; + pci_setup_indirect(hose, (int)&pci->cfg_addr, + (int)&pci->cfg_data); + + fsl_pci_init(hose); + first_free_busno = hose->last_busno+1; + printf(" PCIE2 on bus %02x - %02x\n", + hose->first_busno, hose->last_busno); + + } +#else + gur->devdisr |= MPC85xx_DEVDISR_PCIE2; /* disable */ +#endif /* CONFIG_PCIE2 */ + +#ifdef CONFIG_PCIE3 + pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR; + hose = &pcie3_hose; + host = host_agent_cfg[host_agent].pcie_root[2]; + width = io_port_cfg[io_sel].pcie_width[2]; + r = hose->regions; + + if (width && !(devdisr & MPC85xx_DEVDISR_PCIE3)) { + printf("\n PCIE3 connected as %s (x%d)", + host ? "Root Complex" : "End Point", width); + if (pci->pme_msg_det) { + pci->pme_msg_det = 0xffffffff; + debug(" with errors. Clearing. Now 0x%08x", + pci->pme_msg_det); + } + printf("\n"); + + /* inbound */ + r += fsl_pci_setup_inbound_windows(r); + + /* outbound memory */ + pci_set_region(r++, + CONFIG_SYS_PCIE3_MEM_BASE, + CONFIG_SYS_PCIE3_MEM_PHYS, + CONFIG_SYS_PCIE3_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(r++, + CONFIG_SYS_PCIE3_IO_BASE, + CONFIG_SYS_PCIE3_IO_PHYS, + CONFIG_SYS_PCIE3_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = r - hose->regions; + + hose->first_busno = first_free_busno; + pci_setup_indirect(hose, (int)&pci->cfg_addr, + (int)&pci->cfg_data); + + fsl_pci_init(hose); + first_free_busno = hose->last_busno+1; + printf(" PCIE3 on bus %02x - %02x\n", + hose->first_busno, hose->last_busno); + } +#else + gur->devdisr |= MPC85xx_DEVDISR_PCIE3; /* disable */ +#endif /* CONFIG_PCIE3 */ +} + +#if defined(CONFIG_OF_BOARD_SETUP) +extern void ft_fsl_pci_setup(void *blob, const char *pci_alias, + struct pci_controller *hose); + +void ft_board_pci_setup(void *blob, bd_t *bd) +{ +#ifdef CONFIG_PCIE1 + ft_fsl_pci_setup(blob, "pci2", &pcie1_hose); +#endif +#ifdef CONFIG_PCIE2 + ft_fsl_pci_setup(blob, "pci1", &pcie2_hose); +#endif +#ifdef CONFIG_PCIE3 + ft_fsl_pci_setup(blob, "pci0", &pcie3_hose); +#endif +} +#endif /* CONFIG_OF_BOARD_SETUP */ diff --git a/board/xes/xpedite5370/Makefile b/board/xes/xpedite5370/Makefile new file mode 100644 index 0000000..919397c --- /dev/null +++ b/board/xes/xpedite5370/Makefile @@ -0,0 +1,45 @@ +# +# Copyright 2008 Extreme Engineering Solutions, Inc. +# Copyright 2007 Freescale Semiconductor, Inc. +# (C) Copyright 2001-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS-y += $(BOARD).o +COBJS-y += ddr.o +COBJS-y += law.o +COBJS-y += tlb.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(OBJS) $(SOBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/xes/xpedite5370/config.mk b/board/xes/xpedite5370/config.mk new file mode 100644 index 0000000..39469b2 --- /dev/null +++ b/board/xes/xpedite5370/config.mk @@ -0,0 +1,35 @@ +# +# Copyright 2008 Extreme Engineering Solutions, Inc. +# Copyright 2007-2008 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# xpedite5370 board +# +ifndef TEXT_BASE +TEXT_BASE = 0xfff80000 +endif + +PLATFORM_RELFLAGS += -mrelocatable + +PLATFORM_CPPFLAGS += -DCONFIG_E500=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC8572=1 diff --git a/board/xes/xpedite5370/ddr.c b/board/xes/xpedite5370/ddr.c new file mode 100644 index 0000000..4d3f255 --- /dev/null +++ b/board/xes/xpedite5370/ddr.c @@ -0,0 +1,270 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#include +#include + +static void get_spd(ddr2_spd_eeprom_t *spd, unsigned char i2c_address) +{ + i2c_read(i2c_address, SPD_EEPROM_OFFSET, 2, (uchar *)spd, + sizeof(ddr2_spd_eeprom_t)); +} + +unsigned int fsl_ddr_get_mem_data_rate(void) +{ + return get_ddr_freq(0); +} + +void fsl_ddr_get_spd(ddr2_spd_eeprom_t *ctrl_dimms_spd, + unsigned int ctrl_num) +{ + unsigned int i; + unsigned int i2c_address = 0; + + for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { + if (ctrl_num == 0) + i2c_address = SPD_EEPROM_ADDRESS1; + if (ctrl_num == 1) + i2c_address = SPD_EEPROM_ADDRESS2; + get_spd(&(ctrl_dimms_spd[i]), i2c_address); + } +} + +/* + * There are four board-specific SDRAM timing parameters which must be + * calculated based on the particular PCB artwork. These are: + * 1.) CPO (Read Capture Delay) + * - TIMING_CFG_2 register + * Source: Calculation based on board trace lengths and + * chip-specific internal delays. + * 2.) WR_DATA_DELAY (Write Command to Data Strobe Delay) + * - TIMING_CFG_2 register + * Source: Calculation based on board trace lengths. + * Unless clock and DQ lanes are very different + * lengths (>2"), this should be set to the nominal value + * of 1/2 clock delay. + * 3.) CLK_ADJUST (Clock and Addr/Cmd alignment control) + * - DDR_SDRAM_CLK_CNTL register + * Source: Signal Integrity Simulations + * 4.) 2T Timing on Addr/Ctl + * - TIMING_CFG_2 register + * Source: Signal Integrity Simulations + * Usually only needed with heavy load/very high speed (>DDR2-800) + * + * ====== XPedite5370 DDR2-600 read delay calculations ====== + * + * See Freescale's App Note AN2583 as refrence. This document also + * contains the chip-specific delays for 8548E, 8572, etc. + * + * For MPC8572E + * Minimum chip delay (Ch 0): 1.372ns + * Maximum chip delay (Ch 0): 2.914ns + * Minimum chip delay (Ch 1): 1.220ns + * Maximum chip delay (Ch 1): 2.595ns + * + * CLK adjust = 5 (from simulations) = 5/8* 3.33ns = 2080ps + * + * Minimum delay calc (Ch 0): + * clock prop - dram skew + min dqs prop delay + clk_adjust + min chip dly + * 2.3" * 180 - 400ps + 1.9" * 180 + 2080ps + 1372ps + * = 3808ps + * = 3.808ns + * + * Maximum delay calc (Ch 0): + * clock prop + dram skew + max dqs prop delay + clk_adjust + max chip dly + * 2.3" * 180 + 400ps + 2.4" * 180 + 2080ps + 2914ps + * = 6240ps + * = 6.240ns + * + * Minimum delay calc (Ch 1): + * clock prop - dram skew + min dqs prop delay + clk_adjust + min chip dly + * 1.46" * 180- 400ps + 0.7" * 180 + 2080ps + 1220ps + * = 3288ps + * = 3.288ns + * + * Maximum delay calc (Ch 1): + * clock prop + dram skew + max dqs prop delay + clk_adjust + min chip dly + * 1.46" * 180+ 400ps + 1.1" * 180 + 2080ps + 2595ps + * = 5536ps + * = 5.536ns + * + * Ch.0: 3.808ns to 6.240ns additional delay needed (pick 5ns as target) + * This is 1.5 clock cycles, pick CPO = READ_LAT + 3/2 (0x8) + * Ch.1: 3.288ns to 5.536ns additional delay needed (pick 4.4ns as target) + * This is 1.32 clock cycles, pick CPO = READ_LAT + 5/4 (0x7) + * + * + * ====== XPedite5370 DDR2-800 read delay calculations ====== + * + * See Freescale's App Note AN2583 as refrence. This document also + * contains the chip-specific delays for 8548E, 8572, etc. + * + * For MPC8572E + * Minimum chip delay (Ch 0): 1.372ns + * Maximum chip delay (Ch 0): 2.914ns + * Minimum chip delay (Ch 1): 1.220ns + * Maximum chip delay (Ch 1): 2.595ns + * + * CLK adjust = 5 (from simulations) = 5/8* 2.5ns = 1563ps + * + * Minimum delay calc (Ch 0): + * clock prop - dram skew + min dqs prop delay + clk_adjust + min chip dly + * 2.3" * 180 - 350ps + 1.9" * 180 + 1563ps + 1372ps + * = 3341ps + * = 3.341ns + * + * Maximum delay calc (Ch 0): + * clock prop + dram skew + max dqs prop delay + clk_adjust + max chip dly + * 2.3" * 180 + 350ps + 2.4" * 180 + 1563ps + 2914ps + * = 5673ps + * = 5.673ns + * + * Minimum delay calc (Ch 1): + * clock prop - dram skew + min dqs prop delay + clk_adjust + min chip dly + * 1.46" * 180- 350ps + 0.7" * 180 + 1563ps + 1220ps + * = 2822ps + * = 2.822ns + * + * Maximum delay calc (Ch 1): + * clock prop + dram skew + max dqs prop delay + clk_adjust + min chip dly + * 1.46" * 180+ 350ps + 1.1" * 180 + 1563ps + 2595ps + * = 4968ps + * = 4.968ns + * + * Ch.0: 3.341ns to 5.673ns additional delay needed (pick 4.5ns as target) + * This is 1.8 clock cycles, pick CPO = READ_LAT + 7/4 (0x9) + * Ch.1: 2.822ns to 4.968ns additional delay needed (pick 3.9ns as target) + * This is 1.56 clock cycles, pick CPO = READ_LAT + 3/2 (0x8) + * + * Write latency (WR_DATA_DELAY) is calculated by doing the following: + * + * The DDR SDRAM specification requires DQS be received no sooner than + * 75% of an SDRAM clock period—and no later than 125% of a clock + * period—from the capturing clock edge of the command/address at the + * SDRAM. + * + * Based on the above tracelengths, the following are calculated: + * Ch. 0 8572 to DRAM propagation (DQ lanes) : 1.9" * 180 = 0.342ns + * Ch. 0 8572 to DRAM propagation (CLKs) : 2.3" * 180 = 0.414ns + * Ch. 1 8572 to DRAM propagation (DQ lanes) : 0.7" * 180 = 0.126ns + * Ch. 1 8572 to DRAM propagation (CLKs ) : 1.47" * 180 = 0.264ns + * + * Difference in arrival time CLK vs. DQS: + * Ch. 0 0.072ns + * Ch. 1 0.138ns + * + * Both of these values are much less than 25% of the clock + * period at DDR2-600 or DDR2-800, so no additional delay is needed over + * the 1/2 cycle which normally aligns the first DQS transition + * exactly WL (CAS latency minus one cycle) after the CAS strobe. + * See Figure 9-53 in MPC8572E manual: "1/2 delay" in Freescale's + * terminology corresponds to exactly one clock period delay after + * the CAS strobe. (due to the fact that the "delay" is referenced + * from the *falling* edge of the CLK, just after the rising edge + * which the CAS strobe is latched on. + */ + +typedef struct board_memctl_options { + uint16_t datarate_mhz_low; + uint16_t datarate_mhz_high; + uint8_t clk_adjust; + uint8_t cpo_override; + uint8_t write_data_delay; +} board_memctl_options_t; + +static struct board_memctl_options bopts_ctrl[][2] = { + { + /* Controller 0 */ + { + /* DDR2 600/667 */ + .datarate_mhz_low = 500, + .datarate_mhz_high = 750, + .clk_adjust = 5, + .cpo_override = 8, + .write_data_delay = 2, + }, + { + /* DDR2 800 */ + .datarate_mhz_low = 750, + .datarate_mhz_high = 850, + .clk_adjust = 5, + .cpo_override = 9, + .write_data_delay = 2, + }, + }, + { + /* Controller 1 */ + { + /* DDR2 600/667 */ + .datarate_mhz_low = 500, + .datarate_mhz_high = 750, + .clk_adjust = 5, + .cpo_override = 7, + .write_data_delay = 2, + }, + { + /* DDR2 800 */ + .datarate_mhz_low = 750, + .datarate_mhz_high = 850, + .clk_adjust = 5, + .cpo_override = 8, + .write_data_delay = 2, + }, + }, +}; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + struct board_memctl_options *bopts = bopts_ctrl[ctrl_num]; + sys_info_t sysinfo; + int i; + unsigned int datarate; + + get_sys_info(&sysinfo); + datarate = sysinfo.freqDDRBus / 1000 / 1000; + + for (i = 0; i < ARRAY_SIZE(bopts_ctrl[ctrl_num]); i++) { + if ((bopts[i].datarate_mhz_low <= datarate) && + (bopts[i].datarate_mhz_high >= datarate)) { + debug("controller %d:\n", ctrl_num); + debug(" clk_adjust = %d\n", bopts[i].clk_adjust); + debug(" cpo = %d\n", bopts[i].cpo_override); + debug(" write_data_delay = %d\n", + bopts[i].write_data_delay); + popts->clk_adjust = bopts[i].clk_adjust; + popts->cpo_override = bopts[i].cpo_override; + popts->write_data_delay = bopts[i].write_data_delay; + } + } + + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 0; +} diff --git a/board/xes/xpedite5370/law.c b/board/xes/xpedite5370/law.c new file mode 100644 index 0000000..daee676 --- /dev/null +++ b/board/xes/xpedite5370/law.c @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * Notes: + * CCSRBAR and L2-as-SRAM don't need a configured Local Access Window. + * If flash is 8M at default position (last 8M), no LAW needed. + */ + +struct law_entry law_table[] = { + SET_LAW(CONFIG_SYS_FLASH_BASE2, LAW_SIZE_256M, LAW_TRGT_IF_LBC), + SET_LAW(CONFIG_SYS_NAND_BASE, LAW_SIZE_1M, LAW_TRGT_IF_LBC), +#ifdef CONFIG_SYS_PCIE1_MEM_PHYS + SET_LAW(CONFIG_SYS_PCIE1_MEM_PHYS, LAW_SIZE_1G, LAW_TRGT_IF_PCIE_1), + SET_LAW(CONFIG_SYS_PCIE1_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCIE_1), +#endif +#ifdef CONFIG_SYS_PCIE2_MEM_PHYS + SET_LAW(CONFIG_SYS_PCIE2_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_2), + SET_LAW(CONFIG_SYS_PCIE2_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCIE_2), +#endif +#ifdef CONFIG_SYS_PCIE3_MEM_PHYS + SET_LAW(CONFIG_SYS_PCIE3_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_3), + SET_LAW(CONFIG_SYS_PCIE3_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCIE_3), +#endif +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/xes/xpedite5370/tlb.c b/board/xes/xpedite5370/tlb.c new file mode 100644 index 0000000..caafa30 --- /dev/null +++ b/board/xes/xpedite5370/tlb.c @@ -0,0 +1,94 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* W**G* - NOR flashes */ + /* This will be changed to *I*G* after relocation to RAM. */ + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE2, CONFIG_SYS_FLASH_BASE2, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, + 0, 0, BOOKE_PAGESZ_256M, 1), + + /* *I*G* - CCSRBAR */ + SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 1, BOOKE_PAGESZ_1M, 1), + + /* *I*G* - NAND flash */ + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 2, BOOKE_PAGESZ_1M, 1), + +#ifdef CONFIG_PCIE1 + /* *I*G* - PCIe */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 3, BOOKE_PAGESZ_1G, 1), +#endif + +#ifdef CONFIG_PCIE2 + /* *I*G* - PCIe */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE2_MEM_PHYS, CONFIG_SYS_PCIE2_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 4, BOOKE_PAGESZ_256M, 1), +#endif + +#ifdef CONFIG_PCIE3 + /* *I*G* - PCIe */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_MEM_PHYS, CONFIG_SYS_PCIE3_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 5, BOOKE_PAGESZ_256M, 1), +#endif + +#if defined(CONFIG_PCIE1) || defined(CONFIG_PCIE2) || defined(CONFIG_PCIE3) + /* *I*G* - PCIe */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_PHYS, CONFIG_SYS_PCIE1_IO_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 6, BOOKE_PAGESZ_64M, 1), +#endif + +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/xes/xpedite5370/u-boot.lds b/board/xes/xpedite5370/u-boot.lds new file mode 100644 index 0000000..cb39912 --- /dev/null +++ b/board/xes/xpedite5370/u-boot.lds @@ -0,0 +1,145 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2007-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +PHDRS +{ + text PT_LOAD; + bss PT_LOAD; +} + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + *(.text) + *(.got1) + } :text + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } :text + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + .bootpg ADDR(.text) + 0x7f000 : + { + cpu/mpc85xx/start.o (.bootpg) + } :text = 0xffff + + .resetvec ADDR(.text) + 0x7fffc : + { + *(.resetvec) + } :text = 0xffff + + . = ADDR(.text) + 0x80000; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } :bss + + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); +} diff --git a/board/xes/xpedite5370/xpedite5370.c b/board/xes/xpedite5370/xpedite5370.c new file mode 100644 index 0000000..4875095 --- /dev/null +++ b/board/xes/xpedite5370/xpedite5370.c @@ -0,0 +1,128 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +extern void ft_board_pci_setup(void *blob, bd_t *bd); + +int checkboard(void) +{ + char *s; + + printf("Board: X-ES %s 3U VPX SBC\n", CONFIG_SYS_BOARD_NAME); + printf(" "); + s = getenv("board_rev"); + if (s) + printf("Rev %s, ", s); + s = getenv("serial#"); + if (s) + printf("Serial# %s, ", s); + s = getenv("board_cfg"); + if (s) + printf("Cfg %s", s); + printf("\n"); + + return 0; +} + +static void flash_cs_fixup(void) +{ + volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + int flash_sel; + + /* + * Print boot dev and swap flash flash chip selects if booted from 2nd + * flash. Swapping chip selects presents user with a common memory + * map regardless of which flash was booted from. + */ + flash_sel = !((pca953x_get_val(CONFIG_SYS_I2C_PCA953X_ADDR0) & + CONFIG_SYS_PCA953X_C0_FLASH_PASS_CS)); + printf("FLASH: Executed from FLASH%d\n", flash_sel ? 2 : 1); + + if (flash_sel) { + lbc->br0 = CONFIG_SYS_BR1_PRELIM; + lbc->or0 = CONFIG_SYS_OR1_PRELIM; + + lbc->br1 = CONFIG_SYS_BR0_PRELIM; + lbc->or1 = CONFIG_SYS_OR0_PRELIM; + } +} + +int board_early_init_r(void) +{ + /* Initialize PCA9557 devices */ + pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR0, 0xff, 0); + pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR1, 0xff, 0); + pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR0, 0xff, 0); + pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR0, 0xff, 0); + + /* + * Remap NOR flash region to caching-inhibited + * so that flash can be erased/programmed properly. + */ + + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache(); + + /* Invalidate existing TLB entry for NOR flash */ + disable_tlb(0); + set_tlb(1, (CONFIG_SYS_FLASH_BASE2 & 0xf0000000), + (CONFIG_SYS_FLASH_BASE2 & 0xf0000000), + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_256M, 1); + + flash_cs_fixup(); + + return 0; +} + +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ +#ifdef CONFIG_PCI + ft_board_pci_setup(blob, bd); +#endif + ft_cpu_setup(blob, bd); +} +#endif + +#ifdef CONFIG_MP +extern void cpu_mp_lmb_reserve(struct lmb *lmb); + +void board_lmb_reserve(struct lmb *lmb) +{ + cpu_mp_lmb_reserve(lmb); +} +#endif diff --git a/include/configs/XPEDITE5370.h b/include/configs/XPEDITE5370.h new file mode 100644 index 0000000..3bc0fe8 --- /dev/null +++ b/include/configs/XPEDITE5370.h @@ -0,0 +1,589 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2007-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * xpedite5370 board configuration file + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_BOOKE 1 /* BOOKE */ +#define CONFIG_E500 1 /* BOOKE e500 family */ +#define CONFIG_MPC85xx 1 /* MPC8540/60/55/41/48 */ +#define CONFIG_MPC8572 1 +#define CONFIG_XPEDITE5370 1 +#define CONFIG_SYS_BOARD_NAME "XPedite5370" +#define CONFIG_NUM_CPUS 2 /* 2 Cores */ +#define CONFIG_BOARD_EARLY_INIT_R /* Call board_pre_init */ +#define CONFIG_RELOC_FIXUP_WORKS /* Fully relocate to SDRAM */ + +#define CONFIG_PCI 1 /* Enable PCI/PCIE */ +#define CONFIG_PCI_PNP 1 /* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW 1 /* show pci devices on startup */ +#define CONFIG_PCIE1 1 /* PCIE controler 1 */ +#define CONFIG_PCIE2 1 /* PCIE controler 2 */ +#define CONFIG_FSL_PCI_INIT 1 /* Use common FSL init code */ +#define CONFIG_SYS_PCI_64BIT 1 /* enable 64-bit PCI resources */ +#define CONFIG_FSL_PCIE_RESET 1 /* need PCIe reset errata */ +#define CONFIG_FSL_LAW 1 /* Use common FSL init code */ + +/* + * DDR config + */ +#define CONFIG_FSL_DDR2 +#undef CONFIG_FSL_DDR_INTERACTIVE +#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ +#define CONFIG_DDR_SPD +#define CONFIG_MEM_INIT_VALUE 0xdeadbeef +#define SPD_EEPROM_ADDRESS1 0x54 /* Both channels use the */ +#define SPD_EEPROM_ADDRESS2 0x54 /* same SPD data */ +#define SPD_EEPROM_OFFSET 0x200 /* OFFSET of SPD in EEPROM */ +#define CONFIG_NUM_DDR_CONTROLLERS 2 +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 1 +#define CONFIG_DDR_ECC +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER +#define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory*/ +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_VERY_BIG_RAM + +#ifndef __ASSEMBLY__ +extern unsigned long get_board_sys_clk(unsigned long dummy); +extern unsigned long get_board_ddr_clk(unsigned long dummy); +#endif + +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk(0) /* sysclk for MPC85xx */ +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk(0) /* ddrclk for MPC85xx */ + +/* + * These can be toggled for performance analysis, otherwise use default. + */ +#define CONFIG_L2_CACHE /* toggle L2 cache */ +#define CONFIG_BTB /* toggle branch predition */ +#define CONFIG_ENABLE_36BIT_PHYS 1 + +/* + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + */ +#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ +#define CONFIG_SYS_CCSRBAR 0xef000000 /* relocated CCSRBAR */ +#define CONFIG_SYS_CCSRBAR_PHYS CONFIG_SYS_CCSRBAR /* physical addr of CCSRBAR */ +#define CONFIG_SYS_IMMR CONFIG_SYS_CCSRBAR /* PQII uses CONFIG_SYS_IMMR */ +#define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_CCSRBAR + 0xa000) +#define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_CCSRBAR + 0x9000) + +/* + * Diagnostics + */ +#define CONFIG_SYS_ALT_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x10000000 +#define CONFIG_SYS_MEMTEST_END 0x20000000 + +/* + * Memory map + * 0x0000_0000 0x7fff_ffff DDR 2G Cacheable + * 0x8000_0000 0xbfff_ffff PCIe1 Mem 1G non-cacheable + * 0xc000_0000 0xcfff_ffff PCIe2 Mem 256M non-cacheable + * 0xe000_0000 0xe7ff_ffff SRAM/SSRAM/L1 Cache 128M non-cacheable + * 0xe800_0000 0xe87f_ffff PCIe1 IO 8M non-cacheable + * 0xe880_0000 0xe8ff_ffff PCIe2 IO 8M non-cacheable + * 0xef00_0000 0xef0f_ffff CCSR/IMMR 1M non-cacheable + * 0xef80_0000 0xef8f_ffff NAND Flash 1M non-cacheable + * 0xf000_0000 0xf7ff_ffff NOR Flash 2 128M non-cacheable + * 0xf800_0000 0xffff_ffff NOR Flash 1 128M non-cacheable + */ + +#define CONFIG_SYS_LBC_LCRR (LCRR_CLKDIV_4 | LCRR_EADC_3) + +/* + * NAND flash configuration + */ +#define CONFIG_SYS_NAND_BASE 0xef800000 +#define CONFIG_SYS_NAND_BASE2 0xef840000 /* Unused at this time */ + +/* + * NOR flash configuration + */ +#define CONFIG_SYS_FLASH_BASE 0xf8000000 +#define CONFIG_SYS_FLASH_BASE2 0xf0000000 +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE2} +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_AUTOPROTECT_LIST { {0xfff40000, 0xc0000}, \ + {0xf7f40000, 0xc0000} } +#define CONFIG_SYS_MONITOR_BASE TEXT_BASE /* start of monitor */ + +/* + * Chip select configuration + */ +/* NOR Flash 0 on CS0 */ +#define CONFIG_SYS_BR0_PRELIM (CONFIG_SYS_FLASH_BASE | \ + BR_PS_16 | \ + BR_V) +#define CONFIG_SYS_OR0_PRELIM (OR_AM_128MB | \ + OR_GPCM_CSNT | \ + OR_GPCM_XACS | \ + OR_GPCM_ACS_DIV2 | \ + OR_GPCM_SCY_8 | \ + OR_GPCM_TRLX | \ + OR_GPCM_EHTR | \ + OR_GPCM_EAD) + +/* NOR Flash 1 on CS1 */ +#define CONFIG_SYS_BR1_PRELIM (CONFIG_SYS_FLASH_BASE2 | \ + BR_PS_16 | \ + BR_V) +#define CONFIG_SYS_OR1_PRELIM CONFIG_SYS_OR0_PRELIM + +/* NAND flash on CS2 */ +#define CONFIG_SYS_BR2_PRELIM (CONFIG_SYS_NAND_BASE | \ + (2< " + +/* + * Pass open firmware flat tree + */ +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_OF_BOARD_SETUP 1 +#define CONFIG_OF_STDOUT_VIA_ALIAS 1 + +#define CONFIG_SYS_64BIT_VSPRINTF 1 +#define CONFIG_SYS_64BIT_STRTOUL 1 + +/* + * I2C + */ +#define CONFIG_FSL_I2C /* Use FSL common I2C driver */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SYS_I2C_OFFSET 0x3000 +#define CONFIG_SYS_I2C2_OFFSET 0x3100 +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE + +/* PEX8518 slave I2C interface */ +#define CONFIG_SYS_I2C_PEX8518_ADDR 0x70 + +/* I2C DS1631 temperature sensor */ +#define CONFIG_SYS_I2C_DS1621_ADDR 0x48 +#define CONFIG_DTT_DS1621 +#define CONFIG_DTT_SENSORS { 0 } + +/* I2C EEPROM - AT24C128B */ +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x54 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6 /* 64 byte pages */ +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 /* take up to 10 msec */ + +/* I2C RTC */ +#define CONFIG_RTC_M41T11 1 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#define CONFIG_SYS_M41T11_BASE_YEAR 2000 + +/* GPIO/EEPROM/SRAM */ +#define CONFIG_DS4510 +#define CONFIG_SYS_I2C_DS4510_ADDR 0x51 + +/* GPIO */ +#define CONFIG_PCA953X +#define CONFIG_SYS_I2C_PCA953X_ADDR0 0x18 +#define CONFIG_SYS_I2C_PCA953X_ADDR1 0x1c +#define CONFIG_SYS_I2C_PCA953X_ADDR2 0x1e +#define CONFIG_SYS_I2C_PCA953X_ADDR3 0x1f +#define CONFIG_SYS_I2C_PCA953X_ADDR CONFIG_SYS_I2C_PCA953X_ADDR0 + +/* + * PU = pulled high, PD = pulled low + * I = input, O = output, IO = input/output + */ +/* PCA9557 @ 0x18*/ +#define CONFIG_SYS_PCA953X_C0_SER0_EN 0x01 /* PU; UART0 enable (1: enabled) */ +#define CONFIG_SYS_PCA953X_C0_SER0_MODE 0x02 /* PU; UART0 serial mode select */ +#define CONFIG_SYS_PCA953X_C0_SER1_EN 0x04 /* PU; UART1 enable (1: enabled) */ +#define CONFIG_SYS_PCA953X_C0_SER1_MODE 0x08 /* PU; UART1 serial mode select */ +#define CONFIG_SYS_PCA953X_C0_FLASH_PASS_CS 0x10 /* PU; Boot flash CS select */ +#define CONFIG_SYS_PCA953X_NVM_WP 0x20 /* PU; Set to 0 to enable NVM writing */ +#define CONFIG_SYS_PCA953X_C0_VCORE_VID2 0x40 /* VID2 of ISL6262 */ +#define CONFIG_SYS_PCA953X_C0_VCORE_VID3 0x80 /* VID3 of ISL6262 */ + +/* PCA9557 @ 0x1c*/ +#define CONFIG_SYS_PCA953X_XMC0_ROOT0 0x01 /* PU; Low if XMC is RC */ +#define CONFIG_SYS_PCA953X_XMC0_MVMR0 0x02 /* XMC EEPROM write protect */ +#define CONFIG_SYS_PCA953X_XMC0_WAKE 0x04 /* PU; XMC wake */ +#define CONFIG_SYS_PCA953X_XMC0_BIST 0x08 /* PU; XMC built in self test */ +#define CONFIG_SYS_PCA953X_XMC_PRESENT 0x10 /* PU; Low if XMC module installed */ +#define CONFIG_SYS_PCA953X_PMC_PRESENT 0x20 /* PU; Low if PMC module installed */ +#define CONFIG_SYS_PCA953X_PMC0_MONARCH 0x40 /* PMC monarch mode enable */ +#define CONFIG_SYS_PCA953X_PMC0_EREADY 0x80 /* PU; PMC PCI eready */ + +/* PCA9557 @ 0x1e*/ +#define CONFIG_SYS_PCA953X_P0_GA0 0x01 /* PU; VPX Geographical address */ +#define CONFIG_SYS_PCA953X_P0_GA1 0x02 /* PU; VPX Geographical address */ +#define CONFIG_SYS_PCA953X_P0_GA2 0x04 /* PU; VPX Geographical address */ +#define CONFIG_SYS_PCA953X_P0_GA3 0x08 /* PU; VPX Geographical address */ +#define CONFIG_SYS_PCA953X_P0_GA4 0x10 /* PU; VPX Geographical address */ +#define CONFIG_SYS_PCA953X_P0_GAP 0x20 /* PU; tied to VPX P0.GAP */ +#define CONFIG_SYS_PCA953X_P1_SYSEN 0x80 /* PU; Pulled high; tied to VPX P1.SYSCON */ + +/* PCA9557 @ 0x1f */ +#define CONFIG_SYS_PCA953X_GPIO_VPX0 0x01 /* PU */ +#define CONFIG_SYS_PCA953X_GPIO_VPX1 0x02 /* PU */ +#define CONFIG_SYS_PCA953X_GPIO_VPX2 0x04 /* PU */ +#define CONFIG_SYS_PCA953X_GPIO_VPX3 0x08 /* PU */ +#define CONFIG_SYS_PCA953X_VPX_FRU_WRCTL 0x10 /* PD; I2C master source for FRU SEEPROM */ + +/* + * General PCI + * Memory space is mapped 1-1, but I/O space must start from 0. + */ +/* PCIE1 - VPX P1 */ +#define CONFIG_SYS_PCIE1_MEM_BASE 0x80000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS CONFIG_SYS_PCIE1_MEM_BASE +#define CONFIG_SYS_PCIE1_MEM_SIZE 0x40000000 /* 1G */ +#define CONFIG_SYS_PCIE1_IO_BASE 0x00000000 +#define CONFIG_SYS_PCIE1_IO_PHYS 0xe8000000 +#define CONFIG_SYS_PCIE1_IO_SIZE 0x00800000 /* 8M */ + +/* PCIE2 - PEX8518 */ +#define CONFIG_SYS_PCIE2_MEM_BASE 0xc0000000 +#define CONFIG_SYS_PCIE2_MEM_PHYS CONFIG_SYS_PCIE2_MEM_BASE +#define CONFIG_SYS_PCIE2_MEM_SIZE 0x10000000 /* 256M */ +#define CONFIG_SYS_PCIE2_IO_BASE 0x00000000 +#define CONFIG_SYS_PCIE2_IO_PHYS 0xe8800000 +#define CONFIG_SYS_PCIE2_IO_SIZE 0x00800000 /* 8M */ + +/* + * Networking options + */ +#define CONFIG_TSEC_ENET /* tsec ethernet support */ +#define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ +#define CONFIG_NET_MULTI 1 +#define CONFIG_TSEC_TBI +#define CONFIG_MII 1 /* MII PHY management */ +#define CONFIG_MII_DEFAULT_TSEC 1 /* Allow unregistered phys */ +#define CONFIG_ETHPRIME "eTSEC2" + +#define CONFIG_TSEC1 1 +#define CONFIG_TSEC1_NAME "eTSEC1" +#define TSEC1_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC1_PHY_ADDR 1 +#define TSEC1_PHYIDX 0 +#define CONFIG_HAS_ETH0 + +#define CONFIG_TSEC2 1 +#define CONFIG_TSEC2_NAME "eTSEC2" +#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_PHY_ADDR 2 +#define TSEC2_PHYIDX 0 +#define CONFIG_HAS_ETH1 + +/* + * Command configuration. + */ +#include + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_DS4510 +#define CONFIG_CMD_DS4510_INFO +#define CONFIG_CMD_DTT +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_ELF +#define CONFIG_CMD_ENV +#define CONFIG_CMD_FLASH +#define CONFIG_CMD_I2C +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_MII +#define CONFIG_CMD_NET +#define CONFIG_CMD_PCA953X +#define CONFIG_CMD_PCA953X_INFO +#define CONFIG_CMD_PCI +#define CONFIG_CMD_PING +#define CONFIG_CMD_SNTP + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_LOAD_ADDR 0x2000000 /* default load address */ +#define CONFIG_SYS_PROMPT "=> " /* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */ +#define CONFIG_SYS_HZ 1000 /* decrementer freq: 1ms ticks */ +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +#define CONFIG_LOADADDR 0x1000000 /* default location for tftp and bootm */ +#define CONFIG_BOOTDELAY 3 /* -1 disables auto-boot */ +#define CONFIG_PANIC_HANG /* do not reset board on panic */ +#define CONFIG_PREBOOT /* enable preboot variable */ +#define CONFIG_FIT 1 +#define CONFIG_FIT_VERBOSE 1 +#define CONFIG_INTEGRITY /* support booting INTEGRITY OS */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 16 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_SYS_BOOTMAPSZ (16 << 20) /* Initial Memory map for Linux*/ + +/* + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +/* + * Environment Configuration + */ +#define CONFIG_ENV_IS_IN_FLASH 1 +#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128k (one sector) for env */ +#define CONFIG_ENV_SIZE 0x8000 +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - (256 * 1024)) + +/* + * Flash memory map: + * fff80000 - ffffffff Pri U-Boot (512 KB) + * fff40000 - fff7ffff Pri U-Boot Environment (256 KB) + * fff00000 - fff3ffff Pri FDT (256KB) + * fef00000 - ffefffff Pri OS image (16MB) + * f8000000 - feefffff Pri OS Use/Filesystem (111MB) + * + * f7f80000 - f7ffffff Sec U-Boot (512 KB) + * f7f40000 - f7f7ffff Sec U-Boot Environment (256 KB) + * f7f00000 - f7f3ffff Sec FDT (256KB) + * f6f00000 - f7efffff Sec OS image (16MB) + * f0000000 - f6efffff Sec OS Use/Filesystem (111MB) + */ +#define CONFIG_UBOOT1_ENV_ADDR MK_STR(0xfff80000) +#define CONFIG_UBOOT2_ENV_ADDR MK_STR(0xf7f80000) +#define CONFIG_FDT1_ENV_ADDR MK_STR(0xfff00000) +#define CONFIG_FDT2_ENV_ADDR MK_STR(0xf7f00000) +#define CONFIG_OS1_ENV_ADDR MK_STR(0xfef00000) +#define CONFIG_OS2_ENV_ADDR MK_STR(0xf6f00000) + +#define CONFIG_PROG_UBOOT1 \ + "$download_cmd $loadaddr $ubootfile; " \ + "if test $? -eq 0; then " \ + "protect off "CONFIG_UBOOT1_ENV_ADDR" +80000; " \ + "erase "CONFIG_UBOOT1_ENV_ADDR" +80000; " \ + "cp.w $loadaddr "CONFIG_UBOOT1_ENV_ADDR" 40000; " \ + "protect on "CONFIG_UBOOT1_ENV_ADDR" +80000; " \ + "cmp.b $loadaddr "CONFIG_UBOOT1_ENV_ADDR" 80000; " \ + "if test $? -ne 0; then " \ + "echo PROGRAM FAILED; " \ + "else; " \ + "echo PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_UBOOT2 \ + "$download_cmd $loadaddr $ubootfile; " \ + "if test $? -eq 0; then " \ + "protect off "CONFIG_UBOOT2_ENV_ADDR" +80000; " \ + "erase "CONFIG_UBOOT2_ENV_ADDR" +80000; " \ + "cp.w $loadaddr "CONFIG_UBOOT2_ENV_ADDR" 40000; " \ + "protect on "CONFIG_UBOOT2_ENV_ADDR" +80000; " \ + "cmp.b $loadaddr "CONFIG_UBOOT2_ENV_ADDR" 80000; " \ + "if test $? -ne 0; then " \ + "echo PROGRAM FAILED; " \ + "else; " \ + "echo PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_BOOT_OS_NET \ + "$download_cmd $osaddr $osfile; " \ + "if test $? -eq 0; then " \ + "if test -n $fdtaddr; then " \ + "$download_cmd $fdtaddr $fdtfile; " \ + "if test $? -eq 0; then " \ + "bootm $osaddr - $fdtaddr; " \ + "else; " \ + "echo FDT DOWNLOAD FAILED; " \ + "fi; " \ + "else; " \ + "bootm $osaddr; " \ + "fi; " \ + "else; " \ + "echo OS DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_OS1 \ + "$download_cmd $osaddr $osfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_OS1_ENV_ADDR" +$filesize; " \ + "cp.b $osaddr "CONFIG_OS1_ENV_ADDR" $filesize; " \ + "cmp.b $osaddr "CONFIG_OS1_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo OS PROGRAM FAILED; " \ + "else; " \ + "echo OS PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo OS DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_OS2 \ + "$download_cmd $osaddr $osfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_OS2_ENV_ADDR" +$filesize; " \ + "cp.b $osaddr "CONFIG_OS2_ENV_ADDR" $filesize; " \ + "cmp.b $osaddr "CONFIG_OS2_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo OS PROGRAM FAILED; " \ + "else; " \ + "echo OS PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo OS DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_FDT1 \ + "$download_cmd $fdtaddr $fdtfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_FDT1_ENV_ADDR" +$filesize;" \ + "cp.b $fdtaddr "CONFIG_FDT1_ENV_ADDR" $filesize; " \ + "cmp.b $fdtaddr "CONFIG_FDT1_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo FDT PROGRAM FAILED; " \ + "else; " \ + "echo FDT PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo FDT DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_FDT2 \ + "$download_cmd $fdtaddr $fdtfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_FDT2_ENV_ADDR" +$filesize;" \ + "cp.b $fdtaddr "CONFIG_FDT2_ENV_ADDR" $filesize; " \ + "cmp.b $fdtaddr "CONFIG_FDT2_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo FDT PROGRAM FAILED; " \ + "else; " \ + "echo FDT PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo FDT DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "autoload=yes\0" \ + "download_cmd=tftp\0" \ + "console_args=console=ttyS0,115200\0" \ + "root_args=root=/dev/nfs rw\0" \ + "misc_args=ip=on\0" \ + "set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \ + "bootfile=/home/user/file\0" \ + "osfile=/home/user/uImage-XPedite5370\0" \ + "fdtfile=/home/user/xpedite5370.dtb\0" \ + "ubootfile=/home/user/u-boot.bin\0" \ + "fdtaddr=c00000\0" \ + "osaddr=0x1000000\0" \ + "loadaddr=0x1000000\0" \ + "prog_uboot1="CONFIG_PROG_UBOOT1"\0" \ + "prog_uboot2="CONFIG_PROG_UBOOT2"\0" \ + "prog_os1="CONFIG_PROG_OS1"\0" \ + "prog_os2="CONFIG_PROG_OS2"\0" \ + "prog_fdt1="CONFIG_PROG_FDT1"\0" \ + "prog_fdt2="CONFIG_PROG_FDT2"\0" \ + "bootcmd_net=run set_bootargs; "CONFIG_BOOT_OS_NET"\0" \ + "bootcmd_flash1=run set_bootargs; " \ + "bootm "CONFIG_OS1_ENV_ADDR" - "CONFIG_FDT1_ENV_ADDR"\0"\ + "bootcmd_flash2=run set_bootargs; " \ + "bootm "CONFIG_OS2_ENV_ADDR" - "CONFIG_FDT2_ENV_ADDR"\0"\ + "bootcmd=run bootcmd_flash1\0" +#endif /* __CONFIG_H */ -- cgit v1.1 From 487dcb4fb89be0992bc06ec1341090017bd9cf2f Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Wed, 29 Oct 2008 12:39:27 -0500 Subject: 85xx: Enable inbound PCI config cycles for X-ES boards Update X-ES Freescale boards to allow inbound PCI configuration cycles when configured as agent/endpoint. Signed-off-by: Peter Tyser --- board/xes/common/fsl_85xx_pci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/board/xes/common/fsl_85xx_pci.c b/board/xes/common/fsl_85xx_pci.c index b8e363e..4b04881 100644 --- a/board/xes/common/fsl_85xx_pci.c +++ b/board/xes/common/fsl_85xx_pci.c @@ -29,6 +29,7 @@ #include extern int fsl_pci_setup_inbound_windows(struct pci_region *r); +extern void fsl_pci_config_unlock(struct pci_controller *hose); extern void fsl_pci_init(struct pci_controller *hose); int first_free_busno = 0; @@ -138,6 +139,10 @@ void pci_init_board(void) fsl_pci_init(hose); + /* Unlock inbound PCI configuration cycles */ + if (!host) + fsl_pci_config_unlock(hose); + first_free_busno = hose->last_busno+1; printf(" PCIE1 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); @@ -187,6 +192,11 @@ void pci_init_board(void) (int)&pci->cfg_data); fsl_pci_init(hose); + + /* Unlock inbound PCI configuration cycles */ + if (!host) + fsl_pci_config_unlock(hose); + first_free_busno = hose->last_busno+1; printf(" PCIE2 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); @@ -237,6 +247,11 @@ void pci_init_board(void) (int)&pci->cfg_data); fsl_pci_init(hose); + + /* Unlock inbound PCI configuration cycles */ + if (!host) + fsl_pci_config_unlock(hose); + first_free_busno = hose->last_busno+1; printf(" PCIE3 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); -- cgit v1.1 From 78bbc5ce151c5a484bb51bf1866b4a993ffc16ec Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Mon, 1 Dec 2008 13:47:13 -0600 Subject: XPedite5200 board support Initial support for Extreme Engineering Solutions XPedite5200 - a MPC8548-based PMC single board computer. Signed-off-by: Peter Tyser --- MAINTAINERS | 1 + MAKEALL | 1 + Makefile | 3 ++ board/xes/common/Makefile | 3 +- board/xes/common/fsl_85xx_pci.c | 103 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 106 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index be10eb4..60def0c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -413,6 +413,7 @@ Rune Torgersen Peter Tyser + XPEDITE5200 MPC8548 XPEDITE5370 MPC8572 David Updegraff diff --git a/MAKEALL b/MAKEALL index a136bad..5ce3f31 100755 --- a/MAKEALL +++ b/MAKEALL @@ -385,6 +385,7 @@ LIST_85xx=" \ TQM8548 \ TQM8555 \ TQM8560 \ + XPEDITE5200 \ XPEDITE5370 \ " diff --git a/Makefile b/Makefile index 752a370..c532e5b 100644 --- a/Makefile +++ b/Makefile @@ -2463,6 +2463,9 @@ TQM8560_config: unconfig echo "#define CONFIG_BOARDNAME \"TQM$${CTYPE}\"">>$(obj)include/config.h; @$(MKCONFIG) -a TQM85xx ppc mpc85xx tqm85xx tqc +XPEDITE5200_config: unconfig + @$(MKCONFIG) $(@:_config=) ppc mpc85xx xpedite5200 xes + XPEDITE5370_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx xpedite5370 xes diff --git a/board/xes/common/Makefile b/board/xes/common/Makefile index c5cd633..e7620f4 100644 --- a/board/xes/common/Makefile +++ b/board/xes/common/Makefile @@ -29,9 +29,10 @@ endif LIB = $(obj)lib$(VENDOR).a +COBJS-$(CONFIG_FSL_PCI_INIT) += fsl_85xx_pci.o COBJS-$(CONFIG_MPC8572) += fsl_8572_clk.o COBJS-$(CONFIG_MPC85xx) += fsl_85xx_ddr.o -COBJS-$(CONFIG_FSL_PCI_INIT) += fsl_85xx_pci.o +COBJS-$(CONFIG_NAND_ACTL) += actl_nand.o SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/xes/common/fsl_85xx_pci.c b/board/xes/common/fsl_85xx_pci.c index 4b04881..56f3447 100644 --- a/board/xes/common/fsl_85xx_pci.c +++ b/board/xes/common/fsl_85xx_pci.c @@ -34,6 +34,9 @@ extern void fsl_pci_init(struct pci_controller *hose); int first_free_busno = 0; +#ifdef CONFIG_PCI1 +static struct pci_controller pci1_hose; +#endif #ifdef CONFIG_PCIE1 static struct pci_controller pcie1_hose; #endif @@ -44,6 +47,7 @@ static struct pci_controller pcie2_hose; static struct pci_controller pcie3_hose; #endif +#ifdef CONFIG_MPC8572 /* Correlate host/agent POR bits to usable info. Table 4-14 */ struct host_agent_cfg_t { uchar pcie_root[3]; @@ -81,6 +85,38 @@ struct io_port_cfg_t { {{0, 0, 0}, 4}, {{8, 0, 0}, 0}, }; +#elif defined CONFIG_MPC8548 +/* Correlate host/agent POR bits to usable info. Table 4-12 */ +struct host_agent_cfg_t { + uchar pci_host[2]; + uchar pcie_root[1]; + uchar rio_host; +} host_agent_cfg[8] = { + {{1, 1}, {0}, 0}, + {{1, 1}, {1}, 0}, + {{1, 1}, {0}, 1}, + {{0, 0}, {0}, 0}, /* reserved */ + {{0, 1}, {1}, 0}, + {{1, 1}, {1}, 0}, + {{0, 1}, {1}, 1}, + {{1, 1}, {1}, 1} +}; + +/* Correlate port width POR bits to usable info. Table 4-13 */ +struct io_port_cfg_t { + uchar pcie_width[1]; + uchar rio_width; +} io_port_cfg[8] = { + {{0}, 0}, + {{0}, 0}, + {{0}, 0}, + {{4}, 4}, + {{4}, 4}, + {{0}, 4}, + {{0}, 4}, + {{8}, 0}, +}; +#endif void pci_init_board(void) { @@ -94,9 +130,65 @@ void pci_init_board(void) uint host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16; struct pci_region *r; - debug(" pci_init_board: devdisr=%x, io_sel=%x, host_agent=%x\n", - devdisr, io_sel, host_agent); +#ifdef CONFIG_PCI1 + uint pci_spd_norm = (gur->pordevsr & MPC85xx_PORDEVSR_PCI1_SPD); + uint pci_32 = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32; + uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB; + uint pcix = gur->pordevsr & MPC85xx_PORDEVSR_PCI1; + uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000; + + width = 0; /* Silence compiler warning... */ + io_sel &= 0xf; /* Silence compiler warning... */ + pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR; + hose = &pci1_hose; + host = host_agent_cfg[host_agent].pci_host[0]; + r = hose->regions; + + + if (!(devdisr & MPC85xx_DEVDISR_PCI1)) { + printf("\n PCI1: %d bit %s, %s %d MHz, %s, %s\n", + pci_32 ? 32 : 64, + pcix ? "PCIX" : "PCI", + pci_spd_norm ? ">=" : "<=", + pcix ? freq * 2 : freq, + host ? "host" : "agent", + pci_arb ? "arbiter" : "external-arbiter"); + /* inbound */ + r += fsl_pci_setup_inbound_windows(r); + + /* outbound memory */ + pci_set_region(r++, + CONFIG_SYS_PCI1_MEM_BASE, + CONFIG_SYS_PCI1_MEM_PHYS, + CONFIG_SYS_PCI1_MEM_SIZE, + PCI_REGION_MEM); + + /* outbound io */ + pci_set_region(r++, + CONFIG_SYS_PCI1_IO_BASE, + CONFIG_SYS_PCI1_IO_PHYS, + CONFIG_SYS_PCI1_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = r - hose->regions; + + hose->first_busno = first_free_busno; + pci_setup_indirect(hose, (int)&pci->cfg_addr, + (int)&pci->cfg_data); + + fsl_pci_init(hose); + + first_free_busno = hose->last_busno+1; + printf(" PCI1 on bus %02x - %02x\n", + hose->first_busno, hose->last_busno); + } else { + printf(" PCI1: disabled\n"); + } +#elif defined CONFIG_MPC8548 + /* PCI1 not present on MPC8572 */ + gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */ +#endif #ifdef CONFIG_PCIE1 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR; hose = &pcie1_hose; @@ -143,7 +235,7 @@ void pci_init_board(void) if (!host) fsl_pci_config_unlock(hose); - first_free_busno = hose->last_busno+1; + first_free_busno = hose->last_busno + 1; printf(" PCIE1 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); } @@ -200,7 +292,6 @@ void pci_init_board(void) first_free_busno = hose->last_busno+1; printf(" PCIE2 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); - } #else gur->devdisr |= MPC85xx_DEVDISR_PCIE2; /* disable */ @@ -267,6 +358,10 @@ extern void ft_fsl_pci_setup(void *blob, const char *pci_alias, void ft_board_pci_setup(void *blob, bd_t *bd) { + /* TODO - make node name (eg pci0) dynamic */ +#ifdef CONFIG_PCI1 + ft_fsl_pci_setup(blob, "pci0", &pci1_hose); +#endif #ifdef CONFIG_PCIE1 ft_fsl_pci_setup(blob, "pci2", &pcie1_hose); #endif -- cgit v1.1 From ecf5b98c7a6a2e2256dfddd48fab26678dcd6b90 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 16 Dec 2008 14:59:20 -0600 Subject: 85xx: Add support to populate addr map based on TLB settings Signed-off-by: Kumar Gala --- cpu/mpc85xx/tlb.c | 34 ++++++++++++++++++++++++++++++++++ include/asm-ppc/mmu.h | 3 +++ lib_ppc/board.c | 8 ++++++++ 3 files changed, 45 insertions(+) diff --git a/cpu/mpc85xx/tlb.c b/cpu/mpc85xx/tlb.c index a2d16ae..5b5f791 100644 --- a/cpu/mpc85xx/tlb.c +++ b/cpu/mpc85xx/tlb.c @@ -26,6 +26,11 @@ #include #include #include +#ifdef CONFIG_ADDR_MAP +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; void set_tlb(u8 tlb, u32 epn, u64 rpn, u8 perms, u8 wimge, @@ -47,6 +52,11 @@ void set_tlb(u8 tlb, u32 epn, u64 rpn, mtspr(MAS7, _mas7); #endif asm volatile("isync;msync;tlbwe;isync"); + +#ifdef CONFIG_ADDR_MAP + if ((tlb == 1) && (gd->flags & GD_FLG_RELOC)) + addrmap_set_entry(epn, rpn, (1UL << ((tsize * 2) + 10)), esel); +#endif } void disable_tlb(u8 esel) @@ -67,6 +77,11 @@ void disable_tlb(u8 esel) mtspr(MAS7, _mas7); #endif asm volatile("isync;msync;tlbwe;isync"); + +#ifdef CONFIG_ADDR_MAP + if (gd->flags & GD_FLG_RELOC) + addrmap_set_entry(0, 0, 0, esel); +#endif } void invalidate_tlb(u8 tlb) @@ -91,6 +106,25 @@ void init_tlbs(void) return ; } +#ifdef CONFIG_ADDR_MAP +void init_addr_map(void) +{ + int i; + + for (i = 0; i < num_tlb_entries; i++) { + if (tlb_table[i].tlb == 0) + continue; + + addrmap_set_entry(tlb_table[i].epn, + tlb_table[i].rpn, + (1UL << ((tlb_table[i].tsize * 2) + 10)), + tlb_table[i].esel); + } + + return ; +} +#endif + unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg) { unsigned int tlb_size; diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 8975e6c..6d942d0 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -431,6 +431,9 @@ extern void set_tlb(u8 tlb, u32 epn, u64 rpn, extern void disable_tlb(u8 esel); extern void invalidate_tlb(u8 tlb); extern void init_tlbs(void); +#ifdef CONFIG_ADDR_MAP +extern void init_addr_map(void); +#endif extern unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg); #define SET_TLB_ENTRY(_tlb, _epn, _rpn, _perms, _wimge, _ts, _esel, _sz, _iprot) \ diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 289a32a..61c29b5 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -75,6 +75,10 @@ #include #endif +#ifdef CONFIG_ADDR_MAP +#include +#endif + #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE extern int update_flash_size (int flash_size); #endif @@ -694,6 +698,10 @@ void board_init_r (gd_t *id, ulong dest_addr) */ trap_init (dest_addr); +#if defined(CONFIG_ADDR_MAP) && defined(CONFIG_E500) + init_addr_map(); +#endif + #if defined(CONFIG_BOARD_EARLY_INIT_R) board_early_init_r (); #endif -- cgit v1.1 From 77c8115b1f1871811633eae77a5a700fac1f0e50 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 16 Dec 2008 14:59:21 -0600 Subject: ppc: Use addrmap in virt_to_phys and map_physmem. If we have addr map support enabled use the mapping functions to implement virt_to_phys() and map_physmem(). Signed-off-by: Kumar Gala --- include/asm-ppc/io.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index 64cb746..4ddad26 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -10,6 +10,10 @@ #include #include +#ifdef CONFIG_ADDR_MAP +#include +#endif + #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399 @@ -287,7 +291,11 @@ extern inline void out_be32(volatile unsigned __iomem *addr, int val) static inline void * map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) { +#ifdef CONFIG_ADDR_MAP + return (void *)(addrmap_phys_to_virt(paddr)); +#else return (void *)((unsigned long)paddr); +#endif } /* @@ -300,7 +308,11 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags) static inline phys_addr_t virt_to_phys(void * vaddr) { +#ifdef CONFIG_ADDR_MAP + return addrmap_virt_to_phys(vaddr); +#else return (phys_addr_t)((unsigned long)vaddr); +#endif } #endif -- cgit v1.1 From 9d94aff699eed38b286814fcbb335f3eb8516a0e Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 16 Dec 2008 14:59:22 -0600 Subject: NAND FSL elbc: Use virt_to_phys to determine which bank is in use The current code that determines which bank/chipselect is used for a given NAND instance only worked for 32-bit addresses and assumed a 1:1 mapping. This breaks in 36-bit physical configs. The proper way to handle this is to use the virt_to_phys() and BR_PHYS_ADDR() routinues to match the 34-bit lbc bus address with the the virtual address the NAND code uses. Signed-off-by: Kumar Gala Acked-by: Scott Wood --- drivers/mtd/nand/fsl_elbc_nand.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 367c7d7..3f318e0 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -718,7 +718,7 @@ static void fsl_elbc_ctrl_init(void) int board_nand_init(struct nand_chip *nand) { struct fsl_elbc_mtd *priv; - uint32_t br, or; + uint32_t br = 0, or = 0; if (!elbc_ctrl) { fsl_elbc_ctrl_init(); @@ -737,11 +737,13 @@ int board_nand_init(struct nand_chip *nand) * if we could pass more than one datum to the NAND driver... */ for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) { + phys_addr_t base_addr = virt_to_phys(nand->IO_ADDR_R); + br = in_be32(&elbc_ctrl->regs->bank[priv->bank].br); or = in_be32(&elbc_ctrl->regs->bank[priv->bank].or); if ((br & BR_V) && (br & BR_MSEL) == BR_MS_FCM && - (br & or & BR_BA) == (phys_addr_t)nand->IO_ADDR_R) + (br & or & BR_BA) == BR_PHYS_ADDR(base_addr)) break; } -- cgit v1.1 From 58ec4866ed916c7e422f5107bb27b0822084728e Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 3 Dec 2008 15:16:38 -0800 Subject: mpc8[56]xx: Put localbus clock in device tree Export the localbus frequency in the device tree, the same way the CPU, TB, CCB, and various other frequencies are exported in their respective device tree nodes. Some localbus devices need this information to be programed correctly, so it makes sense to export it along with the other frequencies. Unfortunately, when someone wrote the localbus dts bindings, they didn't bother to define what the "compatible" property should be. So it seems no one was quite sure what to put in their dts files. Based on current existing dts files in the kernel source, I've used "fsl,pq3-localbus" and "fsl,elbc" for MPC85xx, which are used by almost all of the 85xx devices, and are looked for by the Linux code. The eLBC is apparently not entirely backward compatible with the pq3 LBC and so eLBC equipped platforms like 8572 won't use pq3-localbus. For MPC86xx, I've used "fsl,elbc" which is used by some of the 86xx systems and is also looked for by the Linux code. On MPC8641, I've also used "fsl,mpc8641-localbus" as it is also commonly used in dts files, some of which don't use "fsl,elbc" or any other acceptable name to match on. Signed-off-by: Trent Piepho Acked-by: Kumar Gala Acked-by: Jon Loeliger --- cpu/mpc85xx/fdt.c | 8 +++++++- cpu/mpc86xx/fdt.c | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c index 59aafb1..69fab99 100644 --- a/cpu/mpc85xx/fdt.c +++ b/cpu/mpc85xx/fdt.c @@ -28,11 +28,12 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + extern void ft_qe_setup(void *blob); #ifdef CONFIG_MP #include "mp.h" -DECLARE_GLOBAL_DATA_PTR; void ft_fixup_cpu(void *blob, u64 memory_limit) { @@ -231,6 +232,11 @@ void ft_cpu_setup(void *blob, bd_t *bd) "clock-frequency", bd->bi_intfreq, 1); do_fixup_by_prop_u32(blob, "device_type", "soc", 4, "bus-frequency", bd->bi_busfreq, 1); + + do_fixup_by_compat_u32(blob, "fsl,pq3-localbus", + "bus-frequency", gd->lbc_clk, 1); + do_fixup_by_compat_u32(blob, "fsl,elbc", + "bus-frequency", gd->lbc_clk, 1); #ifdef CONFIG_QE ft_qe_setup(blob); #endif diff --git a/cpu/mpc86xx/fdt.c b/cpu/mpc86xx/fdt.c index 3adfad9..e277040 100644 --- a/cpu/mpc86xx/fdt.c +++ b/cpu/mpc86xx/fdt.c @@ -13,6 +13,8 @@ DECLARE_GLOBAL_DATA_PTR; +DECLARE_GLOBAL_DATA_PTR; + void ft_cpu_setup(void *blob, bd_t *bd) { #if (CONFIG_NUM_CPUS > 1) @@ -29,6 +31,13 @@ void ft_cpu_setup(void *blob, bd_t *bd) do_fixup_by_prop_u32(blob, "device_type", "soc", 4, "bus-frequency", bd->bi_busfreq, 1); +#if defined(CONFIG_MPC8641) + do_fixup_by_compat_u32(blob, "fsl,mpc8641-localbus", + "bus-frequency", gd->lbc_clk, 1); +#endif + do_fixup_by_compat_u32(blob, "fsl,elbc", + "bus-frequency", gd->lbc_clk, 1); + fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); #if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) \ -- cgit v1.1 From a5d212a263c58cc746481bf1fc878510533ce7d6 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 3 Dec 2008 15:16:34 -0800 Subject: mpc8xxx: LCRR[CLKDIV] is sometimes five bits On newer CPUs, 8536, 8572, and 8610, the CLKDIV field of LCRR is five bits instead of four. In order to avoid an ifdef, LCRR_CLKDIV is set to 0x1f on all systems. It should be safe as the fifth bit was defined as reserved and set to 0. Code that was using a hard coded 0x0f is changed to use LCRR_CLKDIV. Signed-off-by: Trent Piepho Acked-by: Kumar Gala Acked-by: Jon Loeliger --- board/freescale/mpc8540ads/mpc8540ads.c | 2 +- board/freescale/mpc8541cds/mpc8541cds.c | 2 +- board/freescale/mpc8548cds/mpc8548cds.c | 2 +- board/freescale/mpc8555cds/mpc8555cds.c | 2 +- board/freescale/mpc8560ads/mpc8560ads.c | 2 +- board/freescale/mpc8568mds/mpc8568mds.c | 2 +- board/mpc8540eval/mpc8540eval.c | 2 +- board/pm854/pm854.c | 2 +- board/pm856/pm856.c | 2 +- board/sbc8548/sbc8548.c | 2 +- board/socrates/socrates.c | 2 +- board/tqc/tqm85xx/tqm85xx.c | 2 +- cpu/mpc85xx/cpu.c | 2 +- cpu/mpc86xx/cpu.c | 2 +- include/asm-ppc/fsl_lbc.h | 5 ++++- 15 files changed, 18 insertions(+), 15 deletions(-) diff --git a/board/freescale/mpc8540ads/mpc8540ads.c b/board/freescale/mpc8540ads/mpc8540ads.c index a0b6fbd..9e3f677 100644 --- a/board/freescale/mpc8540ads/mpc8540ads.c +++ b/board/freescale/mpc8540ads/mpc8540ads.c @@ -133,7 +133,7 @@ local_bus_init(void) */ get_sys_info(&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { diff --git a/board/freescale/mpc8541cds/mpc8541cds.c b/board/freescale/mpc8541cds/mpc8541cds.c index 7e40c5c..e6025c8 100644 --- a/board/freescale/mpc8541cds/mpc8541cds.c +++ b/board/freescale/mpc8541cds/mpc8541cds.c @@ -308,7 +308,7 @@ local_bus_init(void) */ get_sys_info(&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { diff --git a/board/freescale/mpc8548cds/mpc8548cds.c b/board/freescale/mpc8548cds/mpc8548cds.c index c562fc9..90e89bc 100644 --- a/board/freescale/mpc8548cds/mpc8548cds.c +++ b/board/freescale/mpc8548cds/mpc8548cds.c @@ -125,7 +125,7 @@ local_bus_init(void) sys_info_t sysinfo; get_sys_info(&sysinfo); - clkdiv = (lbc->lcrr & 0x0f) * 2; + clkdiv = (lbc->lcrr & LCRR_CLKDIV) * 2; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; gur->lbiuiplldcr1 = 0x00078080; diff --git a/board/freescale/mpc8555cds/mpc8555cds.c b/board/freescale/mpc8555cds/mpc8555cds.c index 33685c1..53d5a93 100644 --- a/board/freescale/mpc8555cds/mpc8555cds.c +++ b/board/freescale/mpc8555cds/mpc8555cds.c @@ -308,7 +308,7 @@ local_bus_init(void) */ get_sys_info(&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { diff --git a/board/freescale/mpc8560ads/mpc8560ads.c b/board/freescale/mpc8560ads/mpc8560ads.c index 3730818..ac7778e 100644 --- a/board/freescale/mpc8560ads/mpc8560ads.c +++ b/board/freescale/mpc8560ads/mpc8560ads.c @@ -337,7 +337,7 @@ local_bus_init(void) */ get_sys_info(&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { diff --git a/board/freescale/mpc8568mds/mpc8568mds.c b/board/freescale/mpc8568mds/mpc8568mds.c index bc93be8..7a23b33 100644 --- a/board/freescale/mpc8568mds/mpc8568mds.c +++ b/board/freescale/mpc8568mds/mpc8568mds.c @@ -188,7 +188,7 @@ local_bus_init(void) sys_info_t sysinfo; get_sys_info(&sysinfo); - clkdiv = (lbc->lcrr & 0x0f) * 2; + clkdiv = (lbc->lcrr & LCRR_CLKDIV) * 2; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; gur->lbiuiplldcr1 = 0x00078080; diff --git a/board/mpc8540eval/mpc8540eval.c b/board/mpc8540eval/mpc8540eval.c index fa0a336..bf270f4 100644 --- a/board/mpc8540eval/mpc8540eval.c +++ b/board/mpc8540eval/mpc8540eval.c @@ -101,7 +101,7 @@ phys_size_t initdram (int board_type) #if !defined(CONFIG_RAM_AS_FLASH) /* LocalBus is not emulating flash */ get_sys_info(&sysinfo); /* if localbus freq is less than 66MHz,we use bypass mode,otherwise use DLL */ - if(sysinfo.freqSystemBus/(CONFIG_SYS_LBC_LCRR & 0x0f) < 66000000) { + if(sysinfo.freqSystemBus/(CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV) < 66000000) { lbc->lcrr = (CONFIG_SYS_LBC_LCRR & 0x0fffffff)| 0x80000000; } else { lbc->lcrr = CONFIG_SYS_LBC_LCRR & 0x7fffffff; diff --git a/board/pm854/pm854.c b/board/pm854/pm854.c index fed0ed4..5353d73 100644 --- a/board/pm854/pm854.c +++ b/board/pm854/pm854.c @@ -150,7 +150,7 @@ local_bus_init(void) */ get_sys_info(&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { diff --git a/board/pm856/pm856.c b/board/pm856/pm856.c index 932f112..b14a3d3 100644 --- a/board/pm856/pm856.c +++ b/board/pm856/pm856.c @@ -306,7 +306,7 @@ local_bus_init(void) */ get_sys_info(&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 8c073cb..519b0f7 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -126,7 +126,7 @@ local_bus_init(void) sys_info_t sysinfo; get_sys_info(&sysinfo); - clkdiv = (lbc->lcrr & 0x0f) * 2; + clkdiv = (lbc->lcrr & LCRR_CLKDIV) * 2; lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; gur->lbiuiplldcr1 = 0x00078080; diff --git a/board/socrates/socrates.c b/board/socrates/socrates.c index d83dc7d..df9696e 100644 --- a/board/socrates/socrates.c +++ b/board/socrates/socrates.c @@ -156,7 +156,7 @@ void local_bus_init (void) uint lcrr = CONFIG_SYS_LBC_LCRR; get_sys_info (&sysinfo); - clkdiv = lbc->lcrr & 0x0f; + clkdiv = lbc->lcrr & LCRR_CLKDIV; lbc_mhz = sysinfo.freqSystemBus / 1000000 / clkdiv; /* Disable PLL bypass for Local Bus Clock >= 66 MHz */ diff --git a/board/tqc/tqm85xx/tqm85xx.c b/board/tqc/tqm85xx/tqm85xx.c index 73f1d01..cda8208 100644 --- a/board/tqc/tqm85xx/tqm85xx.c +++ b/board/tqc/tqm85xx/tqm85xx.c @@ -361,7 +361,7 @@ uint get_lbc_clock (void) { volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); sys_info_t sys_info; - ulong clkdiv = lbc->lcrr & 0x0f; + ulong clkdiv = lbc->lcrr & LCRR_CLKDIV; get_sys_info (&sys_info); diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 943602f..59a9ac8 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -174,7 +174,7 @@ int checkcpu (void) lcrr = lbc->lcrr; } #endif - clkdiv = lcrr & 0x0f; + clkdiv = lcrr & LCRR_CLKDIV; if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { #if defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) || \ defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536) diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index 4cace98..0ff76e3 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -110,7 +110,7 @@ checkcpu(void) lcrr = lbc->lcrr; } #endif - clkdiv = lcrr & 0x0f; + clkdiv = lcrr & LCRR_CLKDIV; if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { printf("LBC:%4lu MHz\n", sysinfo.freqSystemBus / 1000000 / clkdiv); diff --git a/include/asm-ppc/fsl_lbc.h b/include/asm-ppc/fsl_lbc.h index 51fc5c1..e492c62 100644 --- a/include/asm-ppc/fsl_lbc.h +++ b/include/asm-ppc/fsl_lbc.h @@ -300,7 +300,10 @@ #define LCRR_EADC_2 0x00020000 #define LCRR_EADC_3 0x00030000 #define LCRR_EADC_4 0x00000000 -#define LCRR_CLKDIV 0x0000000F +/* CLKDIV is five bits only on 8536, 8572, and 8610, so far, but the fifth bit + * should always be zero on older parts that have a four bit CLKDIV. + */ +#define LCRR_CLKDIV 0x0000001F #define LCRR_CLKDIV_SHIFT 0 #define LCRR_CLKDIV_2 0x00000002 #define LCRR_CLKDIV_4 0x00000004 -- cgit v1.1 From 181a3650113883728927928b3ac81ad6dade4b2c Mon Sep 17 00:00:00 2001 From: Haiying Wang Date: Wed, 3 Dec 2008 10:08:19 -0500 Subject: Set IVPR to kenrel entry point in second core boot page Assuming the OSes exception vectors start from the base of kernel address, and the kernel physical starting address can be relocated to an non-zero address. This patch enables the second core to have a valid IVPR for debugger before kernel setting IVPR in CAMP mode. Otherwise, IVPR is 0x0 and it is not a valid value for second core which runs kernel at different physical address other than 0x0. Signed-off-by: Haiying Wang --- cpu/mpc85xx/release.S | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S index 7c3e8a1..54c936c 100644 --- a/cpu/mpc85xx/release.S +++ b/cpu/mpc85xx/release.S @@ -157,6 +157,7 @@ __secondary_start_page: mfspr r0,SPRN_PIR stw r0,ENTRY_PIR(r10) + mtspr IVPR,r12 /* * Coming here, we know the cpu has one TLB mapping in TLB1[0] * which maps 0xfffff000-0xffffffff one-to-one. We set up a -- cgit v1.1 From bd93105fa171184a71ca8b22be03dc2705cfbd3f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 11 Dec 2008 15:47:49 -0500 Subject: sbc8548: don't enable the 3rd and 4th eTSEC These interfaces don't have usable connectors on the board, so don't bother enumerating or configuring them. Signed-off-by: Paul Gortmaker --- include/configs/sbc8548.h | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 528c810..254d91f 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -399,25 +399,16 @@ #define CONFIG_TSEC1_NAME "eTSEC0" #define CONFIG_TSEC2 1 #define CONFIG_TSEC2_NAME "eTSEC1" -#define CONFIG_TSEC3 1 -#define CONFIG_TSEC3_NAME "eTSEC2" -#define CONFIG_TSEC4 -#define CONFIG_TSEC4_NAME "eTSEC3" #undef CONFIG_MPC85XX_FEC #define TSEC1_PHY_ADDR 0 #define TSEC2_PHY_ADDR 1 -#define TSEC3_PHY_ADDR 2 -#define TSEC4_PHY_ADDR 3 #define TSEC1_PHYIDX 0 #define TSEC2_PHYIDX 0 -#define TSEC3_PHYIDX 0 -#define TSEC4_PHYIDX 0 + #define TSEC1_FLAGS TSEC_GIGABIT #define TSEC2_FLAGS TSEC_GIGABIT -#define TSEC3_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) -#define TSEC4_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) /* Options are: eTSEC[0-3] */ #define CONFIG_ETHPRIME "eTSEC0" @@ -507,10 +498,6 @@ #define CONFIG_ETHADDR 02:E0:0C:00:00:FD #define CONFIG_HAS_ETH1 #define CONFIG_ETH1ADDR 02:E0:0C:00:01:FD -#define CONFIG_HAS_ETH2 -#define CONFIG_ETH2ADDR 02:E0:0C:00:02:FD -#define CONFIG_HAS_ETH3 -#define CONFIG_ETH3ADDR 02:E0:0C:00:03:FD #endif #define CONFIG_IPADDR 192.168.0.55 -- cgit v1.1 From ad22f9273c6f24fbfa917e867680e9688e0c59c5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 11 Dec 2008 15:47:51 -0500 Subject: sbc8548: enable command line editing by default. Lets make things a bit more user friendly. It isn't 1985 anymore. Signed-off-by: Paul Gortmaker --- include/configs/sbc8548.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 254d91f..8a7b0da 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -455,6 +455,7 @@ /* * Miscellaneous configurable options */ +#define CONFIG_CMDLINE_EDITING /* undef to save memory */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ #define CONFIG_SYS_LOAD_ADDR 0x2000000 /* default load address */ #define CONFIG_SYS_PROMPT "=> " /* Monitor Command Prompt */ -- cgit v1.1 From 58da8890d5fbd074746037722a423de9ac408616 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 11 Dec 2008 15:47:50 -0500 Subject: sbc8548: use proper PHY address The values given for the PHY address were wrong, so the code read no valid PHY ID, and fell through to the generic PHY support, which would work on 1000M but would not auto negotiate down to 100M or 10M. Signed-off-by: Paul Gortmaker --- include/configs/sbc8548.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 8a7b0da..8141a46 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -401,8 +401,8 @@ #define CONFIG_TSEC2_NAME "eTSEC1" #undef CONFIG_MPC85XX_FEC -#define TSEC1_PHY_ADDR 0 -#define TSEC2_PHY_ADDR 1 +#define TSEC1_PHY_ADDR 0x19 +#define TSEC2_PHY_ADDR 0x1a #define TSEC1_PHYIDX 0 #define TSEC2_PHYIDX 0 -- cgit v1.1 From f51f07eb58fad12de9294ba4ee6c09a0ddeaee03 Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Tue, 16 Dec 2008 12:09:27 +0800 Subject: 85xx: Fix the boot window issue If one custom board is using the 8MB flash, it is set as FLASH_BASE = 0xef000000, TEXT_BASE = 0xef780000. The current start.S code will be broken at switch_as. It is because the TLB1[15] is set as 16MB page size, EPN = TEXT_BASE & 0xff000000, RPN = 0xff000000. For the 8MB flash case, the EPN = 0xefxxxxxx, RPN = 0xffxxxxxx. Assume the virt address of switch_as is 0xef7ff18c, the real address of the instruction at switch_as should be 0xff7ff18c. the 0xff7ff18c is out of the range of the default 8MB boot LAW window 0xff800000 - 0xffffffff. So when we switch to AS1 address space at switch_as, the core can't fetch the instruction at switch_as any more. It will cause broken issue. Signed-off-by: Dave Liu --- cpu/mpc85xx/start.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 8fa0ff7..80f9677 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -184,19 +184,19 @@ _start_e500: mtspr DBCR0,r0 #endif - /* create a temp mapping in AS=1 to the boot window */ + /* create a temp mapping in AS=1 to the 4M boot window */ lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l - lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@h - ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@l + lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h + ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l - /* Align the mapping to 16MB */ - lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@h - ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@l + lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@h + ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@l - lis r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h - ori r9,r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l + /* The 85xx has the default boot window 0xff800000 - 0xffffffff */ + lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h + ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l mtspr MAS0,r6 mtspr MAS1,r7 -- cgit v1.1 From 446c381e3e16f19857b72ea0d06241267b8b9d58 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 3 Dec 2008 15:16:35 -0800 Subject: mpc8568: Double local bus clock divider The clock divider for the MPC8568 local bus should be doubled, like the other newer MPC85xx chips. Since there are now more chips with a 2x divider than a 1x, and any new 85xx chips will probably be 2x, invert the sense of the #if so that it lists the 1x chips instead of the 2x ones. Signed-off-by: Trent Piepho Acked-by: Kumar Gala Acked-by: Jon Loeliger --- cpu/mpc85xx/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 59a9ac8..89800b8 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -176,8 +176,8 @@ int checkcpu (void) #endif clkdiv = lcrr & LCRR_CLKDIV; if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { -#if defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) || \ - defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536) +#if !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ + !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) /* * Yes, the entire PQ38 family use the same * bit-representation for twice the clock divider values. -- cgit v1.1 From 9863d6aca11405e1e0d8aba2045d78aeec4d4ee7 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 3 Dec 2008 15:16:36 -0800 Subject: mpc86xx: Double local bus clock divider The local bus clock divider should be doubled for both 8610 and 8641. Signed-off-by: Trent Piepho Acked-by: Kumar Gala Acked-by: Jon Loeliger --- cpu/mpc86xx/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index 0ff76e3..a179fb3 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -112,6 +112,7 @@ checkcpu(void) #endif clkdiv = lcrr & LCRR_CLKDIV; if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { + clkdiv *= 2; printf("LBC:%4lu MHz\n", sysinfo.freqSystemBus / 1000000 / clkdiv); } else { -- cgit v1.1 From ada591d2a0ecff5f9bc5ed1ebf310f439c3d0a28 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 3 Dec 2008 15:16:37 -0800 Subject: mpc8[56]xx: Put localbus clock in sysinfo and gd Currently MPC85xx and MPC86xx boards just calculate the localbus frequency and print it out, but don't save it. This changes where its calculated and stored to be more consistent with the CPU, CCB, TB, and DDR frequencies and the MPC83xx localbus clock. The localbus frequency is added to sysinfo and calculated when sysinfo is set up, in cpu/mpc8[56]xx/speed.c, the same as the other frequencies are. get_clocks() copies the frequency into the global data, as the other frequencies are, into a new field that is only enabled for MPC85xx and MPC86xx. checkcpu() in cpu/mpc8[56]xx/cpu.c will print out the local bus frequency from sysinfo, like the other frequencies, instead of calculating it on the spot. Signed-off-by: Trent Piepho Acked-by: Kumar Gala Acked-by: Jon Loeliger --- cpu/mpc85xx/cpu.c | 31 +++++-------------------------- cpu/mpc85xx/speed.c | 27 +++++++++++++++++++++++++++ cpu/mpc86xx/cpu.c | 22 ++++------------------ cpu/mpc86xx/speed.c | 19 +++++++++++++++++++ include/asm-ppc/global_data.h | 3 +++ include/e500.h | 1 + include/mpc86xx.h | 1 + 7 files changed, 60 insertions(+), 44 deletions(-) diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 89800b8..15ba7f1 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -77,8 +77,6 @@ struct cpu_type *identify_cpu(u32 ver) int checkcpu (void) { sys_info_t sysinfo; - uint lcrr; /* local bus clock ratio register */ - uint clkdiv; /* clock divider portion of lcrr */ uint pvr, svr; uint fam; uint ver; @@ -165,30 +163,11 @@ int checkcpu (void) break; } -#if defined(CONFIG_SYS_LBC_LCRR) - lcrr = CONFIG_SYS_LBC_LCRR; -#else - { - volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); - - lcrr = lbc->lcrr; - } -#endif - clkdiv = lcrr & LCRR_CLKDIV; - if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { -#if !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ - !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) - /* - * Yes, the entire PQ38 family use the same - * bit-representation for twice the clock divider values. - */ - clkdiv *= 2; -#endif - printf("LBC:%-4s MHz\n", - strmhz(buf1, sysinfo.freqSystemBus / clkdiv)); - } else { - printf("LBC: unknown (lcrr: 0x%08x)\n", lcrr); - } + if (sysinfo.freqLocalBus > LCRR_CLKDIV) + printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus)); + else + printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n", + sysinfo.freqLocalBus); #ifdef CONFIG_CPM2 printf("CPM: %s MHz\n", strmhz(buf1, sysinfo.freqSystemBus)); diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c index 1e0f483..0d55228 100644 --- a/cpu/mpc85xx/speed.c +++ b/cpu/mpc85xx/speed.c @@ -28,6 +28,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -37,6 +38,7 @@ void get_sys_info (sys_info_t * sysInfo) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); uint plat_ratio,e500_ratio,half_freqSystemBus; + uint lcrr_div; plat_ratio = (gur->porpllsr) & 0x0000003e; plat_ratio >>= 1; @@ -60,6 +62,30 @@ void get_sys_info (sys_info_t * sysInfo) sysInfo->freqDDRBus = ddr_ratio * CONFIG_DDR_CLK_FREQ; } #endif + +#if defined(CONFIG_SYS_LBC_LCRR) + /* We will program LCRR to this value later */ + lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; +#else + { + volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + lcrr_div = in_be32(&lbc->lcrr) & LCRR_CLKDIV; + } +#endif + if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { +#if !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ + !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) + /* + * Yes, the entire PQ38 family use the same + * bit-representation for twice the clock divider values. + */ + lcrr_div *= 2; +#endif + sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; + } else { + /* In case anyone cares what the unknown value is */ + sysInfo->freqLocalBus = lcrr_div; + } } @@ -82,6 +108,7 @@ int get_clocks (void) gd->cpu_clk = sys_info.freqProcessor; gd->bus_clk = sys_info.freqSystemBus; gd->mem_clk = sys_info.freqDDRBus; + gd->lbc_clk = sys_info.freqLocalBus; /* * The base clock for I2C depends on the actual SOC. Unfortunately, diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index a179fb3..3568023 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -39,8 +39,6 @@ checkcpu(void) uint pvr, svr; uint ver; uint major, minor; - uint lcrr; /* local bus clock ratio register */ - uint clkdiv; /* clock divider portion of lcrr */ volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; volatile ccsr_gur_t *gur = &immap->im_gur; @@ -100,23 +98,11 @@ checkcpu(void) printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000); printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000); -#if defined(CONFIG_SYS_LBC_LCRR) - lcrr = CONFIG_SYS_LBC_LCRR; -#else - { - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; - volatile ccsr_lbc_t *lbc = &immap->im_lbc; - - lcrr = lbc->lcrr; - } -#endif - clkdiv = lcrr & LCRR_CLKDIV; - if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { - clkdiv *= 2; - printf("LBC:%4lu MHz\n", - sysinfo.freqSystemBus / 1000000 / clkdiv); + if (sysinfo.freqLocalBus > LCRR_CLKDIV) { + printf("LBC:%4lu MHz\n", sysinfo.freqLocalBus / 1000000); } else { - printf(" LBC: unknown (lcrr: 0x%08x)\n", lcrr); + printf("LBC: unknown (LCRR[CLKDIV] = 0x%02x)\n", + sysinfo.freqLocalBus); } puts(" L2: "); diff --git a/cpu/mpc86xx/speed.c b/cpu/mpc86xx/speed.c index 415ac9d..64a3479 100644 --- a/cpu/mpc86xx/speed.c +++ b/cpu/mpc86xx/speed.c @@ -28,6 +28,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,6 +40,7 @@ void get_sys_info(sys_info_t *sysInfo) volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; volatile ccsr_gur_t *gur = &immap->im_gur; uint plat_ratio, e600_ratio; + uint lcrr_div; plat_ratio = (gur->porpllsr) & 0x0000003e; plat_ratio >>= 1; @@ -90,6 +92,22 @@ void get_sys_info(sys_info_t *sysInfo) sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus; break; } + +#if defined(CONFIG_SYS_LBC_LCRR) + /* We will program LCRR to this value later */ + lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; +#else + { + volatile ccsr_lbc_t *lbc = &immap->im_lbc; + lcrr_div = in_be32(&lbc->lcrr) & LCRR_CLKDIV; + } +#endif + if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { + sysInfo->freqLocalBus = sysInfo->freqSystemBus / (lcrr_div * 2); + } else { + /* In case anyone cares what the unknown value is */ + sysInfo->freqLocalBus = lcrr_div; + } } @@ -105,6 +123,7 @@ int get_clocks(void) get_sys_info(&sys_info); gd->cpu_clk = sys_info.freqProcessor; gd->bus_clk = sys_info.freqSystemBus; + gd->lbc_clk = sys_info.freqLocalBus; /* * The base clock for I2C depends on the actual SOC. Unfortunately, diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index aade097..2bb50b4 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -89,6 +89,9 @@ typedef struct global_data { #if defined(CONFIG_MPC837X) || defined(CONFIG_MPC8536) u32 sdhc_clk; #endif +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) + u32 lbc_clk; +#endif /* CONFIG_MPC85xx || CONFIG_MPC86xx */ #if defined(CONFIG_MPC83XX) || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) u32 i2c1_clk; u32 i2c2_clk; diff --git a/include/e500.h b/include/e500.h index 1971eee..9d3c841 100644 --- a/include/e500.h +++ b/include/e500.h @@ -13,6 +13,7 @@ typedef struct unsigned long freqProcessor; unsigned long freqSystemBus; unsigned long freqDDRBus; + unsigned long freqLocalBus; } MPC85xx_SYS_INFO; #endif /* _ASMLANGUAGE */ diff --git a/include/mpc86xx.h b/include/mpc86xx.h index f119d5b..a6fdea3 100644 --- a/include/mpc86xx.h +++ b/include/mpc86xx.h @@ -84,6 +84,7 @@ typedef struct { unsigned long freqProcessor; unsigned long freqSystemBus; + unsigned long freqLocalBus; } MPC86xx_SYS_INFO; #define l1icache_enable icache_enable -- cgit v1.1 From fea91edee8ae0295e3c30b1ff544df51f4d668e1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 2 Dec 2008 21:58:04 +0100 Subject: usb_kbd: fix usb_kbd_deregister when DEVICE_DEREGISTER not enable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Remy Böhmer --- common/usb_kbd.c | 4 ++++ include/devices.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/common/usb_kbd.c b/common/usb_kbd.c index cf14560..89e6ee7 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -211,7 +211,11 @@ int drv_usb_kbd_init(void) /* deregistering the keyboard */ int usb_kbd_deregister(void) { +#ifdef CONFIG_SYS_DEVICE_DEREGISTER return device_deregister(DEVNAME); +#else + return 1; +#endif } /************************************************************************** diff --git a/include/devices.h b/include/devices.h index 6b78d58..20ddfc4 100644 --- a/include/devices.h +++ b/include/devices.h @@ -91,7 +91,9 @@ extern char *stdio_names[MAX_FILES]; */ int device_register (device_t * dev); int devices_init (void); +#ifdef CONFIG_SYS_DEVICE_DEREGISTER int device_deregister(char *devname); +#endif struct list_head* device_get_list(void); device_t* device_get_by_name(char* name); device_t* device_clone(device_t *dev); -- cgit v1.1 From 1f03cbfae221b24ba1341a0a3f62ff01c5c874df Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 23 Dec 2008 16:32:00 -0600 Subject: XPedite5200 board support cleanup Signed-off-by: Peter Tyser --- board/xes/common/actl_nand.c | 65 +++++ board/xes/common/fsl_85xx_pci.c | 6 +- board/xes/xpedite5200/Makefile | 55 ++++ board/xes/xpedite5200/config.mk | 34 +++ board/xes/xpedite5200/ddr.c | 91 ++++++ board/xes/xpedite5200/law.c | 51 ++++ board/xes/xpedite5200/tlb.c | 85 ++++++ board/xes/xpedite5200/u-boot.lds | 145 ++++++++++ board/xes/xpedite5200/xpedite5200.c | 125 +++++++++ include/configs/XPEDITE5200.h | 546 ++++++++++++++++++++++++++++++++++++ 10 files changed, 1200 insertions(+), 3 deletions(-) create mode 100644 board/xes/common/actl_nand.c create mode 100644 board/xes/xpedite5200/Makefile create mode 100644 board/xes/xpedite5200/config.mk create mode 100644 board/xes/xpedite5200/ddr.c create mode 100644 board/xes/xpedite5200/law.c create mode 100644 board/xes/xpedite5200/tlb.c create mode 100644 board/xes/xpedite5200/u-boot.lds create mode 100644 board/xes/xpedite5200/xpedite5200.c create mode 100644 include/configs/XPEDITE5200.h diff --git a/board/xes/common/actl_nand.c b/board/xes/common/actl_nand.c new file mode 100644 index 0000000..465aeb0 --- /dev/null +++ b/board/xes/common/actl_nand.c @@ -0,0 +1,65 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * This driver support NAND devices which have address lines + * connected as ALE and CLE inputs. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * Hardware specific access to control-lines + */ +static void nand_addr_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl) +{ + struct nand_chip *this = mtd->priv; + ulong IO_ADDR_W; + + if (ctrl & NAND_CTRL_CHANGE) { + IO_ADDR_W = (ulong)this->IO_ADDR_W; + + IO_ADDR_W &= ~(CONFIG_SYS_NAND_ACTL_CLE | + CONFIG_SYS_NAND_ACTL_ALE | + CONFIG_SYS_NAND_ACTL_NCE); + if (ctrl & NAND_CLE) + IO_ADDR_W |= CONFIG_SYS_NAND_ACTL_CLE; + if (ctrl & NAND_ALE) + IO_ADDR_W |= CONFIG_SYS_NAND_ACTL_ALE; + if (ctrl & NAND_NCE) + IO_ADDR_W |= CONFIG_SYS_NAND_ACTL_NCE; + + this->IO_ADDR_W = (void *)IO_ADDR_W; + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + +int board_nand_init(struct nand_chip *nand) +{ + nand->ecc.mode = NAND_ECC_SOFT; + nand->cmd_ctrl = nand_addr_hwcontrol; + nand->chip_delay = CONFIG_SYS_NAND_ACTL_DELAY; + + return 0; +} diff --git a/board/xes/common/fsl_85xx_pci.c b/board/xes/common/fsl_85xx_pci.c index 56f3447..cd65a73 100644 --- a/board/xes/common/fsl_85xx_pci.c +++ b/board/xes/common/fsl_85xx_pci.c @@ -179,7 +179,7 @@ void pci_init_board(void) fsl_pci_init(hose); - first_free_busno = hose->last_busno+1; + first_free_busno = hose->last_busno + 1; printf(" PCI1 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); } else { @@ -289,7 +289,7 @@ void pci_init_board(void) if (!host) fsl_pci_config_unlock(hose); - first_free_busno = hose->last_busno+1; + first_free_busno = hose->last_busno + 1; printf(" PCIE2 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); } @@ -343,7 +343,7 @@ void pci_init_board(void) if (!host) fsl_pci_config_unlock(hose); - first_free_busno = hose->last_busno+1; + first_free_busno = hose->last_busno + 1; printf(" PCIE3 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); } diff --git a/board/xes/xpedite5200/Makefile b/board/xes/xpedite5200/Makefile new file mode 100644 index 0000000..02fe8fc --- /dev/null +++ b/board/xes/xpedite5200/Makefile @@ -0,0 +1,55 @@ +# +# Copyright 2008 Extreme Engineering Solutions, Inc. +# Copyright 2004 Freescale Semiconductor. +# (C) Copyright 2001-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS-y += $(BOARD).o +COBJS-y += ddr.o +COBJS-y += law.o +COBJS-y += tlb.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(OBJS) $(SOBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/xes/xpedite5200/config.mk b/board/xes/xpedite5200/config.mk new file mode 100644 index 0000000..be5a5c3 --- /dev/null +++ b/board/xes/xpedite5200/config.mk @@ -0,0 +1,34 @@ +# +# Copyright 2008 Extreme Engineering Solutions, Inc. +# Copyright 2004, 2007 Freescale Semiconductor. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program 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. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# xpedite5200 board +# +ifndef TEXT_BASE +TEXT_BASE = 0xfff80000 +endif + +PLATFORM_CPPFLAGS += -DCONFIG_E500=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC85xx=1 +PLATFORM_CPPFLAGS += -DCONFIG_MPC8548=1 +PLATFORM_CPPFLAGS += -mrelocatable diff --git a/board/xes/xpedite5200/ddr.c b/board/xes/xpedite5200/ddr.c new file mode 100644 index 0000000..c5616d5 --- /dev/null +++ b/board/xes/xpedite5200/ddr.c @@ -0,0 +1,91 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +static void +get_spd(ddr2_spd_eeprom_t *spd, unsigned char i2c_address) +{ + i2c_read(i2c_address, 0, 1, (uchar *)spd, sizeof(ddr2_spd_eeprom_t)); + + /* We use soldered memory, but use an SPD EEPROM to describe it. + * The SPD has an unspecified dimm type, but the DDR2 initialization + * code requires a specific type to be specified. This sets the type + * as a standard unregistered SO-DIMM. */ + if (spd->dimm_type == 0) { + spd->dimm_type = 0x4; + ((uchar *)spd)[63] += 0x4; + } +} + +unsigned int fsl_ddr_get_mem_data_rate(void) +{ + return get_ddr_freq(0); +} + +void fsl_ddr_get_spd(ddr2_spd_eeprom_t *ctrl_dimms_spd, + unsigned int ctrl_num) +{ + unsigned int i; + + if (ctrl_num) { + printf("%s: invalid ctrl_num = %d\n", __func__, ctrl_num); + return; + } + + for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) + get_spd(&(ctrl_dimms_spd[i]), SPD_EEPROM_ADDRESS); +} + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + /* + * Factors to consider for clock adjust: + * - number of chips on bus + * - position of slot + * - DDR1 vs. DDR2? + * - ??? + * + * This needs to be determined on a board-by-board basis. + * 0110 3/4 cycle late + * 0111 7/8 cycle late + */ + popts->clk_adjust = 7; + + /* + * Factors to consider for CPO: + * - frequency + * - ddr1 vs. ddr2 + */ + popts->cpo_override = 9; + + /* + * Factors to consider for write data delay: + * - number of DIMMs + * + * 1 = 1/4 clock delay + * 2 = 1/2 clock delay + * 3 = 3/4 clock delay + * 4 = 1 clock delay + * 5 = 5/4 clock delay + * 6 = 3/2 clock delay + */ + popts->write_data_delay = 3; + + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 0; +} diff --git a/board/xes/xpedite5200/law.c b/board/xes/xpedite5200/law.c new file mode 100644 index 0000000..386f9c5 --- /dev/null +++ b/board/xes/xpedite5200/law.c @@ -0,0 +1,51 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +/* + * Notes: + * CCSRBAR and L2-as-SRAM don't need a configured Local Access Window. + * If flash is 8M at default position (last 8M), no LAW needed. + */ + +struct law_entry law_table[] = { + /* LBC window - maps 256M 0xf0000000 -> 0xffffffff */ + SET_LAW(CONFIG_SYS_FLASH_BASE2, LAW_SIZE_256M, LAW_TRGT_IF_LBC), + SET_LAW(CONFIG_SYS_NAND_BASE, LAW_SIZE_1M, LAW_TRGT_IF_LBC), +#if CONFIG_SYS_PCI1_MEM_PHYS + SET_LAW(CONFIG_SYS_PCI1_MEM_PHYS, LAW_SIZE_1G, LAW_TRGT_IF_PCI_1), + SET_LAW(CONFIG_SYS_PCI1_IO_PHYS, LAWAR_SIZE_8M, LAW_TRGT_IF_PCI_1), +#endif +#if CONFIG_SYS_PCI2_MEM_PHYS + SET_LAW(CONFIG_SYS_PCI2_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCI_2), + SET_LAW(CONFIG_SYS_PCI2_IO_PHYS, LAW_SIZE_8M, LAW_TRGT_IF_PCI_2), +#endif +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/xes/xpedite5200/tlb.c b/board/xes/xpedite5200/tlb.c new file mode 100644 index 0000000..bd7bff8 --- /dev/null +++ b/board/xes/xpedite5200/tlb.c @@ -0,0 +1,85 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* W**G* - NOR flashes */ + /* This will be changed to *I*G* after relocation to RAM. */ + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE2, CONFIG_SYS_FLASH_BASE2, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, + 0, 0, BOOKE_PAGESZ_256M, 1), + + SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 1, BOOKE_PAGESZ_1M, 1), + + /* *I*G* - NAND flash */ + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 2, BOOKE_PAGESZ_1M, 1), + +#if CONFIG_PCI1 + /* *I*G* - PCI MEM */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 3, BOOKE_PAGESZ_1G, 1), +#endif + +#if CONFIG_PCI2 + /* *I*G* - PCI MEM */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCI2_MEM_PHYS, CONFIG_SYS_PCI2_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 4, BOOKE_PAGESZ_256M, 1), +#endif + +#if defined(CONFIG_PCI1) || defined(CONFIG_PCI2) + /* *I*G* - PCI IO */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCI1_IO_PHYS, CONFIG_SYS_PCI1_IO_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 5, BOOKE_PAGESZ_16M, 1), +#endif +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/xes/xpedite5200/u-boot.lds b/board/xes/xpedite5200/u-boot.lds new file mode 100644 index 0000000..bd952d2 --- /dev/null +++ b/board/xes/xpedite5200/u-boot.lds @@ -0,0 +1,145 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2004, 2007-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +PHDRS +{ + text PT_LOAD; + bss PT_LOAD; +} + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + *(.text) + *(.got1) + } :text + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } :text + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + .bootpg ADDR(.text) + 0x7f000 : + { + cpu/mpc85xx/start.o (.bootpg) + } :text = 0xffff + + .resetvec ADDR(.text) + 0x7fffc : + { + *(.resetvec) + } :text = 0xffff + + . = ADDR(.text) + 0x80000; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } :bss + + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); +} diff --git a/board/xes/xpedite5200/xpedite5200.c b/board/xes/xpedite5200/xpedite5200.c new file mode 100644 index 0000000..e266d1d --- /dev/null +++ b/board/xes/xpedite5200/xpedite5200.c @@ -0,0 +1,125 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2004, 2007 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void ft_board_pci_setup(void *blob, bd_t *bd); + +int checkboard(void) +{ + volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); + + char *s; + + printf("Board: X-ES %s PMC\n", CONFIG_SYS_BOARD_NAME); + printf(" "); + s = getenv("board_rev"); + if (s) + printf("Rev %s, ", s); + s = getenv("serial#"); + if (s) + printf("Serial# %s, ", s); + s = getenv("board_cfg"); + if (s) + printf("Cfg %s", s); + printf("\n"); + + lbc->ltesr = 0xffffffff; /* Clear LBC error interrupts */ + lbc->lteir = 0xffffffff; /* Enable LBC error interrupts */ + ecm->eedr = 0xffffffff; /* Clear ecm errors */ + ecm->eeer = 0xffffffff; /* Enable ecm errors */ + + return 0; +} + +static void flash_cs_fixup(void) +{ + volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + int flash_sel; + + /* + * Print boot dev and swap flash flash chip selects if booted from 2nd + * flash. Swapping chip selects presents user with a common memory + * map regardless of which flash was booted from. + */ + flash_sel = !((pca953x_get_val(CONFIG_SYS_I2C_PCA953X_ADDR0) & + CONFIG_SYS_PCA953X_FLASH_PASS_CS)); + printf("FLASH: Executed from FLASH%d\n", flash_sel ? 2 : 1); + + if (flash_sel) { + lbc->br0 = CONFIG_SYS_BR1_PRELIM; + lbc->or0 = CONFIG_SYS_OR1_PRELIM; + + lbc->br1 = CONFIG_SYS_BR0_PRELIM; + lbc->or1 = CONFIG_SYS_OR0_PRELIM; + } +} + +int board_early_init_r(void) +{ + /* Initialize PCA9557 devices */ + pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR0, 0xff, 0); + pca953x_set_pol(CONFIG_SYS_I2C_PCA953X_ADDR1, 0xff, 0); + + /* + * Remap NOR flash region to caching-inhibited + * so that flash can be erased/programmed properly. + */ + + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache(); + + /* Invalidate existing TLB entry for NOR flash */ + disable_tlb(0); + set_tlb(1, (CONFIG_SYS_FLASH_BASE2 & 0xf0000000), + (CONFIG_SYS_FLASH_BASE2 & 0xf0000000), + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_256M, 1); + + flash_cs_fixup(); + + return 0; +} + +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ +#ifdef CONFIG_PCI + ft_board_pci_setup(blob, bd); +#endif + ft_cpu_setup(blob, bd); +} +#endif diff --git a/include/configs/XPEDITE5200.h b/include/configs/XPEDITE5200.h new file mode 100644 index 0000000..1df6855 --- /dev/null +++ b/include/configs/XPEDITE5200.h @@ -0,0 +1,546 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * Copyright 2004-2008 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * xpedite5200 board configuration file + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_BOOKE 1 /* BOOKE */ +#define CONFIG_E500 1 /* BOOKE e500 family */ +#define CONFIG_MPC85xx 1 /* MPC8540/60/55/41/48 */ +#define CONFIG_MPC8548 1 +#define CONFIG_XPEDITE5200 1 +#define CONFIG_SYS_BOARD_NAME "XPedite5200" +#define CONFIG_BOARD_EARLY_INIT_R /* Call board_pre_init */ +#define CONFIG_RELOC_FIXUP_WORKS /* Fully relocate to SDRAM */ + +#define CONFIG_PCI 1 /* Enable PCI/PCIE */ +#define CONFIG_PCI_PNP 1 /* do pci plug-and-play */ +#define CONFIG_PCI_SCAN_SHOW 1 /* show pci devices on startup */ +#define CONFIG_PCI1 1 /* PCI controller 1 */ +#define CONFIG_FSL_PCI_INIT 1 /* Use common FSL init code */ +#define CONFIG_SYS_PCI_64BIT 1 /* enable 64-bit PCI resources */ +#define CONFIG_FSL_LAW 1 /* Use common FSL init code */ + +/* + * DDR config + */ +#define CONFIG_FSL_DDR2 +#undef CONFIG_FSL_DDR_INTERACTIVE +#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ +#define CONFIG_DDR_SPD +#define CONFIG_MEM_INIT_VALUE 0xdeadbeef +#define SPD_EEPROM_ADDRESS 0x54 +#define CONFIG_NUM_DDR_CONTROLLERS 1 +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 2 +#define CONFIG_DDR_ECC +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER +#define CONFIG_SYS_DDR_SDRAM_BASE 0x00000000 +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_VERY_BIG_RAM + +#define CONFIG_SYS_CLK_FREQ 66666666 + +/* + * These can be toggled for performance analysis, otherwise use default. + */ +#define CONFIG_L2_CACHE /* toggle L2 cache */ +#define CONFIG_BTB /* toggle branch predition */ +#define CONFIG_ENABLE_36BIT_PHYS 1 + +/* + * Base addresses -- Note these are effective addresses where the + * actual resources get mapped (not physical addresses) + */ +#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ +#define CONFIG_SYS_CCSRBAR 0xef000000 /* relocated CCSRBAR */ +#define CONFIG_SYS_CCSRBAR_PHYS CONFIG_SYS_CCSRBAR /* physical addr of CCSRBAR */ +#define CONFIG_SYS_IMMR CONFIG_SYS_CCSRBAR /* PQII uses CONFIG_SYS_IMMR */ +#define CONFIG_SYS_PCI1_ADDR (CONFIG_SYS_CCSRBAR + 0x8000) + +/* + * Diagnostics + */ +#define CONFIG_SYS_ALT_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x10000000 +#define CONFIG_SYS_MEMTEST_END 0x20000000 + +/* + * Memory map + * 0x0000_0000 0x7fff_ffff DDR 2G Cacheable + * 0x8000_0000 0xbfff_ffff PCI1 Mem 1G non-cacheable + * 0xe000_0000 0xe7ff_ffff SRAM/SSRAM/L1 Cache 128M non-cacheable + * 0xe800_0000 0xe87f_ffff PCI1 IO 8M non-cacheable + * 0xef00_0000 0xef0f_ffff CCSR/IMMR 1M non-cacheable + * 0xef80_0000 0xef8f_ffff NAND Flash 1M non-cacheable + * 0xf800_0000 0xfbff_ffff NOR Flash 2 64M non-cacheable + * 0xfc00_0000 0xffff_ffff NOR Flash 1 64M non-cacheable + */ + +#define CONFIG_SYS_LBC_LCRR (LCRR_CLKDIV_4 | LCRR_EADC_3) + +/* + * NAND flash configuration + */ +#define CONFIG_SYS_NAND_BASE 0xef800000 +#define CONFIG_SYS_NAND_BASE2 0xef840000 /* Unused at this time */ +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_NAND_ACTL +#define CONFIG_SYS_NAND_ACTL_CLE (1 << 3) /* ADDR3 is CLE */ +#define CONFIG_SYS_NAND_ACTL_ALE (1 << 4) /* ADDR4 is ALE */ +#define CONFIG_SYS_NAND_ACTL_NCE (0) /* NCE not controlled by ADDR */ +#define CONFIG_SYS_NAND_ACTL_DELAY 25 + +/* + * NOR flash configuration + */ +#define CONFIG_SYS_FLASH_BASE 0xfc000000 +#define CONFIG_SYS_FLASH_BASE2 0xf8000000 +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE2} +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_AUTOPROTECT_LIST { {0xfff40000, 0xc0000}, \ + {0xfbf40000, 0xc0000} } +#define CONFIG_SYS_MONITOR_BASE TEXT_BASE /* start of monitor */ + +/* + * Chip select configuration + */ +/* NOR Flash 0 on CS0 */ +#define CONFIG_SYS_BR0_PRELIM (CONFIG_SYS_FLASH_BASE | \ + BR_PS_16 | \ + BR_V) +#define CONFIG_SYS_OR0_PRELIM (OR_AM_64MB | \ + OR_GPCM_ACS_DIV4 | \ + OR_GPCM_SCY_8) + +/* NOR Flash 1 on CS1 */ +#define CONFIG_SYS_BR1_PRELIM (CONFIG_SYS_FLASH_BASE2 | \ + BR_PS_16 | \ + BR_V) +#define CONFIG_SYS_OR1_PRELIM CONFIG_SYS_OR0_PRELIM + +/* NAND flash on CS2 */ +#define CONFIG_SYS_BR2_PRELIM (CONFIG_SYS_NAND_BASE | \ + BR_PS_8 | \ + BR_V) + +/* NAND flash on CS2 */ +#define CONFIG_SYS_OR2_PRELIM (OR_AM_256KB | \ + OR_GPCM_BCTLD | \ + OR_GPCM_CSNT | \ + OR_GPCM_ACS_DIV4 | \ + OR_GPCM_SCY_4 | \ + OR_GPCM_TRLX | \ + OR_GPCM_EHTR) + +/* NAND flash on CS3 */ +#define CONFIG_SYS_BR3_PRELIM (CONFIG_SYS_NAND_BASE2 | \ + BR_PS_8 | \ + BR_V) +#define CONFIG_SYS_OR3_PRELIM CONFIG_SYS_OR2_PRELIM + +/* + * Use L1 as initial stack + */ +#define CONFIG_SYS_INIT_RAM_LOCK 1 +#define CONFIG_SYS_INIT_RAM_ADDR 0xe0000000 +#define CONFIG_SYS_INIT_RAM_END 0x4000 + +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* num bytes initial data */ +#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET + +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 KB for Mon */ +#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) /* Reserved for malloc */ + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK get_bus_freq(0) +#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_CCSRBAR+0x4500) +#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_CCSRBAR+0x4600) +#define CONFIG_SYS_BAUDRATE_TABLE \ + {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 115200} +#define CONFIG_BAUDRATE 115200 +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + +/* + * Use the HUSH parser + */ +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " + +/* + * Pass open firmware flat tree + */ +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_OF_BOARD_SETUP 1 +#define CONFIG_OF_STDOUT_VIA_ALIAS 1 + +#define CONFIG_SYS_64BIT_VSPRINTF 1 +#define CONFIG_SYS_64BIT_STRTOUL 1 + +/* + * I2C + */ +#define CONFIG_FSL_I2C /* Use FSL common I2C driver */ +#define CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */ +#define CONFIG_SYS_I2C_SLAVE 0x7F +#define CONFIG_SYS_I2C_OFFSET 0x3000 +#define CONFIG_SYS_I2C2_OFFSET 0x3100 +#define CONFIG_I2C_MULTI_BUS +#define CONFIG_I2C_CMD_TREE + +/* I2C EEPROM */ +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6 /* 64 byte pages */ +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 /* take up to 10 msec */ + +/* I2C RTC */ +#define CONFIG_RTC_M41T11 1 +#define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#define CONFIG_SYS_M41T11_BASE_YEAR 2000 + +/* GPIO */ +#define CONFIG_PCA953X +#define CONFIG_SYS_I2C_PCA953X_ADDR0 0x18 +#define CONFIG_SYS_I2C_PCA953X_ADDR1 0x19 +#define CONFIG_SYS_I2C_PCA953X_ADDR CONFIG_SYS_I2C_PCA953X_ADDR0 + +/* PCA957 @ 0x18 */ +#define CONFIG_SYS_PCA953X_BRD_CFG0 0x01 +#define CONFIG_SYS_PCA953X_BRD_CFG1 0x02 +#define CONFIG_SYS_PCA953X_BRD_CFG2 0x04 +#define CONFIG_SYS_PCA953X_XMC_ROOT0 0x08 +#define CONFIG_SYS_PCA953X_FLASH_PASS_CS 0x10 +#define CONFIG_SYS_PCA953X_FLASH_WP 0x20 +#define CONFIG_SYS_PCA953X_MONARCH 0x40 +#define CONFIG_SYS_PCA953X_EREADY 0x80 + +/* PCA957 @ 0x19 */ +#define CONFIG_SYS_PCA953X_P14_IO0 0x01 +#define CONFIG_SYS_PCA953X_P14_IO1 0x02 +#define CONFIG_SYS_PCA953X_P14_IO2 0x04 +#define CONFIG_SYS_PCA953X_P14_IO3 0x08 +#define CONFIG_SYS_PCA953X_P14_IO4 0x10 +#define CONFIG_SYS_PCA953X_P14_IO5 0x20 +#define CONFIG_SYS_PCA953X_P14_IO6 0x40 +#define CONFIG_SYS_PCA953X_P14_IO7 0x80 + +/* + * General PCI + * Memory space is mapped 1-1, but I/O space must start from 0. + */ +#define CONFIG_SYS_PCI1_MEM_BASE 0x80000000 +#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_BASE +#define CONFIG_SYS_PCI1_MEM_SIZE 0x40000000 /* 1G */ +#define CONFIG_SYS_PCI1_IO_BASE 0x00000000 +#define CONFIG_SYS_PCI1_IO_PHYS 0xe8000000 +#define CONFIG_SYS_PCI1_IO_SIZE 0x00800000 /* 1M */ + +/* + * Networking options + */ +#define CONFIG_TSEC_ENET /* tsec ethernet support */ +#define CONFIG_PHY_GIGE 1 /* Include GbE speed/duplex detection */ +#define CONFIG_NET_MULTI 1 +#define CONFIG_MII 1 /* MII PHY management */ +#define CONFIG_ETHPRIME "eTSEC1" + +#define CONFIG_TSEC1 1 +#define CONFIG_TSEC1_NAME "eTSEC1" +#define TSEC1_FLAGS TSEC_GIGABIT +#define TSEC1_PHY_ADDR 1 +#define TSEC1_PHYIDX 0 +#define CONFIG_HAS_ETH0 + +#define CONFIG_TSEC2 1 +#define CONFIG_TSEC2_NAME "eTSEC2" +#define TSEC2_FLAGS TSEC_GIGABIT +#define TSEC2_PHY_ADDR 2 +#define TSEC2_PHYIDX 0 +#define CONFIG_HAS_ETH1 + +#define CONFIG_TSEC3 1 +#define CONFIG_TSEC3_NAME "eTSEC3" +#define TSEC3_FLAGS TSEC_GIGABIT +#define TSEC3_PHY_ADDR 3 +#define TSEC3_PHYIDX 0 +#define CONFIG_HAS_ETH2 + +#define CONFIG_TSEC4 1 +#define CONFIG_TSEC4_NAME "eTSEC4" +#define TSEC4_FLAGS TSEC_GIGABIT +#define TSEC4_PHY_ADDR 4 +#define TSEC4_PHYIDX 0 +#define CONFIG_HAS_ETH3 + +/* + * BOOTP options + */ +#define CONFIG_BOOTP_BOOTFILESIZE +#define CONFIG_BOOTP_BOOTPATH +#define CONFIG_BOOTP_GATEWAY + +/* + * Command configuration. + */ +#include + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_ELF +#define CONFIG_CMD_ENV +#define CONFIG_CMD_FLASH +#define CONFIG_CMD_I2C +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_MII +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NET +#define CONFIG_CMD_PCA953X +#define CONFIG_CMD_PCA953X_INFO +#define CONFIG_CMD_PCI +#define CONFIG_CMD_PING +#define CONFIG_CMD_SNTP + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_LOAD_ADDR 0x2000000 /* default load address */ +#define CONFIG_SYS_PROMPT "=> " /* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */ +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */ +#define CONFIG_SYS_HZ 1000 /* decrementer freq: 1ms ticks */ +#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ +#define CONFIG_LOADADDR 0x1000000 /* default location for tftp and bootm */ +#define CONFIG_BOOTDELAY 3 /* -1 disables auto-boot */ +#define CONFIG_PANIC_HANG /* do not reset board on panic */ +#define CONFIG_PREBOOT /* enable preboot variable */ +#define CONFIG_FIT 1 +#define CONFIG_FIT_VERBOSE 1 +#define CONFIG_INTEGRITY /* support booting INTEGRITY OS */ +#define CONFIG_INTERRUPTS /* enable pci, srio, ddr interrupts */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 16 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CONFIG_SYS_BOOTMAPSZ (16 << 20) /* Initial Memory map for Linux*/ + +/* + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +/* + * Environment Configuration + */ +#define CONFIG_ENV_IS_IN_FLASH 1 +#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128k (one sector) for env */ +#define CONFIG_ENV_SIZE 0x8000 +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - (256 * 1024)) + +/* + * Flash memory map: + * fff80000 - ffffffff Pri U-Boot (512 KB) + * fff40000 - fff7ffff Pri U-Boot Environment (256 KB) + * fff00000 - fff3ffff Pri FDT (256KB) + * fef00000 - ffefffff Pri OS image (16MB) + * fc000000 - feefffff Pri OS Use/Filesystem (47MB) + * + * fbf80000 - fbffffff Sec U-Boot (512 KB) + * fbf40000 - fbf7ffff Sec U-Boot Environment (256 KB) + * fbf00000 - fbf3ffff Sec FDT (256KB) + * faf00000 - fbefffff Sec OS image (16MB) + * f8000000 - faefffff Sec OS Use/Filesystem (47MB) + */ +#define CONFIG_UBOOT1_ENV_ADDR MK_STR(0xfff80000) +#define CONFIG_UBOOT2_ENV_ADDR MK_STR(0xfbf80000) +#define CONFIG_FDT1_ENV_ADDR MK_STR(0xfff00000) +#define CONFIG_FDT2_ENV_ADDR MK_STR(0xfbf00000) +#define CONFIG_OS1_ENV_ADDR MK_STR(0xfef00000) +#define CONFIG_OS2_ENV_ADDR MK_STR(0xfaf00000) + +#define CONFIG_PROG_UBOOT1 \ + "$download_cmd $loadaddr $ubootfile; " \ + "if test $? -eq 0; then " \ + "protect off "CONFIG_UBOOT1_ENV_ADDR" +80000; " \ + "erase "CONFIG_UBOOT1_ENV_ADDR" +80000; " \ + "cp.w $loadaddr "CONFIG_UBOOT1_ENV_ADDR" 40000; " \ + "protect on "CONFIG_UBOOT1_ENV_ADDR" +80000; " \ + "cmp.b $loadaddr "CONFIG_UBOOT1_ENV_ADDR" 80000; " \ + "if test $? -ne 0; then " \ + "echo PROGRAM FAILED; " \ + "else; " \ + "echo PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_UBOOT2 \ + "$download_cmd $loadaddr $ubootfile; " \ + "if test $? -eq 0; then " \ + "protect off "CONFIG_UBOOT2_ENV_ADDR" +80000; " \ + "erase "CONFIG_UBOOT2_ENV_ADDR" +80000; " \ + "cp.w $loadaddr "CONFIG_UBOOT2_ENV_ADDR" 40000; " \ + "protect on "CONFIG_UBOOT2_ENV_ADDR" +80000; " \ + "cmp.b $loadaddr "CONFIG_UBOOT2_ENV_ADDR" 80000; " \ + "if test $? -ne 0; then " \ + "echo PROGRAM FAILED; " \ + "else; " \ + "echo PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_BOOT_OS_NET \ + "$download_cmd $osaddr $osfile; " \ + "if test $? -eq 0; then " \ + "if test -n $fdtaddr; then " \ + "$download_cmd $fdtaddr $fdtfile; " \ + "if test $? -eq 0; then " \ + "bootm $osaddr - $fdtaddr; " \ + "else; " \ + "echo FDT DOWNLOAD FAILED; " \ + "fi; " \ + "else; " \ + "bootm $osaddr; " \ + "fi; " \ + "else; " \ + "echo OS DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_OS1 \ + "$download_cmd $osaddr $osfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_OS1_ENV_ADDR" +$filesize; " \ + "cp.b $osaddr "CONFIG_OS1_ENV_ADDR" $filesize; " \ + "cmp.b $osaddr "CONFIG_OS1_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo OS PROGRAM FAILED; " \ + "else; " \ + "echo OS PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo OS DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_OS2 \ + "$download_cmd $osaddr $osfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_OS2_ENV_ADDR" +$filesize; " \ + "cp.b $osaddr "CONFIG_OS2_ENV_ADDR" $filesize; " \ + "cmp.b $osaddr "CONFIG_OS2_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo OS PROGRAM FAILED; " \ + "else; " \ + "echo OS PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo OS DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_FDT1 \ + "$download_cmd $fdtaddr $fdtfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_FDT1_ENV_ADDR" +$filesize;" \ + "cp.b $fdtaddr "CONFIG_FDT1_ENV_ADDR" $filesize; " \ + "cmp.b $fdtaddr "CONFIG_FDT1_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo FDT PROGRAM FAILED; " \ + "else; " \ + "echo FDT PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo FDT DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_PROG_FDT2 \ + "$download_cmd $fdtaddr $fdtfile; " \ + "if test $? -eq 0; then " \ + "erase "CONFIG_FDT2_ENV_ADDR" +$filesize;" \ + "cp.b $fdtaddr "CONFIG_FDT2_ENV_ADDR" $filesize; " \ + "cmp.b $fdtaddr "CONFIG_FDT2_ENV_ADDR" $filesize; " \ + "if test $? -ne 0; then " \ + "echo FDT PROGRAM FAILED; " \ + "else; " \ + "echo FDT PROGRAM SUCCEEDED; " \ + "fi; " \ + "else; " \ + "echo FDT DOWNLOAD FAILED; " \ + "fi;" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "autoload=yes\0" \ + "download_cmd=tftp\0" \ + "console_args=console=ttyS0,115200\0" \ + "root_args=root=/dev/nfs rw\0" \ + "misc_args=ip=on\0" \ + "set_bootargs=setenv bootargs ${console_args} ${root_args} ${misc_args}\0" \ + "bootfile=/home/user/file\0" \ + "osfile=/home/user/uImage-XPedite5200\0" \ + "fdtfile=/home/user/xpedite5200.dtb\0" \ + "ubootfile=/home/user/u-boot.bin\0" \ + "fdtaddr=c00000\0" \ + "osaddr=0x1000000\0" \ + "loadaddr=0x1000000\0" \ + "prog_uboot1="CONFIG_PROG_UBOOT1"\0" \ + "prog_uboot2="CONFIG_PROG_UBOOT2"\0" \ + "prog_os1="CONFIG_PROG_OS1"\0" \ + "prog_os2="CONFIG_PROG_OS2"\0" \ + "prog_fdt1="CONFIG_PROG_FDT1"\0" \ + "prog_fdt2="CONFIG_PROG_FDT2"\0" \ + "bootcmd_net=run set_bootargs; "CONFIG_BOOT_OS_NET"\0" \ + "bootcmd_flash1=run set_bootargs; " \ + "bootm "CONFIG_OS1_ENV_ADDR" - "CONFIG_FDT1_ENV_ADDR"\0"\ + "bootcmd_flash2=run set_bootargs; " \ + "bootm "CONFIG_OS2_ENV_ADDR" - "CONFIG_FDT2_ENV_ADDR"\0"\ + "bootcmd=run bootcmd_flash1\0" +#endif /* __CONFIG_H */ -- cgit v1.1 From d9011f9b75561a0bd9254934c2bb2bc799d4f645 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 23 Dec 2008 16:32:01 -0600 Subject: 85xx: Enable inbound PCI config cycles for X-ES boards cleanup Signed-off-by: Peter Tyser --- board/xes/common/fsl_85xx_pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/board/xes/common/fsl_85xx_pci.c b/board/xes/common/fsl_85xx_pci.c index cd65a73..9673a02 100644 --- a/board/xes/common/fsl_85xx_pci.c +++ b/board/xes/common/fsl_85xx_pci.c @@ -179,6 +179,10 @@ void pci_init_board(void) fsl_pci_init(hose); + /* Unlock inbound PCI configuration cycles */ + if (!host) + fsl_pci_config_unlock(hose); + first_free_busno = hose->last_busno + 1; printf(" PCI1 on bus %02x - %02x\n", hose->first_busno, hose->last_busno); -- cgit v1.1 From 0668236bafaa1c11c521652a2facebc74beecbf0 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 30 Dec 2008 22:56:11 +0100 Subject: README: update mailing list name and hits to patch submission. Signed-off-by: Wolfgang Denk --- README | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README b/README index 2a553c2..3674ca1 100644 --- a/README +++ b/README @@ -3731,7 +3731,7 @@ MPC826x processors), on others (parts of) the data cache can be locked as (mis-) used as memory, etc. Chris Hallinan posted a good summary of these issues to the - u-boot-users mailing list: + U-Boot mailing list: Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)? From: "Chris Hallinan" @@ -3941,7 +3941,7 @@ int main (int argc, char *argv[]) Download latest U-Boot source; - Subscribe to u-boot-users mailing list; + Subscribe to u-boot mailing list; if (clueless) { email ("Hi, I am new to U-Boot, how do I get started?"); @@ -4018,10 +4018,11 @@ Since the number of patches for U-Boot is growing, we need to establish some rules. Submissions which do not conform to these rules may be rejected, even when they contain important and valuable stuff. -Patches shall be sent to the u-boot-users mailing list. - Please see http://www.denx.de/wiki/U-Boot/Patches for details. +Patches shall be sent to the u-boot mailing list ; +see http://lists.denx.de/mailman/listinfo/u-boot + When you send a patch, please include the following information with it: @@ -4084,7 +4085,7 @@ Notes: disabled must not need more memory than the old code without your modification. -* Remember that there is a size limit of 40 kB per message on the - u-boot-users mailing list. Bigger patches will be moderated. If - they are reasonable and not bigger than 100 kB, they will be - acknowledged. Even bigger patches should be avoided. +* Remember that there is a size limit of 100 kB per message on the + u-boot mailing list. Bigger patches will be moderated. If they are + reasonable and not too big, they will be acknowledged. But patches + bigger than the size limit should be avoided. -- cgit v1.1 From e12d9a8fb48d24176efffccc072b445e60a3afe4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 3 Jan 2009 17:22:24 +0100 Subject: at91: Fix Atmel's at91sam9 boards out of tree build introduced in commit 89a7a87f084c Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index c532e5b..0f8b520 100644 --- a/Makefile +++ b/Makefile @@ -2602,6 +2602,7 @@ at91sam9260ek_nandflash_config \ at91sam9260ek_dataflash_cs0_config \ at91sam9260ek_dataflash_cs1_config \ at91sam9260ek_config : unconfig + @mkdir -p $(obj)include @if [ "$(findstring _nandflash,$@)" ] ; then \ echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ $(XECHO) "... with environment variable in NAND FLASH" ; \ @@ -2618,6 +2619,7 @@ at91sam9261ek_nandflash_config \ at91sam9261ek_dataflash_cs0_config \ at91sam9261ek_dataflash_cs3_config \ at91sam9261ek_config : unconfig + @mkdir -p $(obj)include @if [ "$(findstring _nandflash,$@)" ] ; then \ echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ $(XECHO) "... with environment variable in NAND FLASH" ; \ @@ -2634,6 +2636,7 @@ at91sam9263ek_nandflash_config \ at91sam9263ek_dataflash_config \ at91sam9263ek_dataflash_cs0_config \ at91sam9263ek_config : unconfig + @mkdir -p $(obj)include @if [ "$(findstring _nandflash,$@)" ] ; then \ echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ $(XECHO) "... with environment variable in NAND FLASH" ; \ @@ -2647,6 +2650,7 @@ at91sam9rlek_nandflash_config \ at91sam9rlek_dataflash_config \ at91sam9rlek_dataflash_cs0_config \ at91sam9rlek_config : unconfig + @mkdir -p $(obj)include @if [ "$(findstring _nandflash,$@)" ] ; then \ echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ $(XECHO) "... with environment variable in NAND FLASH" ; \ -- cgit v1.1 From 9ffd53db870a7da134f9a1ae76894a6b31237be5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 6 Jan 2009 21:15:57 +0100 Subject: fix bmp_logo.h make dependencies to allow parallel build Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0f8b520..74b1854 100644 --- a/Makefile +++ b/Makefile @@ -348,7 +348,7 @@ $(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(OBJS): depend $(obj)include/autoconf.mk $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@)) -$(LIBS): depend $(obj)include/autoconf.mk +$(LIBS): depend $(obj)include/autoconf.mk $(SUBDIRS) $(MAKE) -C $(dir $(subst $(obj),,$@)) $(LIBBOARD): depend $(LIBS) $(obj)include/autoconf.mk -- cgit v1.1 From 4e170b16625291aa10d0d9abc3f34e8a5945d157 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 6 Jan 2009 21:13:14 +0100 Subject: at91: add at91sam9xeek board support At91sam9xe is basically an at91sam9260 with embedded flash. We can manage it as another entry for at91sam9260 in the Makefile. Check documentation at : http://www.atmel.com/dyn/products/product_card.asp?part_id=4263 Signed-off-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- Makefile | 17 +++++++++++++++++ doc/README.at91 | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 74b1854..ecde92b 100644 --- a/Makefile +++ b/Makefile @@ -2615,6 +2615,23 @@ at91sam9260ek_config : unconfig fi; @$(MKCONFIG) -a at91sam9260ek arm arm926ejs at91sam9260ek atmel at91 +at91sam9xeek_nandflash_config \ +at91sam9xeek_dataflash_cs0_config \ +at91sam9xeek_dataflash_cs1_config \ +at91sam9xeek_config : unconfig + @mkdir -p $(obj)include + @if [ "$(findstring _nandflash,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in NAND FLASH" ; \ + elif [ "$(findstring dataflash_cs0,$@)" ] ; then \ + echo "#define CONFIG_SYS_USE_DATAFLASH_CS0 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \ + else \ + echo "#define CONFIG_SYS_USE_DATAFLASH_CS1 1" >>$(obj)include/config.h ; \ + $(XECHO) "... with environment variable in SPI DATAFLASH CS1" ; \ + fi; + @$(MKCONFIG) -n at91sam9xeek -a at91sam9260ek arm arm926ejs at91sam9260ek atmel at91sam9 + at91sam9261ek_nandflash_config \ at91sam9261ek_dataflash_cs0_config \ at91sam9261ek_dataflash_cs3_config \ diff --git a/doc/README.at91 b/doc/README.at91 index 838769a..4e3928a 100644 --- a/doc/README.at91 +++ b/doc/README.at91 @@ -3,7 +3,7 @@ Atmel AT91 Evaluation kits http://atmel.com/dyn/products/tools.asp?family_id=605#1443 ------------------------------------------------------------------------------ -AT91SAM9260EK +AT91SAM9260EK & AT91SAM9XEEK ------------------------------------------------------------------------------ Memory map -- cgit v1.1 From d481c80d78f954133c035dae6c7d22de3625795d Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 3 Jan 2009 17:22:25 +0100 Subject: at91rm9200: rename lowlevel init value to CONFIG_SYS_ Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- board/m501sk/memsetup.S | 134 ++++++++++++++++----------------- cpu/arm920t/at91rm9200/lowlevel_init.S | 88 +++++++++++----------- include/configs/at91rm9200dk.h | 46 +++++------ include/configs/cmc_pu2.h | 46 +++++------ include/configs/csb637.h | 46 +++++------ include/configs/mp2usb.h | 46 +++++------ 6 files changed, 203 insertions(+), 203 deletions(-) diff --git a/board/m501sk/memsetup.S b/board/m501sk/memsetup.S index 6aea723..1a3ca4b 100644 --- a/board/m501sk/memsetup.S +++ b/board/m501sk/memsetup.S @@ -41,50 +41,50 @@ /* flash */ #define MC_PUIA 0xFFFFFF10 -#define MC_PUIA_VAL 0x00000000 +#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 #define MC_PUP 0xFFFFFF50 -#define MC_PUP_VAL 0x00000000 +#define CONFIG_SYS_MC_PUP_VAL 0x00000000 #define MC_PUER 0xFFFFFF54 -#define MC_PUER_VAL 0x00000000 +#define CONFIG_SYS_MC_PUER_VAL 0x00000000 #define MC_ASR 0xFFFFFF04 -#define MC_ASR_VAL 0x00000000 +#define CONFIG_SYS_MC_ASR_VAL 0x00000000 #define MC_AASR 0xFFFFFF08 -#define MC_AASR_VAL 0x00000000 +#define CONFIG_SYS_MC_AASR_VAL 0x00000000 #define EBI_CFGR 0xFFFFFF64 -#define EBI_CFGR_VAL 0x00000000 +#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 #define SMC_CSR0 0xFFFFFF70 -#define SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ +#define CONFIG_SYS_SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ /* clocks */ #define PLLAR 0xFFFFFC28 -#define PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ +#define CONFIG_SYS_PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ #define PLLBR 0xFFFFFC2C -#define PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ +#define CONFIG_SYS_PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ #define MCKR 0xFFFFFC30 /* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */ -#define MCKR_VAL 0x00000202 +#define CONFIG_SYS_MCKR_VAL 0x00000202 /* sdram */ #define PIOC_ASR 0xFFFFF870 -#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as Perip (D16/D31) */ +#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as Perip (D16/D31) */ #define PIOC_BSR 0xFFFFF874 -#define PIOC_BSR_VAL 0x00000000 +#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 #define PIOC_PDR 0xFFFFF804 -#define PIOC_PDR_VAL 0xFFFF0000 +#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 #define EBI_CSA 0xFFFFFF60 -#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ +#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ #define SDRC_CR 0xFFFFFF98 -#define SDRC_CR_VAL 0x2188c155 /* set up the SDRAM */ -#define SDRAM 0x20000000 /* address of the SDRAM */ -#define SDRAM1 0x20000080 /* address of the SDRAM */ -#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ +#define CONFIG_SYS_SDRC_CR_VAL 0x2188c155 /* set up the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM1 0x20000080 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ #define SDRC_MR 0xFFFFFF90 -#define SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define SDRC_MR_VAL1 0x00000004 /* refresh */ -#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ +#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ +#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ +#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ +#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ #define SDRC_TR 0xFFFFFF94 -#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ _TEXT_BASE: .word TEXT_BASE @@ -130,71 +130,71 @@ lowlevelinit: SMRDATA: .word MC_PUIA - .word MC_PUIA_VAL + .word CONFIG_SYS_MC_PUIA_VAL .word MC_PUP - .word MC_PUP_VAL + .word CONFIG_SYS_MC_PUP_VAL .word MC_PUER - .word MC_PUER_VAL + .word CONFIG_SYS_MC_PUER_VAL .word MC_ASR - .word MC_ASR_VAL + .word CONFIG_SYS_MC_ASR_VAL .word MC_AASR - .word MC_AASR_VAL + .word CONFIG_SYS_MC_AASR_VAL .word EBI_CFGR - .word EBI_CFGR_VAL + .word CONFIG_SYS_EBI_CFGR_VAL .word SMC_CSR0 - .word SMC_CSR0_VAL + .word CONFIG_SYS_SMC_CSR0_VAL .word PLLAR - .word PLLAR_VAL + .word CONFIG_SYS_PLLAR_VAL .word PLLBR - .word PLLBR_VAL + .word CONFIG_SYS_PLLBR_VAL .word MCKR - .word MCKR_VAL + .word CONFIG_SYS_MCKR_VAL /* SMRDATA is 80 bytes long */ /* here there's a delay of 100 */ SMRDATA1: .word PIOC_ASR - .word PIOC_ASR_VAL + .word CONFIG_SYS_PIOC_ASR_VAL .word PIOC_BSR - .word PIOC_BSR_VAL + .word CONFIG_SYS_PIOC_BSR_VAL .word PIOC_PDR - .word PIOC_PDR_VAL + .word CONFIG_SYS_PIOC_PDR_VAL .word EBI_CSA - .word EBI_CSA_VAL + .word CONFIG_SYS_EBI_CSA_VAL .word SDRC_CR - .word SDRC_CR_VAL + .word CONFIG_SYS_SDRC_CR_VAL .word SDRC_MR - .word SDRC_MR_VAL - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL .word SDRC_MR - .word SDRC_MR_VAL1 - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL1 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL .word SDRC_MR - .word SDRC_MR_VAL2 - .word SDRAM1 - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM1 + .word CONFIG_SYS_SDRAM_VAL .word SDRC_TR - .word SDRC_TR_VAL - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_TR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL .word SDRC_MR - .word SDRC_MR_VAL3 - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL /* SMRDATA1 is 176 bytes long */ #endif /* CONFIG_BOOTBINFUNC */ diff --git a/cpu/arm920t/at91rm9200/lowlevel_init.S b/cpu/arm920t/at91rm9200/lowlevel_init.S index 66b07da..736f1ea 100644 --- a/cpu/arm920t/at91rm9200/lowlevel_init.S +++ b/cpu/arm920t/at91rm9200/lowlevel_init.S @@ -135,71 +135,71 @@ LoopOsc: SMRDATA: .word MC_PUIA - .word MC_PUIA_VAL + .word CONFIG_SYS_MC_PUIA_VAL .word MC_PUP - .word MC_PUP_VAL + .word CONFIG_SYS_MC_PUP_VAL .word MC_PUER - .word MC_PUER_VAL + .word CONFIG_SYS_MC_PUER_VAL .word MC_ASR - .word MC_ASR_VAL + .word CONFIG_SYS_MC_ASR_VAL .word MC_AASR - .word MC_AASR_VAL + .word CONFIG_SYS_MC_AASR_VAL .word EBI_CFGR - .word EBI_CFGR_VAL + .word CONFIG_SYS_EBI_CFGR_VAL .word SMC_CSR0 - .word SMC_CSR0_VAL + .word CONFIG_SYS_SMC_CSR0_VAL .word PLLAR - .word PLLAR_VAL + .word CONFIG_SYS_PLLAR_VAL .word PLLBR - .word PLLBR_VAL + .word CONFIG_SYS_PLLBR_VAL .word MCKR - .word MCKR_VAL + .word CONFIG_SYS_MCKR_VAL /* SMRDATA is 80 bytes long */ /* here there's a delay of 100 */ SMRDATA1: .word PIOC_ASR - .word PIOC_ASR_VAL + .word CONFIG_SYS_PIOC_ASR_VAL .word PIOC_BSR - .word PIOC_BSR_VAL + .word CONFIG_SYS_PIOC_BSR_VAL .word PIOC_PDR - .word PIOC_PDR_VAL + .word CONFIG_SYS_PIOC_PDR_VAL .word EBI_CSA - .word EBI_CSA_VAL + .word CONFIG_SYS_EBI_CSA_VAL .word SDRC_CR - .word SDRC_CR_VAL + .word CONFIG_SYS_SDRC_CR_VAL .word SDRC_MR - .word SDRC_MR_VAL - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL .word SDRC_MR - .word SDRC_MR_VAL1 - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL1 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL .word SDRC_MR - .word SDRC_MR_VAL2 - .word SDRAM1 - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL2 + .word CONFIG_SYS_SDRAM1 + .word CONFIG_SYS_SDRAM_VAL .word SDRC_TR - .word SDRC_TR_VAL - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_TR_VAL + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL .word SDRC_MR - .word SDRC_MR_VAL3 - .word SDRAM - .word SDRAM_VAL + .word CONFIG_SYS_SDRC_MR_VAL3 + .word CONFIG_SYS_SDRAM + .word CONFIG_SYS_SDRAM_VAL /* SMRDATA1 is 176 bytes long */ #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/include/configs/at91rm9200dk.h b/include/configs/at91rm9200dk.h index 746f0ef..c7e83cc 100644 --- a/include/configs/at91rm9200dk.h +++ b/include/configs/at91rm9200dk.h @@ -45,33 +45,33 @@ #ifndef CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SYS_USE_MAIN_OSCILLATOR 1 /* flash */ -#define MC_PUIA_VAL 0x00000000 -#define MC_PUP_VAL 0x00000000 -#define MC_PUER_VAL 0x00000000 -#define MC_ASR_VAL 0x00000000 -#define MC_AASR_VAL 0x00000000 -#define EBI_CFGR_VAL 0x00000000 -#define SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ +#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 +#define CONFIG_SYS_MC_PUP_VAL 0x00000000 +#define CONFIG_SYS_MC_PUER_VAL 0x00000000 +#define CONFIG_SYS_MC_ASR_VAL 0x00000000 +#define CONFIG_SYS_MC_AASR_VAL 0x00000000 +#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 +#define CONFIG_SYS_SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ /* clocks */ -#define PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ -#define PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ -#define MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */ +#define CONFIG_SYS_PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ +#define CONFIG_SYS_PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ +#define CONFIG_SYS_MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */ /* sdram */ -#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ -#define PIOC_BSR_VAL 0x00000000 -#define PIOC_PDR_VAL 0xFFFF0000 -#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ -#define SDRC_CR_VAL 0x2188c155 /* set up the SDRAM */ -#define SDRAM 0x20000000 /* address of the SDRAM */ -#define SDRAM1 0x20000080 /* address of the SDRAM */ -#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ -#define SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define SDRC_MR_VAL1 0x00000004 /* refresh */ -#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ -#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ +#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 +#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 +#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_CR_VAL 0x2188c155 /* set up the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM1 0x20000080 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ +#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ +#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ +#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ +#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ #else #define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/include/configs/cmc_pu2.h b/include/configs/cmc_pu2.h index cdd308d..d9acb47 100644 --- a/include/configs/cmc_pu2.h +++ b/include/configs/cmc_pu2.h @@ -44,33 +44,33 @@ #ifndef CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SYS_USE_MAIN_OSCILLATOR 1 /* flash */ -#define MC_PUIA_VAL 0x00000000 -#define MC_PUP_VAL 0x00000000 -#define MC_PUER_VAL 0x00000000 -#define MC_ASR_VAL 0x00000000 -#define MC_AASR_VAL 0x00000000 -#define EBI_CFGR_VAL 0x00000000 -#define SMC_CSR0_VAL 0x100032ad /* 16bit, 2 TDF, 4 WS */ +#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 +#define CONFIG_SYS_MC_PUP_VAL 0x00000000 +#define CONFIG_SYS_MC_PUER_VAL 0x00000000 +#define CONFIG_SYS_MC_ASR_VAL 0x00000000 +#define CONFIG_SYS_MC_AASR_VAL 0x00000000 +#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 +#define CONFIG_SYS_SMC_CSR0_VAL 0x100032ad /* 16bit, 2 TDF, 4 WS */ /* clocks */ -#define PLLAR_VAL 0x2026BE04 /* 179,712 MHz for PCK */ -#define PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ -#define MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 69.120MHz from PLLA */ +#define CONFIG_SYS_PLLAR_VAL 0x2026BE04 /* 179,712 MHz for PCK */ +#define CONFIG_SYS_PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ +#define CONFIG_SYS_MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 69.120MHz from PLLA */ /* sdram */ -#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ -#define PIOC_BSR_VAL 0x00000000 -#define PIOC_PDR_VAL 0xFFFF0000 -#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ -#define SDRC_CR_VAL 0x3399c1d4 /* set up the SDRAM */ -#define SDRAM 0x20000000 /* address of the SDRAM */ -#define SDRAM1 0x20000080 /* address of the SDRAM */ -#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ -#define SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define SDRC_MR_VAL1 0x00000004 /* refresh */ -#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ -#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ +#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 +#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 +#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_CR_VAL 0x3399c1d4 /* set up the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM1 0x20000080 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ +#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ +#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ +#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ +#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ #else #define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/include/configs/csb637.h b/include/configs/csb637.h index 682db44..2df77cf 100644 --- a/include/configs/csb637.h +++ b/include/configs/csb637.h @@ -45,33 +45,33 @@ #ifndef CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SYS_USE_MAIN_OSCILLATOR 1 /* flash */ -#define MC_PUIA_VAL 0x00000000 -#define MC_PUP_VAL 0x00000000 -#define MC_PUER_VAL 0x00000000 -#define MC_ASR_VAL 0x00000000 -#define MC_AASR_VAL 0x00000000 -#define EBI_CFGR_VAL 0x00000000 -#define SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ +#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 +#define CONFIG_SYS_MC_PUP_VAL 0x00000000 +#define CONFIG_SYS_MC_PUER_VAL 0x00000000 +#define CONFIG_SYS_MC_ASR_VAL 0x00000000 +#define CONFIG_SYS_MC_AASR_VAL 0x00000000 +#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 +#define CONFIG_SYS_SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ /* clocks */ -#define PLLAR_VAL 0x2031BE01 /* 184.320000 MHz for PCK */ -#define PLLBR_VAL 0x128A3E19 /* 47.996928 MHz (divider by 2 for USB) */ -#define MCKR_VAL 0x00000302 /* PCK/4 = MCK Master Clock = 46.080000 MHz from PLLA */ +#define CONFIG_SYS_PLLAR_VAL 0x2031BE01 /* 184.320000 MHz for PCK */ +#define CONFIG_SYS_PLLBR_VAL 0x128A3E19 /* 47.996928 MHz (divider by 2 for USB) */ +#define CONFIG_SYS_MCKR_VAL 0x00000302 /* PCK/4 = MCK Master Clock = 46.080000 MHz from PLLA */ /* sdram */ -#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ -#define PIOC_BSR_VAL 0x00000000 -#define PIOC_PDR_VAL 0xFFFF0000 -#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ -#define SDRC_CR_VAL 0x21914159 /* set up the SDRAM */ -#define SDRAM 0x20000000 /* address of the SDRAM */ -#define SDRAM1 0x20000080 /* address of the SDRAM */ -#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ -#define SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define SDRC_MR_VAL1 0x00000004 /* refresh */ -#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ -#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ +#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 +#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 +#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_CR_VAL 0x21914159 /* set up the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM1 0x20000080 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ +#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ +#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ +#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ +#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ #else #define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ diff --git a/include/configs/mp2usb.h b/include/configs/mp2usb.h index cbbdb0c..fb10616 100644 --- a/include/configs/mp2usb.h +++ b/include/configs/mp2usb.h @@ -49,33 +49,33 @@ #ifndef CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SYS_USE_MAIN_OSCILLATOR 1 /* flash */ -#define MC_PUIA_VAL 0x00000000 -#define MC_PUP_VAL 0x00000000 -#define MC_PUER_VAL 0x00000000 -#define MC_ASR_VAL 0x00000000 -#define MC_AASR_VAL 0x00000000 -#define EBI_CFGR_VAL 0x00000000 -#define SMC_CSR0_VAL 0x00003084 /* 16bit, 2 TDF, 4 WS */ +#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 +#define CONFIG_SYS_MC_PUP_VAL 0x00000000 +#define CONFIG_SYS_MC_PUER_VAL 0x00000000 +#define CONFIG_SYS_MC_ASR_VAL 0x00000000 +#define CONFIG_SYS_MC_AASR_VAL 0x00000000 +#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 +#define CONFIG_SYS_SMC_CSR0_VAL 0x00003084 /* 16bit, 2 TDF, 4 WS */ /* clocks */ -#define PLLAR_VAL 0x20263E04 /* 180 MHz for PCK */ -#define PLLBR_VAL 0x1048bE0E /* 48 MHz (divider by 2 for USB) */ -#define MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 60MHz from PLLA */ +#define CONFIG_SYS_PLLAR_VAL 0x20263E04 /* 180 MHz for PCK */ +#define CONFIG_SYS_PLLBR_VAL 0x1048bE0E /* 48 MHz (divider by 2 for USB) */ +#define CONFIG_SYS_MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 60MHz from PLLA */ /* sdram */ -#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ -#define PIOC_BSR_VAL 0x00000000 -#define PIOC_PDR_VAL 0xFFFF0000 -#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */ -#define SDRC_CR_VAL 0x3211295A /* set up the SDRAM */ -#define SDRAM 0x20000000 /* address of the SDRAM */ -#define SDRAM1 0x20000020 /* address of the SDRAM */ -#define SDRAM_VAL 0x00000000 /* value written to SDRAM */ -#define SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define SDRC_MR_VAL1 0x00000004 /* refresh */ -#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */ -#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ +#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ +#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 +#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 +#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_CR_VAL 0x3211295A /* set up the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM1 0x20000020 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ +#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ +#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ +#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ +#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ #else #define CONFIG_SKIP_RELOCATE_UBOOT #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ -- cgit v1.1 From 8a48686fac2030287765f1970ea046bd5734b733 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 3 Jan 2009 17:22:26 +0100 Subject: m501sk: move to the common memory setup Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- board/m501sk/Makefile | 2 - board/m501sk/memsetup.S | 200 ----------------------------------------------- include/configs/m501sk.h | 33 ++++++++ 3 files changed, 33 insertions(+), 202 deletions(-) delete mode 100644 board/m501sk/memsetup.S diff --git a/board/m501sk/Makefile b/board/m501sk/Makefile index c562c60..aec3d1c 100644 --- a/board/m501sk/Makefile +++ b/board/m501sk/Makefile @@ -27,8 +27,6 @@ LIB = $(obj)lib$(BOARD).a COBJS := m501sk.o eeprom.o -SOBJS := memsetup.o - SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) diff --git a/board/m501sk/memsetup.S b/board/m501sk/memsetup.S deleted file mode 100644 index 1a3ca4b..0000000 --- a/board/m501sk/memsetup.S +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Memory Setup stuff - taken from blob memsetup.S - * - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and - * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) - * - * Modified for the at91rm9200dk board by - * (C) Copyright 2004 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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. - * - * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#ifdef CONFIG_BOOTBINFUNC -/* - * some parameters for the board - * - * This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in - * turn is based on the boot.bin code from ATMEL - * - */ - -/* flash */ -#define MC_PUIA 0xFFFFFF10 -#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 -#define MC_PUP 0xFFFFFF50 -#define CONFIG_SYS_MC_PUP_VAL 0x00000000 -#define MC_PUER 0xFFFFFF54 -#define CONFIG_SYS_MC_PUER_VAL 0x00000000 -#define MC_ASR 0xFFFFFF04 -#define CONFIG_SYS_MC_ASR_VAL 0x00000000 -#define MC_AASR 0xFFFFFF08 -#define CONFIG_SYS_MC_AASR_VAL 0x00000000 -#define EBI_CFGR 0xFFFFFF64 -#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 -#define SMC_CSR0 0xFFFFFF70 -#define CONFIG_SYS_SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ - -/* clocks */ -#define PLLAR 0xFFFFFC28 -#define CONFIG_SYS_PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ -#define PLLBR 0xFFFFFC2C -#define CONFIG_SYS_PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ -#define MCKR 0xFFFFFC30 -/* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */ -#define CONFIG_SYS_MCKR_VAL 0x00000202 - -/* sdram */ -#define PIOC_ASR 0xFFFFF870 -#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as Perip (D16/D31) */ -#define PIOC_BSR 0xFFFFF874 -#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 -#define PIOC_PDR 0xFFFFF804 -#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 -#define EBI_CSA 0xFFFFFF60 -#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ -#define SDRC_CR 0xFFFFFF98 -#define CONFIG_SYS_SDRC_CR_VAL 0x2188c155 /* set up the CONFIG_SYS_SDRAM */ -#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ -#define CONFIG_SYS_SDRAM1 0x20000080 /* address of the CONFIG_SYS_SDRAM */ -#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ -#define SDRC_MR 0xFFFFFF90 -#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ -#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ -#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ -#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ -#define SDRC_TR 0xFFFFFF94 -#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ - -_TEXT_BASE: - .word TEXT_BASE - -.globl lowlevelinit -lowlevelinit: - /* memory control configuration */ - /* this isn't very elegant, but what the heck */ - ldr r0, =SMRDATA - ldr r1, _TEXT_BASE - sub r0, r0, r1 - add r2, r0, #80 -0: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 0b - /* delay - this is all done by guess */ - ldr r0, =0x00010000 -1: - subs r0, r0, #1 - bhi 1b - ldr r0, =SMRDATA1 - ldr r1, _TEXT_BASE - sub r0, r0, r1 - add r2, r0, #176 -2: - /* the address */ - ldr r1, [r0], #4 - /* the value */ - ldr r3, [r0], #4 - str r3, [r1] - cmp r2, r0 - bne 2b - - /* everything is fine now */ - mov pc, lr - - .ltorg - -SMRDATA: - .word MC_PUIA - .word CONFIG_SYS_MC_PUIA_VAL - .word MC_PUP - .word CONFIG_SYS_MC_PUP_VAL - .word MC_PUER - .word CONFIG_SYS_MC_PUER_VAL - .word MC_ASR - .word CONFIG_SYS_MC_ASR_VAL - .word MC_AASR - .word CONFIG_SYS_MC_AASR_VAL - .word EBI_CFGR - .word CONFIG_SYS_EBI_CFGR_VAL - .word SMC_CSR0 - .word CONFIG_SYS_SMC_CSR0_VAL - .word PLLAR - .word CONFIG_SYS_PLLAR_VAL - .word PLLBR - .word CONFIG_SYS_PLLBR_VAL - .word MCKR - .word CONFIG_SYS_MCKR_VAL - /* SMRDATA is 80 bytes long */ - /* here there's a delay of 100 */ -SMRDATA1: - .word PIOC_ASR - .word CONFIG_SYS_PIOC_ASR_VAL - .word PIOC_BSR - .word CONFIG_SYS_PIOC_BSR_VAL - .word PIOC_PDR - .word CONFIG_SYS_PIOC_PDR_VAL - .word EBI_CSA - .word CONFIG_SYS_EBI_CSA_VAL - .word SDRC_CR - .word CONFIG_SYS_SDRC_CR_VAL - .word SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL1 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL2 - .word CONFIG_SYS_SDRAM1 - .word CONFIG_SYS_SDRAM_VAL - .word SDRC_TR - .word CONFIG_SYS_SDRC_TR_VAL - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - .word SDRC_MR - .word CONFIG_SYS_SDRC_MR_VAL3 - .word CONFIG_SYS_SDRAM - .word CONFIG_SYS_SDRAM_VAL - /* SMRDATA1 is 176 bytes long */ -#endif /* CONFIG_BOOTBINFUNC */ diff --git a/include/configs/m501sk.h b/include/configs/m501sk.h index f09214d..eab37df 100644 --- a/include/configs/m501sk.h +++ b/include/configs/m501sk.h @@ -41,6 +41,39 @@ #define CONFIG_INITRD_TAG 1 #define CONFIG_MENUPROMPT "." +/* + * LowLevel Init + */ +#define CONFIG_SYS_USE_MAIN_OSCILLATOR 1 +/* flash */ +#define CONFIG_SYS_MC_PUIA_VAL 0x00000000 +#define CONFIG_SYS_MC_PUP_VAL 0x00000000 +#define CONFIG_SYS_MC_PUER_VAL 0x00000000 +#define CONFIG_SYS_MC_ASR_VAL 0x00000000 +#define CONFIG_SYS_MC_AASR_VAL 0x00000000 +#define CONFIG_SYS_EBI_CFGR_VAL 0x00000000 +#define CONFIG_SYS_SMC_CSR0_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */ + +/* clocks */ +#define CONFIG_SYS_PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */ +#define CONFIG_SYS_PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */ +/* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */ +#define CONFIG_SYS_MCKR_VAL 0x00000202 + +/* sdram */ +#define CONFIG_SYS_PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */ +#define CONFIG_SYS_PIOC_BSR_VAL 0x00000000 +#define CONFIG_SYS_PIOC_PDR_VAL 0xFFFF0000 +#define CONFIG_SYS_EBI_CSA_VAL 0x00000002 /* CS1=CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_CR_VAL 0x2188c155 /* set up the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM 0x20000000 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM1 0x20000080 /* address of the CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRAM_VAL 0x00000000 /* value written to CONFIG_SYS_SDRAM */ +#define CONFIG_SYS_SDRC_MR_VAL 0x00000002 /* Precharge All */ +#define CONFIG_SYS_SDRC_MR_VAL1 0x00000004 /* refresh */ +#define CONFIG_SYS_SDRC_MR_VAL2 0x00000003 /* Load Mode Register */ +#define CONFIG_SYS_SDRC_MR_VAL3 0x00000000 /* Normal Mode */ +#define CONFIG_SYS_SDRC_TR_VAL 0x000002E0 /* Write refresh rate */ /* * Size of malloc() pool -- cgit v1.1 From 3dd9395a0d7ce69a335d0e743c04b9caedd681d3 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 6 Jan 2009 21:41:59 +0100 Subject: at91rm9200: move define from lowlevel_init to header Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- cpu/arm920t/at91rm9200/lowlevel_init.S | 70 +++++++++------------------- include/asm-arm/arch-at91rm9200/AT91RM9200.h | 27 +++++++++++ 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/cpu/arm920t/at91rm9200/lowlevel_init.S b/cpu/arm920t/at91rm9200/lowlevel_init.S index 736f1ea..0913284 100644 --- a/cpu/arm920t/at91rm9200/lowlevel_init.S +++ b/cpu/arm920t/at91rm9200/lowlevel_init.S @@ -38,33 +38,7 @@ * turn is based on the boot.bin code from ATMEL * */ - -/* flash */ -#define MC_PUIA 0xFFFFFF10 -#define MC_PUP 0xFFFFFF50 -#define MC_PUER 0xFFFFFF54 -#define MC_ASR 0xFFFFFF04 -#define MC_AASR 0xFFFFFF08 -#define EBI_CFGR 0xFFFFFF64 -#define SMC_CSR0 0xFFFFFF70 - -/* clocks */ -#define PLLAR 0xFFFFFC28 -#define PLLBR 0xFFFFFC2C -#define MCKR 0xFFFFFC30 - -#define AT91C_BASE_CKGR 0xFFFFFC20 -#define CKGR_MOR 0 - -/* sdram */ -#define PIOC_ASR 0xFFFFF870 -#define PIOC_BSR 0xFFFFF874 -#define PIOC_PDR 0xFFFFF804 -#define EBI_CSA 0xFFFFFF60 -#define SDRC_CR 0xFFFFFF98 -#define SDRC_MR 0xFFFFFF90 -#define SDRC_TR 0xFFFFFF94 - +#include _MTEXT_BASE: #undef START_FROM_MEM @@ -84,7 +58,7 @@ lowlevel_init: #else ldr r0, =0x0000FF00 /* Disable main oscillator, OSCOUNT = 0xFF */ #endif - str r0, [r1, #CKGR_MOR] + str r0, [r1, #AT91C_CKGR_MOR] /* Add loop to compensate Main Oscillator startup time */ ldr r0, =0x00000010 LoopOsc: @@ -134,44 +108,44 @@ LoopOsc: .ltorg SMRDATA: - .word MC_PUIA + .word AT91C_MC_PUIA .word CONFIG_SYS_MC_PUIA_VAL - .word MC_PUP + .word AT91C_MC_PUP .word CONFIG_SYS_MC_PUP_VAL - .word MC_PUER + .word AT91C_MC_PUER .word CONFIG_SYS_MC_PUER_VAL - .word MC_ASR + .word AT91C_MC_ASR .word CONFIG_SYS_MC_ASR_VAL - .word MC_AASR + .word AT91C_MC_AASR .word CONFIG_SYS_MC_AASR_VAL - .word EBI_CFGR + .word AT91C_EBI_CFGR .word CONFIG_SYS_EBI_CFGR_VAL - .word SMC_CSR0 + .word AT91C_SMC_CSR0 .word CONFIG_SYS_SMC_CSR0_VAL - .word PLLAR + .word AT91C_PLLAR .word CONFIG_SYS_PLLAR_VAL - .word PLLBR + .word AT91C_PLLBR .word CONFIG_SYS_PLLBR_VAL - .word MCKR + .word AT91C_MCKR .word CONFIG_SYS_MCKR_VAL /* SMRDATA is 80 bytes long */ /* here there's a delay of 100 */ SMRDATA1: - .word PIOC_ASR + .word AT91C_PIOC_ASR .word CONFIG_SYS_PIOC_ASR_VAL - .word PIOC_BSR + .word AT91C_PIOC_BSR .word CONFIG_SYS_PIOC_BSR_VAL - .word PIOC_PDR + .word AT91C_PIOC_PDR .word CONFIG_SYS_PIOC_PDR_VAL - .word EBI_CSA + .word AT91C_EBI_CSA .word CONFIG_SYS_EBI_CSA_VAL - .word SDRC_CR + .word AT91C_SDRC_CR .word CONFIG_SYS_SDRC_CR_VAL - .word SDRC_MR + .word AT91C_SDRC_MR .word CONFIG_SYS_SDRC_MR_VAL .word CONFIG_SYS_SDRAM .word CONFIG_SYS_SDRAM_VAL - .word SDRC_MR + .word AT91C_SDRC_MR .word CONFIG_SYS_SDRC_MR_VAL1 .word CONFIG_SYS_SDRAM .word CONFIG_SYS_SDRAM_VAL @@ -189,15 +163,15 @@ SMRDATA1: .word CONFIG_SYS_SDRAM_VAL .word CONFIG_SYS_SDRAM .word CONFIG_SYS_SDRAM_VAL - .word SDRC_MR + .word AT91C_SDRC_MR .word CONFIG_SYS_SDRC_MR_VAL2 .word CONFIG_SYS_SDRAM1 .word CONFIG_SYS_SDRAM_VAL - .word SDRC_TR + .word AT91C_SDRC_TR .word CONFIG_SYS_SDRC_TR_VAL .word CONFIG_SYS_SDRAM .word CONFIG_SYS_SDRAM_VAL - .word SDRC_MR + .word AT91C_SDRC_MR .word CONFIG_SYS_SDRC_MR_VAL3 .word CONFIG_SYS_SDRAM .word CONFIG_SYS_SDRAM_VAL diff --git a/include/asm-arm/arch-at91rm9200/AT91RM9200.h b/include/asm-arm/arch-at91rm9200/AT91RM9200.h index 95db017..00bae1c 100644 --- a/include/asm-arm/arch-at91rm9200/AT91RM9200.h +++ b/include/asm-arm/arch-at91rm9200/AT91RM9200.h @@ -781,5 +781,32 @@ typedef struct _AT91S_PDC #define AT91C_PIOB_ODR ((AT91_REG *) 0xFFFFF614) /* (PIOB) Output Disable Registerr */ #define AT91C_PIOB_PDSR ((AT91_REG *) 0xFFFFF63C) /* (PIOB) Pin Data Status Register */ +#else +/* flash */ +#define AT91C_MC_PUIA 0xFFFFFF10 +#define AT91C_MC_PUP 0xFFFFFF50 +#define AT91C_MC_PUER 0xFFFFFF54 +#define AT91C_MC_ASR 0xFFFFFF04 +#define AT91C_MC_AASR 0xFFFFFF08 +#define AT91C_EBI_CFGR 0xFFFFFF64 +#define AT91C_SMC_CSR0 0xFFFFFF70 + +/* clocks */ +#define AT91C_PLLAR 0xFFFFFC28 +#define AT91C_PLLBR 0xFFFFFC2C +#define AT91C_MCKR 0xFFFFFC30 + +#define AT91C_BASE_CKGR 0xFFFFFC20 +#define AT91C_CKGR_MOR 0 + +/* sdram */ +#define AT91C_PIOC_ASR 0xFFFFF870 +#define AT91C_PIOC_BSR 0xFFFFF874 +#define AT91C_PIOC_PDR 0xFFFFF804 +#define AT91C_EBI_CSA 0xFFFFFF60 +#define AT91C_SDRC_CR 0xFFFFFF98 +#define AT91C_SDRC_MR 0xFFFFFF90 +#define AT91C_SDRC_TR 0xFFFFFF94 + #endif /* __ASSEMBLY__ */ #endif /* AT91RM9200_H */ -- cgit v1.1 From 509fc553bc6087a6f705b3bf52f3950d7d1eaa58 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 11 Oct 2008 20:45:44 -0400 Subject: Blackfin: set proper LDRFLAGS for parallel booting LDRs In order to boot an LDR out of parallel flash, the ldr utility needs a few flags to tell it to generate the right header. Signed-off-by: Mike Frysinger --- board/bf533-ezkit/config.mk | 6 ++++++ board/bf533-stamp/config.mk | 6 ++++++ board/bf537-stamp/config.mk | 5 ++++- board/bf561-ezkit/config.mk | 6 ++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/board/bf533-ezkit/config.mk b/board/bf533-ezkit/config.mk index de80ffe..9847924 100644 --- a/board/bf533-ezkit/config.mk +++ b/board/bf533-ezkit/config.mk @@ -1,4 +1,6 @@ # +# Copyright (c) 2005-2008 Analog Device Inc. +# # (C) Copyright 2001 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # @@ -23,3 +25,7 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me + +# Set some default LDR flags based on boot mode. +LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 --dma 8 +LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) diff --git a/board/bf533-stamp/config.mk b/board/bf533-stamp/config.mk index de80ffe..9847924 100644 --- a/board/bf533-stamp/config.mk +++ b/board/bf533-stamp/config.mk @@ -1,4 +1,6 @@ # +# Copyright (c) 2005-2008 Analog Device Inc. +# # (C) Copyright 2001 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # @@ -23,3 +25,7 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me + +# Set some default LDR flags based on boot mode. +LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 --dma 8 +LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) diff --git a/board/bf537-stamp/config.mk b/board/bf537-stamp/config.mk index 1b87d53..d9e884e 100644 --- a/board/bf537-stamp/config.mk +++ b/board/bf537-stamp/config.mk @@ -1,4 +1,6 @@ # +# Copyright (c) 2005-2008 Analog Device Inc. +# # (C) Copyright 2001 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # @@ -25,5 +27,6 @@ #TEXT_BASE = do-not-use-me # Set some default LDR flags based on boot mode. -LDR_FLAGS-BFIN_BOOT_UART := --port g --gpio 6 +LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 --dma 8 +LDR_FLAGS-BFIN_BOOT_UART := --port g --gpio 6 LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) diff --git a/board/bf561-ezkit/config.mk b/board/bf561-ezkit/config.mk index de80ffe..77c888b 100644 --- a/board/bf561-ezkit/config.mk +++ b/board/bf561-ezkit/config.mk @@ -1,4 +1,6 @@ # +# Copyright (c) 2005-2008 Analog Device Inc. +# # (C) Copyright 2001 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # @@ -23,3 +25,7 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me + +# Set some default LDR flags based on boot mode. +LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 +LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) -- cgit v1.1 From b9eecc342f767b50e1476fbc1aad7d88dd4ce5eb Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 24 Oct 2008 17:48:54 -0400 Subject: Blackfin: fix linker scripts to work with --gc-sections Make sure all .text sections get pulled in and the entry point is properly referenced so they don't get discarded when linking with --gc-sections. Signed-off-by: Mike Frysinger --- board/bf533-ezkit/u-boot.lds.S | 23 +++++++++++++---------- board/bf533-stamp/u-boot.lds.S | 19 +++++++++++-------- board/bf537-stamp/u-boot.lds.S | 19 +++++++++++-------- board/bf561-ezkit/u-boot.lds.S | 23 +++++++++++++---------- 4 files changed, 48 insertions(+), 36 deletions(-) diff --git a/board/bf533-ezkit/u-boot.lds.S b/board/bf533-ezkit/u-boot.lds.S index 70764ac..da16726 100644 --- a/board/bf533-ezkit/u-boot.lds.S +++ b/board/bf533-ezkit/u-boot.lds.S @@ -28,6 +28,8 @@ #include #include #undef ALIGN +#undef ENTRY +#undef bfin /* If we don't actually load anything into L1 data, this will avoid * a syntax error. If we do actually load something into L1 data, @@ -50,11 +52,12 @@ MEMORY l1_data : ORIGIN = L1_DATA_B_SRAM, LENGTH = L1_DATA_B_SRAM_SIZE } +ENTRY(_start) SECTIONS { .text : { - cpu/blackfin/start.o (.text) + cpu/blackfin/start.o (.text .text.*) #ifdef ENV_IS_EMBEDDED /* WARNING - the following is hand-optimized to fit within @@ -63,20 +66,20 @@ SECTIONS * it linked after the configuration sector. */ - cpu/blackfin/traps.o (.text) - cpu/blackfin/interrupt.o (.text) - cpu/blackfin/serial.o (.text) - common/dlmalloc.o (.text) - lib_generic/crc32.o (.text) - lib_generic/zlib.o (.text) - board/bf533-ezkit/bf533-ezkit.o (.text) + cpu/blackfin/traps.o (.text .text.*) + cpu/blackfin/interrupt.o (.text .text.*) + cpu/blackfin/serial.o (.text .text.*) + common/dlmalloc.o (.text .text.*) + lib_generic/crc32.o (.text .text.*) + lib_generic/zlib.o (.text .text.*) + board/bf533-ezkit/bf533-ezkit.o (.text .text.*) . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) + common/env_embedded.o (.text .text.*) #endif __initcode_start = .; - cpu/blackfin/initcode.o (.text) + cpu/blackfin/initcode.o (.text .text.*) __initcode_end = .; *(.text .text.*) diff --git a/board/bf533-stamp/u-boot.lds.S b/board/bf533-stamp/u-boot.lds.S index 187309f..76daa75 100644 --- a/board/bf533-stamp/u-boot.lds.S +++ b/board/bf533-stamp/u-boot.lds.S @@ -28,6 +28,8 @@ #include #include #undef ALIGN +#undef ENTRY +#undef bfin /* If we don't actually load anything into L1 data, this will avoid * a syntax error. If we do actually load something into L1 data, @@ -50,11 +52,12 @@ MEMORY l1_data : ORIGIN = L1_DATA_B_SRAM, LENGTH = L1_DATA_B_SRAM_SIZE } +ENTRY(_start) SECTIONS { .text : { - cpu/blackfin/start.o (.text) + cpu/blackfin/start.o (.text .text.*) #ifdef ENV_IS_EMBEDDED /* WARNING - the following is hand-optimized to fit within @@ -63,18 +66,18 @@ SECTIONS * it linked after the configuration sector. */ - cpu/blackfin/traps.o (.text) - cpu/blackfin/interrupt.o (.text) - cpu/blackfin/serial.o (.text) - common/dlmalloc.o (.text) - lib_generic/crc32.o (.text) + cpu/blackfin/traps.o (.text .text.*) + cpu/blackfin/interrupt.o (.text .text.*) + cpu/blackfin/serial.o (.text .text.*) + common/dlmalloc.o (.text .text.*) + lib_generic/crc32.o (.text .text.*) . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) + common/env_embedded.o (.text .text.*) #endif __initcode_start = .; - cpu/blackfin/initcode.o (.text) + cpu/blackfin/initcode.o (.text .text.*) __initcode_end = .; *(.text .text.*) diff --git a/board/bf537-stamp/u-boot.lds.S b/board/bf537-stamp/u-boot.lds.S index 187309f..76daa75 100644 --- a/board/bf537-stamp/u-boot.lds.S +++ b/board/bf537-stamp/u-boot.lds.S @@ -28,6 +28,8 @@ #include #include #undef ALIGN +#undef ENTRY +#undef bfin /* If we don't actually load anything into L1 data, this will avoid * a syntax error. If we do actually load something into L1 data, @@ -50,11 +52,12 @@ MEMORY l1_data : ORIGIN = L1_DATA_B_SRAM, LENGTH = L1_DATA_B_SRAM_SIZE } +ENTRY(_start) SECTIONS { .text : { - cpu/blackfin/start.o (.text) + cpu/blackfin/start.o (.text .text.*) #ifdef ENV_IS_EMBEDDED /* WARNING - the following is hand-optimized to fit within @@ -63,18 +66,18 @@ SECTIONS * it linked after the configuration sector. */ - cpu/blackfin/traps.o (.text) - cpu/blackfin/interrupt.o (.text) - cpu/blackfin/serial.o (.text) - common/dlmalloc.o (.text) - lib_generic/crc32.o (.text) + cpu/blackfin/traps.o (.text .text.*) + cpu/blackfin/interrupt.o (.text .text.*) + cpu/blackfin/serial.o (.text .text.*) + common/dlmalloc.o (.text .text.*) + lib_generic/crc32.o (.text .text.*) . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) + common/env_embedded.o (.text .text.*) #endif __initcode_start = .; - cpu/blackfin/initcode.o (.text) + cpu/blackfin/initcode.o (.text .text.*) __initcode_end = .; *(.text .text.*) diff --git a/board/bf561-ezkit/u-boot.lds.S b/board/bf561-ezkit/u-boot.lds.S index 99d6be6..3d0453e 100644 --- a/board/bf561-ezkit/u-boot.lds.S +++ b/board/bf561-ezkit/u-boot.lds.S @@ -28,6 +28,8 @@ #include #include #undef ALIGN +#undef ENTRY +#undef bfin /* If we don't actually load anything into L1 data, this will avoid * a syntax error. If we do actually load something into L1 data, @@ -50,11 +52,12 @@ MEMORY l1_data : ORIGIN = L1_DATA_B_SRAM, LENGTH = L1_DATA_B_SRAM_SIZE } +ENTRY(_start) SECTIONS { .text : { - cpu/blackfin/start.o (.text) + cpu/blackfin/start.o (.text .text.*) #ifdef ENV_IS_EMBEDDED /* WARNING - the following is hand-optimized to fit within @@ -63,20 +66,20 @@ SECTIONS * it linked after the configuration sector. */ - cpu/blackfin/traps.o (.text) - cpu/blackfin/interrupt.o (.text) - cpu/blackfin/serial.o (.text) - common/dlmalloc.o (.text) - lib_generic/crc32.o (.text) - lib_generic/zlib.o (.text) - board/bf561-ezkit/bf561-ezkit.o (.text) + cpu/blackfin/traps.o (.text .text.*) + cpu/blackfin/interrupt.o (.text .text.*) + cpu/blackfin/serial.o (.text .text.*) + common/dlmalloc.o (.text .text.*) + lib_generic/crc32.o (.text .text.*) + lib_generic/zlib.o (.text .text.*) + board/bf561-ezkit/bf561-ezkit.o (.text .text.*) . = DEFINED(env_offset) ? env_offset : .; - common/env_embedded.o (.text) + common/env_embedded.o (.text .text.*) #endif __initcode_start = .; - cpu/blackfin/initcode.o (.text) + cpu/blackfin/initcode.o (.text .text.*) __initcode_end = .; *(.text .text.*) -- cgit v1.1 From e7e684b10d73a303902208594c7c3e7e0d753282 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 24 Oct 2008 17:51:57 -0400 Subject: Blackfin: fix out-of-tree building with ldscripts Many of the Blackfin board linker scripts are preprocessed, so make sure we output the linker script into the build tree rather than the source tree. Signed-off-by: Mike Frysinger --- board/bf533-ezkit/Makefile | 7 +++---- board/bf533-ezkit/config.mk | 2 ++ board/bf533-stamp/Makefile | 7 +++---- board/bf533-stamp/config.mk | 2 ++ board/bf537-stamp/Makefile | 7 +++---- board/bf537-stamp/config.mk | 2 ++ board/bf561-ezkit/Makefile | 7 +++---- board/bf561-ezkit/config.mk | 2 ++ 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/board/bf533-ezkit/Makefile b/board/bf533-ezkit/Makefile index b2d7acf..6a45b7c 100644 --- a/board/bf533-ezkit/Makefile +++ b/board/bf533-ezkit/Makefile @@ -35,12 +35,11 @@ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds +$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) -u-boot.lds: u-boot.lds.S - $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P -Ubfin $^ > $@.tmp - mv -f $@.tmp $@ +$(obj)u-boot.lds: u-boot.lds.S + $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P $^ > $@ clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/bf533-ezkit/config.mk b/board/bf533-ezkit/config.mk index 9847924..c8b9fb8 100644 --- a/board/bf533-ezkit/config.mk +++ b/board/bf533-ezkit/config.mk @@ -26,6 +26,8 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me +LDSCRIPT = $(obj)board/$(BOARDDIR)/u-boot.lds + # Set some default LDR flags based on boot mode. LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 --dma 8 LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile index 21f6ad1..5ae0228 100644 --- a/board/bf533-stamp/Makefile +++ b/board/bf533-stamp/Makefile @@ -35,12 +35,11 @@ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds +$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) -u-boot.lds: u-boot.lds.S - $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P -Ubfin $^ > $@.tmp - mv -f $@.tmp $@ +$(obj)u-boot.lds: u-boot.lds.S + $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P $^ > $@ clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/bf533-stamp/config.mk b/board/bf533-stamp/config.mk index 9847924..c8b9fb8 100644 --- a/board/bf533-stamp/config.mk +++ b/board/bf533-stamp/config.mk @@ -26,6 +26,8 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me +LDSCRIPT = $(obj)board/$(BOARDDIR)/u-boot.lds + # Set some default LDR flags based on boot mode. LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 --dma 8 LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile index e5481bf..e5ef9af 100644 --- a/board/bf537-stamp/Makefile +++ b/board/bf537-stamp/Makefile @@ -35,12 +35,11 @@ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds +$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) -u-boot.lds: u-boot.lds.S - $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P -Ubfin $^ > $@.tmp - mv -f $@.tmp $@ +$(obj)u-boot.lds: u-boot.lds.S + $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P $^ > $@ clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/bf537-stamp/config.mk b/board/bf537-stamp/config.mk index d9e884e..719b97e 100644 --- a/board/bf537-stamp/config.mk +++ b/board/bf537-stamp/config.mk @@ -26,6 +26,8 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me +LDSCRIPT = $(obj)board/$(BOARDDIR)/u-boot.lds + # Set some default LDR flags based on boot mode. LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 --dma 8 LDR_FLAGS-BFIN_BOOT_UART := --port g --gpio 6 diff --git a/board/bf561-ezkit/Makefile b/board/bf561-ezkit/Makefile index a1a4433..e7ee243 100644 --- a/board/bf561-ezkit/Makefile +++ b/board/bf561-ezkit/Makefile @@ -35,12 +35,11 @@ SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds +$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) -u-boot.lds: u-boot.lds.S - $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P -Ubfin $^ > $@.tmp - mv -f $@.tmp $@ +$(obj)u-boot.lds: u-boot.lds.S + $(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -P $^ > $@ clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/bf561-ezkit/config.mk b/board/bf561-ezkit/config.mk index 77c888b..710809a 100644 --- a/board/bf561-ezkit/config.mk +++ b/board/bf561-ezkit/config.mk @@ -26,6 +26,8 @@ # This is not actually used for Blackfin boards so do not change it #TEXT_BASE = do-not-use-me +LDSCRIPT = $(obj)board/$(BOARDDIR)/u-boot.lds + # Set some default LDR flags based on boot mode. LDR_FLAGS-BFIN_BOOT_PARA := --bits 16 LDR_FLAGS += $(LDR_FLAGS-$(CONFIG_BFIN_BOOT_MODE)) -- cgit v1.1 From 687f952e4119594ab913be11c90f7f018c2a7a79 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 11 Dec 2008 07:04:48 -0500 Subject: Blackfin: drop CONFIG_SPI handling in board init The eeprom SPI init functions are duplicated as the common code already executes these for us. Signed-off-by: Mike Frysinger --- lib_blackfin/board.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c index fde4bbe..05e66e3 100644 --- a/lib_blackfin/board.c +++ b/lib_blackfin/board.c @@ -374,13 +374,6 @@ void board_init_r(gd_t * id, ulong dest_addr) mem_malloc_init(); malloc_bin_reloc(); -#ifdef CONFIG_SPI -# if ! defined(CONFIG_ENV_IS_IN_EEPROM) - spi_init_f(); -# endif - spi_init_r(); -#endif - #ifdef CONFIG_CMD_NAND puts("NAND: "); nand_init(); /* go init the NAND */ -- cgit v1.1 From 032a1c934ef4dc003281f57302b6e693062c1868 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 5 Jan 2009 16:09:44 -0500 Subject: bf537-stamp/nand: fix board_nand_init prototype The board_nand_init() function should return an int, not void. Signed-off-by: Mike Frysinger --- board/bf537-stamp/nand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index c597f2d..20a7d0e 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -87,7 +87,7 @@ int bfin_device_ready(struct mtd_info *mtd) * Members with a "?" were not set in the merged testing-NAND branch, * so they are not set here either. */ -void board_nand_init(struct nand_chip *nand) +int board_nand_init(struct nand_chip *nand) { *PORT(CONFIG_NAND_GPIO_PORT, _FER) &= ~BFIN_NAND_READY; *PORT(CONFIG_NAND_GPIO_PORT, IO_DIR) &= ~BFIN_NAND_READY; @@ -97,5 +97,7 @@ void board_nand_init(struct nand_chip *nand) nand->ecc.mode = NAND_ECC_SOFT; nand->dev_ready = bfin_device_ready; nand->chip_delay = 30; + + return 0; } #endif -- cgit v1.1 From a9f3acbcd07da72b5446ce557531a3ed8b8beff0 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Mon, 12 Jan 2009 14:50:35 +0100 Subject: MPC86xx: fix build warnings Signed-off-by: Wolfgang Denk --- cpu/mpc86xx/cpu.c | 2 +- cpu/mpc86xx/fdt.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index 3568023..dc53bee 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -101,7 +101,7 @@ checkcpu(void) if (sysinfo.freqLocalBus > LCRR_CLKDIV) { printf("LBC:%4lu MHz\n", sysinfo.freqLocalBus / 1000000); } else { - printf("LBC: unknown (LCRR[CLKDIV] = 0x%02x)\n", + printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n", sysinfo.freqLocalBus); } diff --git a/cpu/mpc86xx/fdt.c b/cpu/mpc86xx/fdt.c index e277040..383b06b 100644 --- a/cpu/mpc86xx/fdt.c +++ b/cpu/mpc86xx/fdt.c @@ -13,8 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -DECLARE_GLOBAL_DATA_PTR; - void ft_cpu_setup(void *blob, bd_t *bd) { #if (CONFIG_NUM_CPUS > 1) -- cgit v1.1 From 79e436cad3b4a7db88408c3f05175028f30d700d Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Wed, 3 Dec 2008 22:36:26 -0600 Subject: sbc8641d: Fix PCI mapping concepts Rename _BASE to _BUS, as it's actually a PCI bus address, separate virtual and physical addresses into _VIRT and _PHYS, and use each appopriately. This makes the code easier to read and understand, and facilitates mapping changes going forward. Signed-off-by: Becky Bruce --- board/sbc8641d/law.c | 10 +++++----- board/sbc8641d/sbc8641d.c | 8 ++++---- include/configs/sbc8641d.h | 32 ++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/board/sbc8641d/law.c b/board/sbc8641d/law.c index de47fcd..760c693 100644 --- a/board/sbc8641d/law.c +++ b/board/sbc8641d/law.c @@ -45,14 +45,14 @@ struct law_entry law_table[] = { SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_DDR_1), - SET_LAW(CONFIG_SYS_PCI1_MEM_BASE, LAW_SIZE_512M, LAW_TRGT_IF_PCI_1), - SET_LAW(CONFIG_SYS_PCI2_MEM_BASE, LAW_SIZE_512M, LAW_TRGT_IF_PCI_2), + SET_LAW(CONFIG_SYS_PCI1_MEM_PHYS, LAW_SIZE_512M, LAW_TRGT_IF_PCI_1), + SET_LAW(CONFIG_SYS_PCI2_MEM_PHYS, LAW_SIZE_512M, LAW_TRGT_IF_PCI_2), SET_LAW(0xf8000000, LAW_SIZE_2M, LAW_TRGT_IF_LBC), - SET_LAW(CONFIG_SYS_PCI1_IO_BASE, LAW_SIZE_16M, LAW_TRGT_IF_PCI_1), - SET_LAW(CONFIG_SYS_PCI2_IO_BASE, LAW_SIZE_16M, LAW_TRGT_IF_PCI_2), + SET_LAW(CONFIG_SYS_PCI1_IO_PHYS, LAW_SIZE_16M, LAW_TRGT_IF_PCI_1), + SET_LAW(CONFIG_SYS_PCI2_IO_PHYS, LAW_SIZE_16M, LAW_TRGT_IF_PCI_2), SET_LAW(0xfe000000, LAW_SIZE_32M, LAW_TRGT_IF_LBC), SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_DDR_2), - SET_LAW(CONFIG_SYS_RIO_MEM_BASE, LAW_SIZE_512M, LAW_TRGT_IF_RIO) + SET_LAW(CONFIG_SYS_RIO_MEM_PHYS, LAW_SIZE_512M, LAW_TRGT_IF_RIO) }; int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/sbc8641d/sbc8641d.c b/board/sbc8641d/sbc8641d.c index 1471e58..508bdc5 100644 --- a/board/sbc8641d/sbc8641d.c +++ b/board/sbc8641d/sbc8641d.c @@ -247,14 +247,14 @@ void pci_init_board(void) /* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCI1_MEM_BASE, + CONFIG_SYS_PCI1_MEM_BUS, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM); /* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCI1_IO_BASE, + CONFIG_SYS_PCI1_IO_BUS, CONFIG_SYS_PCI1_IO_PHYS, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO); @@ -290,14 +290,14 @@ void pci_init_board(void) /* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCI2_MEM_BASE, + CONFIG_SYS_PCI2_MEM_BUS, CONFIG_SYS_PCI2_MEM_PHYS, CONFIG_SYS_PCI2_MEM_SIZE, PCI_REGION_MEM); /* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCI2_IO_BASE, + CONFIG_SYS_PCI2_IO_BUS, CONFIG_SYS_PCI2_IO_PHYS, CONFIG_SYS_PCI2_IO_SIZE, PCI_REGION_IO); diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index 0012945..1008812 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -311,18 +311,22 @@ * General PCI * Addresses are mapped 1-1. */ -#define CONFIG_SYS_PCI1_MEM_BASE 0x80000000 -#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_BASE +#define CONFIG_SYS_PCI1_MEM_BUS 0x80000000 +#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_BUS +#define CONFIG_SYS_PCI1_MEM_VIRT CONFIG_SYS_PCI1_MEM_BUS #define CONFIG_SYS_PCI1_MEM_SIZE 0x20000000 /* 512M */ -#define CONFIG_SYS_PCI1_IO_BASE 0xe2000000 -#define CONFIG_SYS_PCI1_IO_PHYS CONFIG_SYS_PCI1_IO_BASE +#define CONFIG_SYS_PCI1_IO_BUS 0xe2000000 +#define CONFIG_SYS_PCI1_IO_PHYS CONFIG_SYS_PCI1_IO_BUS +#define CONFIG_SYS_PCI1_IO_VIRT CONFIG_SYS_PCI1_IO_BUS #define CONFIG_SYS_PCI1_IO_SIZE 0x1000000 /* 16M */ -#define CONFIG_SYS_PCI2_MEM_BASE 0xa0000000 -#define CONFIG_SYS_PCI2_MEM_PHYS CONFIG_SYS_PCI2_MEM_BASE +#define CONFIG_SYS_PCI2_MEM_BUS 0xa0000000 +#define CONFIG_SYS_PCI2_MEM_PHYS CONFIG_SYS_PCI2_MEM_BUS +#define CONFIG_SYS_PCI2_MEM_VIRT CONFIG_SYS_PCI2_MEM_BUS #define CONFIG_SYS_PCI2_MEM_SIZE 0x10000000 /* 256M */ -#define CONFIG_SYS_PCI2_IO_BASE 0xe3000000 -#define CONFIG_SYS_PCI2_IO_PHYS CONFIG_SYS_PCI2_IO_BASE +#define CONFIG_SYS_PCI2_IO_BUS 0xe3000000 +#define CONFIG_SYS_PCI2_IO_PHYS CONFIG_SYS_PCI2_IO_BUS +#define CONFIG_SYS_PCI2_IO_VIRT CONFIG_SYS_PCI2_IO_BUS #define CONFIG_SYS_PCI2_IO_SIZE 0x1000000 /* 16M */ #if defined(CONFIG_PCI) @@ -409,10 +413,10 @@ * 0xa000_0000 512M PCI-Express 2 Memory * Changed it for operating from 0xd0000000 */ -#define CONFIG_SYS_DBAT1L ( CONFIG_SYS_PCI1_MEM_BASE | BATL_PP_RW \ +#define CONFIG_SYS_DBAT1L ( CONFIG_SYS_PCI1_MEM_PHYS | BATL_PP_RW \ | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CONFIG_SYS_DBAT1U (CONFIG_SYS_PCI1_MEM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) -#define CONFIG_SYS_IBAT1L (CONFIG_SYS_PCI1_MEM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CONFIG_SYS_DBAT1U (CONFIG_SYS_PCI1_MEM_VIRT | BATU_BL_256M | BATU_VS | BATU_VP) +#define CONFIG_SYS_IBAT1L (CONFIG_SYS_PCI1_MEM_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CONFIG_SYS_IBAT1U CONFIG_SYS_DBAT1U /* @@ -452,10 +456,10 @@ * 0xe300_0000 16M PCI-Express 2 I/0 * Note that this is at 0xe0000000 */ -#define CONFIG_SYS_DBAT4L ( CONFIG_SYS_PCI1_IO_BASE | BATL_PP_RW \ +#define CONFIG_SYS_DBAT4L ( CONFIG_SYS_PCI1_IO_PHYS | BATL_PP_RW \ | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) -#define CONFIG_SYS_DBAT4U (CONFIG_SYS_PCI1_IO_BASE | BATU_BL_32M | BATU_VS | BATU_VP) -#define CONFIG_SYS_IBAT4L (CONFIG_SYS_PCI1_IO_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) +#define CONFIG_SYS_DBAT4U (CONFIG_SYS_PCI1_IO_VIRT | BATU_BL_32M | BATU_VS | BATU_VP) +#define CONFIG_SYS_IBAT4L (CONFIG_SYS_PCI1_IO_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CONFIG_SYS_IBAT4U CONFIG_SYS_DBAT4U /* -- cgit v1.1 From 3e3fffe3baf3befde287fec1fcbfe55052fb8946 Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Wed, 3 Dec 2008 22:36:44 -0600 Subject: mpc8610hpcd: Fix PCI mapping concepts Rename _BASE to _BUS, as it's actually a PCI bus address, separate virtual and physical addresses into _VIRT and _PHYS, and use each appopriately. This makes the code easier to read and understand, and facilitates mapping changes going forward. Signed-off-by: Becky Bruce --- board/freescale/mpc8610hpcd/law.c | 4 ++-- board/freescale/mpc8610hpcd/mpc8610hpcd.c | 12 ++++++------ include/configs/MPC8610HPCD.h | 24 +++++++++++++----------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/board/freescale/mpc8610hpcd/law.c b/board/freescale/mpc8610hpcd/law.c index 2aad28a..0fc8384 100644 --- a/board/freescale/mpc8610hpcd/law.c +++ b/board/freescale/mpc8610hpcd/law.c @@ -31,8 +31,8 @@ struct law_entry law_table[] = { #if !defined(CONFIG_SPD_EEPROM) SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_512M, LAW_TRGT_IF_DDR_1), #endif - SET_LAW(CONFIG_SYS_PCIE1_MEM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_1), - SET_LAW(CONFIG_SYS_PCIE2_MEM_BASE, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_2), + SET_LAW(CONFIG_SYS_PCIE1_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_1), + SET_LAW(CONFIG_SYS_PCIE2_MEM_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_PCIE_2), SET_LAW(PIXIS_BASE, LAW_SIZE_2M, LAW_TRGT_IF_LBC), SET_LAW(CONFIG_SYS_PCIE1_IO_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_PCIE_1), SET_LAW(CONFIG_SYS_PCIE2_IO_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_PCIE_2), diff --git a/board/freescale/mpc8610hpcd/mpc8610hpcd.c b/board/freescale/mpc8610hpcd/mpc8610hpcd.c index 2792778..a2097a5 100644 --- a/board/freescale/mpc8610hpcd/mpc8610hpcd.c +++ b/board/freescale/mpc8610hpcd/mpc8610hpcd.c @@ -266,14 +266,14 @@ void pci_init_board(void) /* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCIE1_MEM_BASE, + CONFIG_SYS_PCIE1_MEM_BUS, CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_SIZE, PCI_REGION_MEM); /* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCIE1_IO_BASE, + CONFIG_SYS_PCIE1_IO_BUS, CONFIG_SYS_PCIE1_IO_PHYS, CONFIG_SYS_PCIE1_IO_SIZE, PCI_REGION_IO); @@ -321,14 +321,14 @@ void pci_init_board(void) /* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCIE2_MEM_BASE, + CONFIG_SYS_PCIE2_MEM_BUS, CONFIG_SYS_PCIE2_MEM_PHYS, CONFIG_SYS_PCIE2_MEM_SIZE, PCI_REGION_MEM); /* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCIE2_IO_BASE, + CONFIG_SYS_PCIE2_IO_BUS, CONFIG_SYS_PCIE2_IO_PHYS, CONFIG_SYS_PCIE2_IO_SIZE, PCI_REGION_IO); @@ -370,14 +370,14 @@ void pci_init_board(void) /* outbound memory */ pci_set_region(r++, - CONFIG_SYS_PCI1_MEM_BASE, + CONFIG_SYS_PCI1_MEM_BUS, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM); /* outbound io */ pci_set_region(r++, - CONFIG_SYS_PCI1_IO_BASE, + CONFIG_SYS_PCI1_IO_BUS, CONFIG_SYS_PCI1_IO_PHYS, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO); diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index 27517e5..4bd3e0b 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -273,11 +273,13 @@ * General PCI * Addresses are mapped 1-1. */ -#define CONFIG_SYS_PCI1_MEM_BASE 0x80000000 -#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_BASE +#define CONFIG_SYS_PCI1_MEM_BUS 0x80000000 +#define CONFIG_SYS_PCI1_MEM_PHYS CONFIG_SYS_PCI1_MEM_BUS +#define CONFIG_SYS_PCI1_MEM_VIRT CONFIG_SYS_PCI1_MEM_BUS #define CONFIG_SYS_PCI1_MEM_SIZE 0x10000000 /* 256M */ -#define CONFIG_SYS_PCI1_IO_BASE 0x00000000 +#define CONFIG_SYS_PCI1_IO_BUS 0x0000000 #define CONFIG_SYS_PCI1_IO_PHYS 0xe1000000 +#define CONFIG_SYS_PCI1_IO_VIRT 0xe1000000 #define CONFIG_SYS_PCI1_IO_SIZE 0x00100000 /* 1M */ /* For RTL8139 */ @@ -285,18 +287,18 @@ #define _IO_BASE 0x00000000 /* controller 1, Base address 0xa000 */ -#define CONFIG_SYS_PCIE1_MEM_BASE 0xa0000000 -#define CONFIG_SYS_PCIE1_MEM_PHYS CONFIG_SYS_PCIE1_MEM_BASE +#define CONFIG_SYS_PCIE1_MEM_BUS 0xa0000000 +#define CONFIG_SYS_PCIE1_MEM_PHYS CONFIG_SYS_PCIE1_MEM_BUS #define CONFIG_SYS_PCIE1_MEM_SIZE 0x10000000 /* 256M */ -#define CONFIG_SYS_PCIE1_IO_BASE 0x00000000 +#define CONFIG_SYS_PCIE1_IO_BUS 0x00000000 #define CONFIG_SYS_PCIE1_IO_PHYS 0xe3000000 #define CONFIG_SYS_PCIE1_IO_SIZE 0x00100000 /* 1M */ /* controller 2, Base Address 0x9000 */ -#define CONFIG_SYS_PCIE2_MEM_BASE 0x90000000 -#define CONFIG_SYS_PCIE2_MEM_PHYS CONFIG_SYS_PCIE2_MEM_BASE +#define CONFIG_SYS_PCIE2_MEM_BUS 0x90000000 +#define CONFIG_SYS_PCIE2_MEM_PHYS CONFIG_SYS_PCIE2_MEM_BUS #define CONFIG_SYS_PCIE2_MEM_SIZE 0x10000000 /* 256M */ -#define CONFIG_SYS_PCIE2_IO_BASE 0x00000000 /* reuse mem LAW */ +#define CONFIG_SYS_PCIE2_IO_BUS 0x00000000 /* reuse mem LAW */ #define CONFIG_SYS_PCIE2_IO_PHYS 0xe2000000 #define CONFIG_SYS_PCIE2_IO_SIZE 0x00100000 /* 1M */ @@ -364,7 +366,7 @@ #define CONFIG_SYS_DBAT1L (CONFIG_SYS_PCI1_MEM_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT \ | BATL_GUARDEDSTORAGE) -#define CONFIG_SYS_DBAT1U (CONFIG_SYS_PCI1_MEM_PHYS | BATU_BL_1G | BATU_VS | BATU_VP) +#define CONFIG_SYS_DBAT1U (CONFIG_SYS_PCI1_MEM_VIRT | BATU_BL_1G | BATU_VS | BATU_VP) #define CONFIG_SYS_IBAT1L (CONFIG_SYS_PCI1_MEM_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CONFIG_SYS_IBAT1U CONFIG_SYS_DBAT1U @@ -375,7 +377,7 @@ #define CONFIG_SYS_DBAT2L (CONFIG_SYS_PCI1_IO_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT \ | BATL_GUARDEDSTORAGE) -#define CONFIG_SYS_DBAT2U (CONFIG_SYS_PCI1_IO_PHYS | BATU_BL_16M | BATU_VS | BATU_VP) +#define CONFIG_SYS_DBAT2U (CONFIG_SYS_PCI1_IO_VIRT | BATU_BL_16M | BATU_VS | BATU_VP) #define CONFIG_SYS_IBAT2L (CONFIG_SYS_PCI1_IO_PHYS | BATL_PP_RW | BATL_CACHEINHIBIT) #define CONFIG_SYS_IBAT2U CONFIG_SYS_DBAT2U -- cgit v1.1 From 9afc2ef0307aecf52482df67c31b75d5f9e66b47 Mon Sep 17 00:00:00 2001 From: Roy Zang Date: Fri, 9 Jan 2009 16:00:55 +0800 Subject: Fix IO port selection issue on MPC8544DS and MPC8572DS boards The IO port selection is not correct on MPC8572DS and MPC8544DS board. This patch fixes this issue. For MPC8572 Port cfg_io_ports PCIE1 0x2, 0x3, 0x7, 0xb, 0xc, 0xf PCIE2 0x3, 0x7 PCIE3 0x7 For MPC8544 Port cfg_io_ports PCIE1 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 PCIE2 0x4, 0x5, 0x6, 0x7 PCIE3 0x6, 0x7 Signed-off-by: Roy Zang --- board/freescale/mpc8544ds/mpc8544ds.c | 2 +- board/freescale/mpc8572ds/mpc8572ds.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/board/freescale/mpc8544ds/mpc8544ds.c b/board/freescale/mpc8544ds/mpc8544ds.c index 14581ab..13c55fd 100644 --- a/board/freescale/mpc8544ds/mpc8544ds.c +++ b/board/freescale/mpc8544ds/mpc8544ds.c @@ -121,7 +121,7 @@ pci_init_board(void) volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR; struct pci_controller *hose = &pcie3_hose; int pcie_ep = (host_agent == 1); - int pcie_configured = io_sel >= 1; + int pcie_configured = io_sel >= 6; struct pci_region *r = hose->regions; if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index a14db5a..4733b82 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -166,7 +166,7 @@ void pci_init_board(void) struct pci_controller *hose = &pcie3_hose; int pcie_ep = (host_agent == 0) || (host_agent == 3) || (host_agent == 5) || (host_agent == 6); - int pcie_configured = io_sel >= 1; + int pcie_configured = (io_sel == 0x7); struct pci_region *r = hose->regions; u32 temp32; @@ -234,7 +234,7 @@ void pci_init_board(void) struct pci_controller *hose = &pcie2_hose; int pcie_ep = (host_agent == 2) || (host_agent == 4) || (host_agent == 6) || (host_agent == 0); - int pcie_configured = io_sel & 4; + int pcie_configured = (io_sel == 0x3) || (io_sel == 0x7); struct pci_region *r = hose->regions; if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ @@ -287,7 +287,9 @@ void pci_init_board(void) struct pci_controller *hose = &pcie1_hose; int pcie_ep = (host_agent <= 1) || (host_agent == 4) || (host_agent == 5); - int pcie_configured = io_sel & 6; + int pcie_configured = (io_sel == 0x2) || (io_sel == 0x3) || + (io_sel == 0x7) || (io_sel == 0xb) || + (io_sel == 0xc) || (io_sel == 0xf); struct pci_region *r = hose->regions; if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ -- cgit v1.1 From 028e116811d28a031660f1ad9e20ac1293b3c5c7 Mon Sep 17 00:00:00 2001 From: Roy Zang Date: Fri, 9 Jan 2009 16:01:52 +0800 Subject: PCIE2 and PCIE3 are decided by corresponing bit in devdisr instead of PCIE1 bit PCIE2 and PCIE3 should be decided by corresponing bit in devdisr instead of PCIE1 bit. On MPC8572DS board, PCIE refers to PCIE1. Signed-off-by: Roy Zang --- board/freescale/mpc8572ds/mpc8572ds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index 4733b82..c2487e5 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -170,7 +170,7 @@ void pci_init_board(void) struct pci_region *r = hose->regions; u32 temp32; - if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ + if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE3)){ printf ("\n PCIE3 connected to ULI as %s (base address %x)", pcie_ep ? "End Point" : "Root Complex", (uint)pci); @@ -237,7 +237,7 @@ void pci_init_board(void) int pcie_configured = (io_sel == 0x3) || (io_sel == 0x7); struct pci_region *r = hose->regions; - if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ + if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE2)){ printf ("\n PCIE2 connected to Slot 1 as %s (base address %x)", pcie_ep ? "End Point" : "Root Complex", (uint)pci); -- cgit v1.1 From 6d3a10f73ece7ffb736890c10e023222612a4aa0 Mon Sep 17 00:00:00 2001 From: Roy Zang Date: Fri, 9 Jan 2009 16:02:35 +0800 Subject: Change PCIE1&2 deciide logic on MPC8544DS board more readable The IO port selection for MPC8544DS board: Port cfg_io_ports PCIE1 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 PCIE2 0x4, 0x5, 0x6, 0x7 PCIE3 0x6, 0x7 This patch changes the PCIE12 and PCIE2 logic more readable. Signed-off-by: Roy Zang --- board/freescale/mpc8544ds/mpc8544ds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/freescale/mpc8544ds/mpc8544ds.c b/board/freescale/mpc8544ds/mpc8544ds.c index 13c55fd..9777312 100644 --- a/board/freescale/mpc8544ds/mpc8544ds.c +++ b/board/freescale/mpc8544ds/mpc8544ds.c @@ -188,7 +188,7 @@ pci_init_board(void) volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR; struct pci_controller *hose = &pcie1_hose; int pcie_ep = (host_agent == 5); - int pcie_configured = io_sel & 6; + int pcie_configured = io_sel >= 2; struct pci_region *r = hose->regions; if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ @@ -251,7 +251,7 @@ pci_init_board(void) volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR; struct pci_controller *hose = &pcie2_hose; int pcie_ep = (host_agent == 3); - int pcie_configured = io_sel & 4; + int pcie_configured = io_sel >= 4; struct pci_region *r = hose->regions; if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){ -- cgit v1.1 From 950264317eb9594b2b5ee2fb65206200a1c6007a Mon Sep 17 00:00:00 2001 From: Haiying Wang Date: Tue, 13 Jan 2009 16:29:22 -0500 Subject: Change DDR tlb start entry to CONFIG param for 85xx So that we can locate the DDR tlb start entry to the value other than 8. By default, it is still 8. Signed-off-by: Haiying Wang --- cpu/mpc85xx/tlb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpu/mpc85xx/tlb.c b/cpu/mpc85xx/tlb.c index 5b5f791..25fa9ee 100644 --- a/cpu/mpc85xx/tlb.c +++ b/cpu/mpc85xx/tlb.c @@ -125,6 +125,10 @@ void init_addr_map(void) } #endif +#ifndef CONFIG_SYS_DDR_TLB_START +#define CONFIG_SYS_DDR_TLB_START 8 +#endif + unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg) { unsigned int tlb_size; @@ -171,7 +175,7 @@ unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg) * Configure DDR TLB1 entries. * Starting at TLB1 8, use no more than 8 TLB1 entries. */ - ram_tlb_index = 8; + ram_tlb_index = CONFIG_SYS_DDR_TLB_START; ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE; while (ram_tlb_address < (memsize_in_meg * 1024 * 1024) && ram_tlb_index < 16) { -- cgit v1.1 From b5f65dfa9aa8e068e62aba4733dc4fd97b1d9bf6 Mon Sep 17 00:00:00 2001 From: Haiying Wang Date: Tue, 13 Jan 2009 16:29:28 -0500 Subject: Some changes of TLB entry setting for MPC8572DS - Move the TLB entry of PIXIS_BASE from TLB0 to TLB1[8], because in CAMP mode, all the TLB0 entries will be invalidated after cpu1 brings up kernel, thus cpu0 can not access PIXIS_BASE anymore (any access will cause DataTLBError exception) - Set CONFIG_SYS_DDR_TLB_START to 9 for MPC8572DS board. Signed-off-by: Haiying Wang --- board/freescale/mpc8572ds/tlb.c | 7 +++---- include/configs/MPC8572DS.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/board/freescale/mpc8572ds/tlb.c b/board/freescale/mpc8572ds/tlb.c index 8d1f646..829896a 100644 --- a/board/freescale/mpc8572ds/tlb.c +++ b/board/freescale/mpc8572ds/tlb.c @@ -41,10 +41,6 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, 0, 0, 0, BOOKE_PAGESZ_4K, 0), - SET_TLB_ENTRY(0, PIXIS_BASE, PIXIS_BASE, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 0, BOOKE_PAGESZ_4K, 0), - /* TLB 1 */ /* *I*** - Covers boot page */ SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, @@ -86,6 +82,9 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 7, BOOKE_PAGESZ_1M, 1), + SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 8, BOOKE_PAGESZ_4K, 1), }; int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 37c3f42..6c7a364 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -92,6 +92,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_CCSRBAR+0xa000) /* DDR Setup */ +#define CONFIG_SYS_DDR_TLB_START 9 #define CONFIG_FSL_DDR2 #undef CONFIG_FSL_DDR_INTERACTIVE #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */ -- cgit v1.1 From fceebb45a0b97e92f9889861f8c3b9cb885e706f Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Fri, 2 Jan 2009 12:16:35 +0100 Subject: ppc4xx: Enable auto RS485 mode on PLU405 boards This patch turns on the auto RS485 mode in the 2nd external uart on PLU405 boards. This is a special mode of the used Exar XR16C2850 uart. Because these boards only have a 485 physical layer connected it's a good idea to turn it on by default. Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/plu405/plu405.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/board/esd/plu405/plu405.c b/board/esd/plu405/plu405.c index 61186a8..85057a2 100644 --- a/board/esd/plu405/plu405.c +++ b/board/esd/plu405/plu405.c @@ -104,6 +104,7 @@ int misc_init_r (void) unsigned char *duart0_mcr = (unsigned char *)((ulong)DUART0_BA + 4); unsigned char *duart1_mcr = (unsigned char *)((ulong)DUART1_BA + 4); unsigned char *dst; + unsigned char fctr; ulong len = sizeof(fpgadata); int status; int index; @@ -203,6 +204,15 @@ int misc_init_r (void) out_8(duart0_mcr, 0x08); out_8(duart1_mcr, 0x08); + /* + * Enable auto RS485 mode in 2nd external uart + */ + out_8((void *)DUART1_BA + 3, 0xbf); /* write LCR */ + fctr = in_8((void *)DUART1_BA + 1); /* read FCTR */ + fctr |= 0x08; /* enable RS485 mode */ + out_8((void *)DUART1_BA + 1, fctr); /* write FCTR */ + out_8((void *)DUART1_BA + 3, 0); /* write LCR */ + return (0); } -- cgit v1.1 From f6a1f490d224c600a09137e58d1026d150b8e679 Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Fri, 2 Jan 2009 12:17:36 +0100 Subject: ppc4xx: Cleanup CPCI405 board code This patch cleans up CPCI405 board support: - wrap long lines - unification of spaces in function calls - remove dead code Use correct io accessors on peripherals. Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/cpci405/cpci405.c | 307 +++++++++++++++++++++----------------------- 1 file changed, 144 insertions(+), 163 deletions(-) diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c index c5ccb34..9bb5f63 100644 --- a/board/esd/cpci405/cpci405.c +++ b/board/esd/cpci405/cpci405.c @@ -20,7 +20,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ - #include #include #include @@ -31,16 +30,16 @@ DECLARE_GLOBAL_DATA_PTR; -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /*cmd_boot.c*/ -#if 0 -#define FPGA_DEBUG -#endif +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern void __ft_board_setup(void *blob, bd_t *bd); + +#undef FPGA_DEBUG /* fpga configuration data - generated by bin2cc */ const unsigned char fpgadata[] = { -#ifdef CONFIG_CPCI405_VER2 -# ifdef CONFIG_CPCI405AB +#if defined(CONFIG_CPCI405_VER2) +# if defined(CONFIG_CPCI405AB) # include "fpgadata_cpci405ab.c" # else # include "fpgadata_cpci4052.c" @@ -56,7 +55,7 @@ const unsigned char fpgadata[] = #include "../common/fpga.c" #include "../common/auto_update.h" -#ifdef CONFIG_CPCI405AB +#if defined(CONFIG_CPCI405AB) au_image_t au_image[] = { {"cpci405ab/preinst.img", 0, -1, AU_SCRIPT}, {"cpci405ab/pImage", 0xffc00000, 0x000c0000, AU_NOR}, @@ -65,7 +64,7 @@ au_image_t au_image[] = { {"cpci405ab/postinst.img", 0, 0, AU_SCRIPT}, }; #else -#ifdef CONFIG_CPCI405_VER2 +#if defined(CONFIG_CPCI405_VER2) au_image_t au_image[] = { {"cpci4052/preinst.img", 0, -1, AU_SCRIPT}, {"cpci4052/pImage", 0xffc00000, 0x000c0000, AU_NOR}, @@ -91,7 +90,7 @@ int cpci405_version(void); int gunzip(void *, int, unsigned char *, unsigned long *); void lxt971_no_sleep(void); -int board_early_init_f (void) +int board_early_init_f(void) { #ifndef CONFIG_CPCI405_VER2 int index, len, i; @@ -100,18 +99,19 @@ int board_early_init_f (void) #ifdef FPGA_DEBUG /* set up serial port with default baudrate */ - (void) get_clocks (); + (void)get_clocks(); gd->baudrate = CONFIG_BAUDRATE; - serial_init (); + serial_init(); console_init_f(); #endif /* - * First pull fpga-prg pin low, to disable fpga logic (on version 2 board) + * First pull fpga-prg pin low, + * to disable fpga logic (on version 2 board) */ out32(GPIO0_ODR, 0x00000000); /* no open drain pins */ - out32(GPIO0_TCR, CONFIG_SYS_FPGA_PRG); /* setup for output */ - out32(GPIO0_OR, CONFIG_SYS_FPGA_PRG); /* set output pins to high */ + out32(GPIO0_TCR, CONFIG_SYS_FPGA_PRG); /* setup for output */ + out32(GPIO0_OR, CONFIG_SYS_FPGA_PRG); /* set output pins to high */ out32(GPIO0_OR, 0); /* pull prg low */ /* @@ -124,39 +124,42 @@ int board_early_init_f (void) /* booting FPGA failed */ #ifndef FPGA_DEBUG /* set up serial port with default baudrate */ - (void) get_clocks (); + (void)get_clocks(); gd->baudrate = CONFIG_BAUDRATE; - serial_init (); + serial_init(); console_init_f(); #endif printf("\nFPGA: Booting failed "); switch (status) { case ERROR_FPGA_PRG_INIT_LOW: - printf("(Timeout: INIT not low after asserting PROGRAM*)\n "); + printf("(Timeout: INIT not low after " + "asserting PROGRAM*)\n "); break; case ERROR_FPGA_PRG_INIT_HIGH: - printf("(Timeout: INIT not high after deasserting PROGRAM*)\n "); + printf("(Timeout: INIT not high after " + "deasserting PROGRAM*)\n "); break; case ERROR_FPGA_PRG_DONE: - printf("(Timeout: DONE not high after programming FPGA)\n "); + printf("(Timeout: DONE not high after " + "programming FPGA)\n "); break; } /* display infos on fpgaimage */ index = 15; - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { len = fpgadata[index]; - printf("FPGA: %s\n", &(fpgadata[index+1])); - index += len+3; + printf("FPGA: %s\n", &(fpgadata[index + 1])); + index += len + 3; } - putc ('\n'); + putc('\n'); /* delayed reboot */ - for (i=20; i>0; i--) { + for (i = 20; i > 0; i--) { printf("Rebooting in %2d seconds \r",i); - for (index=0;index<1000;index++) + for (index = 0; index < 1000; index++) udelay(1000); } - putc ('\n'); + putc('\n'); do_reset(NULL, 0, 0, NULL); } } @@ -167,7 +170,7 @@ int board_early_init_f (void) * IRQ 16 405GP internally generated; active low; level sensitive * IRQ 17-24 RESERVED * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive - * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive + * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052); active low; level sens. * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive @@ -177,7 +180,7 @@ int board_early_init_f (void) mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ mtdcr(uicer, 0x00000000); /* disable all ints */ mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/ -#ifdef CONFIG_CPCI405_6U +#if defined(CONFIG_CPCI405_6U) if (cpci405_version() == 3) { mtdcr(uicpr, 0xFFFFFF99); /* set int polarities */ } else { @@ -187,21 +190,20 @@ int board_early_init_f (void) mtdcr(uicpr, 0xFFFFFF81); /* set int polarities */ #endif mtdcr(uictr, 0x10000000); /* set int trigger levels */ - mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/ + mtdcr(uicvcr, 0x00000001); /* set vect base=0, + * INT0 highest priority */ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ return 0; } -/* ------------------------------------------------------------------------- */ - int ctermm2(void) { -#ifdef CONFIG_CPCI405_VER2 +#if defined(CONFIG_CPCI405_VER2) return 0; /* no, board is cpci405 */ #else - if ((*(unsigned char *)0xf0000400 == 0x00) && - (*(unsigned char *)0xf0000401 == 0x01)) + if ((in_8((void*)0xf0000400) == 0x00) && + (in_8((void*)0xf0000401) == 0x01)) return 0; /* no, board is cpci405 */ else return -1; /* yes, board is cterm-m2 */ @@ -228,8 +230,8 @@ int cpci405_version(void) mtdcr(cntrl0, cntrl0Reg | 0x03000000); out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x00180000); out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x00180000); - udelay(1000); /* wait some time before reading input */ - value = in_be32((void*)GPIO0_IR) & 0x00180000; /* get config bits */ + udelay(1000); /* wait some time before reading input */ + value = in_be32((void*)GPIO0_IR) & 0x00180000; /* get config bits */ /* * Restore GPIO settings @@ -263,7 +265,7 @@ int misc_init_r (void) gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize; gd->bd->bi_flashoffset = 0; -#ifdef CONFIG_CPCI405_VER2 +#if defined(CONFIG_CPCI405_VER2) { unsigned char *dst; ulong len = sizeof(fpgadata); @@ -283,9 +285,10 @@ int misc_init_r (void) mtdcr(cntrl0, cntrl0Reg | 0x00300000); dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE); - if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) { - printf ("GUNZIP ERROR - must RESET board to recover\n"); - do_reset (NULL, 0, 0, NULL); + if (gunzip(dst, CONFIG_SYS_FPGA_MAX_SIZE, + (uchar *)fpgadata, &len) != 0) { + printf("GUNZIP ERROR - must RESET board to recover\n"); + do_reset(NULL, 0, 0, NULL); } status = fpga_boot(dst, len); @@ -293,31 +296,34 @@ int misc_init_r (void) printf("\nFPGA: Booting failed "); switch (status) { case ERROR_FPGA_PRG_INIT_LOW: - printf("(Timeout: INIT not low after asserting PROGRAM*)\n "); + printf("(Timeout: INIT not low after " + "asserting PROGRAM*)\n "); break; case ERROR_FPGA_PRG_INIT_HIGH: - printf("(Timeout: INIT not high after deasserting PROGRAM*)\n "); + printf("(Timeout: INIT not high after " + "deasserting PROGRAM*)\n "); break; case ERROR_FPGA_PRG_DONE: - printf("(Timeout: DONE not high after programming FPGA)\n "); + printf("(Timeout: DONE not high after " + "programming FPGA)\n "); break; } /* display infos on fpgaimage */ index = 15; - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { len = dst[index]; - printf("FPGA: %s\n", &(dst[index+1])); - index += len+3; + printf("FPGA: %s\n", &(dst[index + 1])); + index += len + 3; } - putc ('\n'); + putc('\n'); /* delayed reboot */ - for (i=20; i>0; i--) { - printf("Rebooting in %2d seconds \r",i); - for (index=0;index<1000;index++) + for (i = 20; i > 0; i--) { + printf("Rebooting in %2d seconds \r", i); + for (index = 0; index < 1000; index++) udelay(1000); } - putc ('\n'); + putc('\n'); do_reset(NULL, 0, 0, NULL); } @@ -328,12 +334,12 @@ int misc_init_r (void) /* display infos on fpgaimage */ index = 15; - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { len = dst[index]; - printf("%s ", &(dst[index+1])); - index += len+3; + printf("%s ", &(dst[index + 1])); + index += len + 3; } - putc ('\n'); + putc('\n'); free(dst); @@ -345,68 +351,48 @@ int misc_init_r (void) SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); udelay(1000); /* wait 1ms */ -#ifdef CONFIG_CPCI405_6U +#if defined(CONFIG_CPCI405_6U) +#error HIER GETH ES WEITER MIT IO ACCESSORS if (cpci405_version() == 3) { - volatile unsigned short *fpga_mode = (unsigned short *)CONFIG_SYS_FPGA_BASE_ADDR; - volatile unsigned char *leds = (unsigned char *)CONFIG_SYS_LED_ADDR; - /* * Enable outputs in fpga on version 3 board */ - *fpga_mode |= CONFIG_SYS_FPGA_MODE_ENABLE_OUTPUT; + out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR, + in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) | + CONFIG_SYS_FPGA_MODE_ENABLE_OUTPUT); /* * Set outputs to 0 */ - *leds = 0x00; + out_8((void*)CONFIG_SYS_LED_ADDR, 0x00); /* * Reset external DUART */ - *fpga_mode |= CONFIG_SYS_FPGA_MODE_DUART_RESET; + out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR, + in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) | + CONFIG_SYS_FPGA_MODE_DUART_RESET); udelay(100); - *fpga_mode &= ~(CONFIG_SYS_FPGA_MODE_DUART_RESET); + out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR, + in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) & + ~CONFIG_SYS_FPGA_MODE_DUART_RESET); } #endif } else { puts("\n*** U-Boot Version does not match Board Version!\n"); puts("*** CPCI-405 Version 1.x detected!\n"); - puts("*** Please use correct U-Boot version (CPCI405 instead of CPCI4052)!\n\n"); + puts("*** Please use correct U-Boot version " + "(CPCI405 instead of CPCI4052)!\n\n"); } } - #else /* CONFIG_CPCI405_VER2 */ - -#if 0 /* test-only: code-plug now not relavant for ip-address any more */ - /* - * Generate last byte of ip-addr from code-plug @ 0xf0000400 - */ - if (ctermm2()) { - char str[32]; - unsigned char ipbyte = *(unsigned char *)0xf0000400; - - /* - * Only overwrite ip-addr with allowed values - */ - if ((ipbyte != 0x00) && (ipbyte != 0xff)) { - bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte; - sprintf(str, "%ld.%ld.%ld.%ld", - (bd->bi_ip_addr & 0xff000000) >> 24, - (bd->bi_ip_addr & 0x00ff0000) >> 16, - (bd->bi_ip_addr & 0x0000ff00) >> 8, - (bd->bi_ip_addr & 0x000000ff)); - setenv("ipaddr", str); - } - } -#endif - if (cpci405_version() >= 2) { puts("\n*** U-Boot Version does not match Board Version!\n"); puts("*** CPCI-405 Board Version 2.x detected!\n"); - puts("*** Please use correct U-Boot version (CPCI4052 instead of CPCI405)!\n\n"); + puts("*** Please use correct U-Boot version " + "(CPCI4052 instead of CPCI405)!\n\n"); } - #endif /* CONFIG_CPCI405_VER2 */ /* @@ -415,46 +401,33 @@ int misc_init_r (void) cntrl0Reg = mfdcr(cntrl0); mtdcr(cntrl0, cntrl0Reg | 0x00001000); - return (0); + return 0; } /* * Check Board Identity: */ -int checkboard (void) +int checkboard(void) { #ifndef CONFIG_CPCI405_VER2 int index; int len; #endif char str[64]; - int i = getenv_r ("serial#", str, sizeof(str)); + int i = getenv_r("serial#", str, sizeof(str)); unsigned short ver; - puts ("Board: "); + puts("Board: "); - if (i == -1) { - puts ("### No HW ID - assuming CPCI405"); - } else { + if (i == -1) + puts("### No HW ID - assuming CPCI405"); + else puts(str); - } ver = cpci405_version(); printf(" (Ver %d.x, ", ver); -#if 0 /* test-only */ - if (ver >= 2) { - volatile u16 *fpga_status = (u16 *)CONFIG_SYS_FPGA_BASE_ADDR + 1; - - if (*fpga_status & CONFIG_SYS_FPGA_STATUS_FLASH) { - puts ("FLASH Bank B, "); - } else { - puts ("FLASH Bank A, "); - } - } -#endif - if (ctermm2()) { char str[4]; @@ -465,32 +438,31 @@ int checkboard (void) setenv("boardid", str); printf("CTERM-M2 - Id=%s)", str); } else { - if (cpci405_host()) { - puts ("PCI Host Version)"); - } else { - puts ("PCI Adapter Version)"); - } + if (cpci405_host()) + puts("PCI Host Version)"); + else + puts("PCI Adapter Version)"); } #ifndef CONFIG_CPCI405_VER2 - puts ("\nFPGA: "); + puts("\nFPGA: "); /* display infos on fpgaimage */ index = 15; - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { len = fpgadata[index]; - printf("%s ", &(fpgadata[index+1])); - index += len+3; + printf("%s ", &(fpgadata[index + 1])); + index += len + 3; } #endif - putc ('\n'); + putc('\n'); return 0; } void reset_phy(void) { -#ifdef CONFIG_LXT971_NO_SLEEP +#if defined(CONFIG_LXT971_NO_SLEEP) /* * Disable sleep mode in LXT971 @@ -499,25 +471,24 @@ void reset_phy(void) #endif } -#ifdef CONFIG_CPCI405_VER2 -#ifdef CONFIG_IDE_RESET - +#if defined(CONFIG_CPCI405_VER2) && defined (CONFIG_IDE_RESET) void ide_set_reset(int on) { - volatile unsigned short *fpga_mode = (unsigned short *)CONFIG_SYS_FPGA_BASE_ADDR; - /* * Assert or deassert CompactFlash Reset Pin */ - if (on) { /* assert RESET */ - *fpga_mode &= ~(CONFIG_SYS_FPGA_MODE_CF_RESET); - } else { /* release RESET */ - *fpga_mode |= CONFIG_SYS_FPGA_MODE_CF_RESET; + if (on) { /* assert RESET */ + out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR, + in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) & + ~CONFIG_SYS_FPGA_MODE_CF_RESET); + } else { /* release RESET */ + out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR, + in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) | + CONFIG_SYS_FPGA_MODE_CF_RESET); } } -#endif /* CONFIG_IDE_RESET */ -#endif /* CONFIG_CPCI405_VER2 */ +#endif /* CONFIG_IDE_RESET && CONFIG_CPCI405_VER2 */ #if defined(CONFIG_PCI) void cpci405_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev) @@ -552,15 +523,22 @@ int pci_pre_init(struct pci_controller *hose) } #endif /* defined(CONFIG_PCI) */ +#if defined(CONFIG_CPCI405AB) +#define ONE_WIRE_CLEAR out_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + \ + CONFIG_SYS_FPGA_MODE), \ + in_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + \ + CONFIG_SYS_FPGA_MODE)) | \ + CONFIG_SYS_FPGA_MODE_1WIRE_DIR) -#ifdef CONFIG_CPCI405AB +#define ONE_WIRE_SET out_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + \ + CONFIG_SYS_FPGA_MODE), \ + in_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + \ + CONFIG_SYS_FPGA_MODE)) & \ + ~CONFIG_SYS_FPGA_MODE_1WIRE_DIR) -#define ONE_WIRE_CLEAR (*(volatile unsigned short *)(CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_MODE) \ - |= CONFIG_SYS_FPGA_MODE_1WIRE_DIR) -#define ONE_WIRE_SET (*(volatile unsigned short *)(CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_MODE) \ - &= ~CONFIG_SYS_FPGA_MODE_1WIRE_DIR) -#define ONE_WIRE_GET (*(volatile unsigned short *)(CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_STATUS) \ - & CONFIG_SYS_FPGA_MODE_1WIRE) +#define ONE_WIRE_GET (in_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + \ + CONFIG_SYS_FPGA_STATUS)) & \ + CONFIG_SYS_FPGA_MODE_1WIRE) /* * Generate a 1-wire reset, return 1 if no presence detect was found, @@ -630,7 +608,7 @@ void OWWriteByte(int data) { int loop; - for (loop=0; loop<8; loop++) { + for (loop = 0; loop < 8; loop++) { OWWriteBit(data & 0x01); data >>= 1; } @@ -640,11 +618,10 @@ int OWReadByte(void) { int loop, result = 0; - for (loop=0; loop<8; loop++) { + for (loop = 0; loop < 8; loop++) { result >>= 1; - if (OWReadBit()) { + if (OWReadBit()) result |= 0x80; - } } return result; @@ -652,7 +629,7 @@ int OWReadByte(void) int do_onewire(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - volatile unsigned short val; + unsigned short val; int result; int i; unsigned char ow_id[6]; @@ -662,23 +639,25 @@ int do_onewire(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* * Clear 1-wire bit (open drain with pull-up) */ - val = *(volatile unsigned short *)0xf0400000; - val &= ~0x1000; /* clear 1-wire bit */ - *(volatile unsigned short *)0xf0400000 = val; + val = in_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + + CONFIG_SYS_FPGA_MODE)); + val &= ~CONFIG_SYS_FPGA_MODE_1WIRE; /* clear 1-wire bit */ + out_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + + CONFIG_SYS_FPGA_MODE), val); result = OWTouchReset(); - if (result != 0) { + if (result != 0) puts("No 1-wire device detected!\n"); - } OWWriteByte(0x33); /* send read rom command */ OWReadByte(); /* skip family code ( == 0x01) */ - for (i=0; i<6; i++) { + for (i = 0; i < 6; i++) ow_id[i] = OWReadByte(); - } ow_crc = OWReadByte(); /* read crc */ - sprintf(str, "%08X%04X", *(unsigned int *)&ow_id[0], *(unsigned short *)&ow_id[4]); + sprintf(str, "%08X%04X", + *(unsigned int *)&ow_id[0], + *(unsigned short *)&ow_id[4]); printf("Setting environment variable 'ow_id' to %s\n", str); setenv("ow_id", str); @@ -690,8 +669,8 @@ U_BOOT_CMD( NULL ); -#define CONFIG_SYS_I2C_EEPROM_ADDR_2 0x51 /* EEPROM CAT28WC32 */ -#define CONFIG_ENV_SIZE_2 0x800 /* 2048 bytes may be used for env vars*/ +#define CONFIG_SYS_I2C_EEPROM_ADDR_2 0x51 /* EEPROM CAT24WC32 */ +#define CONFIG_ENV_SIZE_2 0x800 /* 2048 bytes may be used for env vars */ /* * Write backplane ip-address... @@ -706,12 +685,14 @@ int do_get_bpip(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) IPaddr_t ipaddr; buf = malloc(CONFIG_ENV_SIZE_2); - if (eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR_2, 0, (uchar *)buf, CONFIG_ENV_SIZE_2)) { + if (eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR_2, 0, + (uchar *)buf, CONFIG_ENV_SIZE_2)) puts("\nError reading backplane EEPROM!\n"); - } else { - crc = crc32(0, (uchar *)(buf+4), CONFIG_ENV_SIZE_2-4); + else { + crc = crc32(0, (uchar *)(buf+4), CONFIG_ENV_SIZE_2 - 4); if (crc != *(ulong *)buf) { - printf("ERROR: crc mismatch %08lx %08lx\n", crc, *(ulong *)buf); + printf("ERROR: crc mismatch %08lx %08lx\n", + crc, *(ulong *)buf); return -1; } @@ -768,12 +749,12 @@ int do_set_bpip(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) memset(buf, 0, CONFIG_ENV_SIZE_2); sprintf(str, "bp_ip=%s", argv[1]); strcpy(buf+4, str); - crc = crc32(0, (uchar *)(buf+4), CONFIG_ENV_SIZE_2-4); + crc = crc32(0, (uchar *)(buf+4), CONFIG_ENV_SIZE_2 - 4); *(ulong *)buf = crc; - if (eeprom_write(CONFIG_SYS_I2C_EEPROM_ADDR_2, 0, (uchar *)buf, CONFIG_ENV_SIZE_2)) { + if (eeprom_write(CONFIG_SYS_I2C_EEPROM_ADDR_2, + 0, (uchar *)buf, CONFIG_ENV_SIZE_2)) puts("\nError writing backplane EEPROM!\n"); - } free(buf); -- cgit v1.1 From 600fe46fb3dab7f07604f9009904f31584415114 Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Fri, 2 Jan 2009 12:18:12 +0100 Subject: ppc4xx: Disable pci node in device tree on CPCI405 pci adapters Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/cpci405/cpci405.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c index 9bb5f63..bd569a6 100644 --- a/board/esd/cpci405/cpci405.c +++ b/board/esd/cpci405/cpci405.c @@ -21,6 +21,8 @@ * MA 02111-1307 USA */ #include +#include +#include #include #include #include @@ -523,6 +525,28 @@ int pci_pre_init(struct pci_controller *hose) } #endif /* defined(CONFIG_PCI) */ +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ + int rc; + + __ft_board_setup(blob, bd); + + /* + * Disable PCI in adapter mode. + */ + if (!cpci405_host()) { + rc = fdt_find_and_setprop(blob, "/plb/pci@ec000000", "status", + "disabled", sizeof("disabled"), 1); + if (rc) { + printf("Unable to update property status in PCI node, " + "err=%s\n", + fdt_strerror(rc)); + } + } +} +#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ + #if defined(CONFIG_CPCI405AB) #define ONE_WIRE_CLEAR out_be16((void*)(CONFIG_SYS_FPGA_BASE_ADDR + \ CONFIG_SYS_FPGA_MODE), \ -- cgit v1.1 From 3ba605d4beec649438539e7df97b5fedb26592fb Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Fri, 2 Jan 2009 12:18:49 +0100 Subject: ppc4xx: Add loadpci command to esd's CPCI4052 and CPCI405AB boards This patch adds esd's loadpci BSP command to CPCI4052 and CPCI405AB board. This requires CONFIG_CMD_BSP and CONFIG_PRAM. Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/cpci405/Makefile | 1 + include/configs/CPCI4052.h | 2 ++ include/configs/CPCI405AB.h | 3 +++ 3 files changed, 6 insertions(+) diff --git a/board/esd/cpci405/Makefile b/board/esd/cpci405/Makefile index 3867bd8..7516c22 100644 --- a/board/esd/cpci405/Makefile +++ b/board/esd/cpci405/Makefile @@ -29,6 +29,7 @@ endif LIB = $(obj)lib$(BOARD).a COBJS = $(BOARD).o flash.o ../common/misc.o ../common/auto_update.o +COBJS += ../common/cmd_loadpci.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/include/configs/CPCI4052.h b/include/configs/CPCI4052.h index e231fa7..d0b4d11 100644 --- a/include/configs/CPCI4052.h +++ b/include/configs/CPCI4052.h @@ -216,6 +216,8 @@ #define CONFIG_SYS_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Monitor */ #define CONFIG_SYS_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */ +#define CONFIG_PRAM 0 /* use pram variable to overwrite */ + /* * For booting Linux, the board info and command line data * have to be in the first 8 MB of memory, since this is diff --git a/include/configs/CPCI405AB.h b/include/configs/CPCI405AB.h index 2319c58..69c8c6e 100644 --- a/include/configs/CPCI405AB.h +++ b/include/configs/CPCI405AB.h @@ -92,6 +92,7 @@ #define CONFIG_CMD_I2C #define CONFIG_CMD_MII #define CONFIG_CMD_PING +#define CONFIG_CMD_BSP #define CONFIG_CMD_EEPROM @@ -212,6 +213,8 @@ #define CONFIG_SYS_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Monitor */ #define CONFIG_SYS_MALLOC_LEN (256 * 1024) /* Reserve 256 kB for malloc() */ +#define CONFIG_PRAM 0 /* use pram variable to overwrite */ + /* * For booting Linux, the board info and command line data * have to be in the first 8 MB of memory, since this is -- cgit v1.1 From e92c9a860e44c14513c8909ce4299e253a775eeb Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 14 Jan 2009 22:35:30 +0100 Subject: cpu/mpc824x/Makefile: fix warning with parallel builds Parallel builds would occasionally issue this build warning: ln: creating symbolic link `cpu/mpc824x/bedbug_603e.c': File exists Use "ln -sf" as quick work around for the issue. Signed-off-by: Wolfgang Denk --- cpu/mpc824x/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/mpc824x/Makefile b/cpu/mpc824x/Makefile index f249dd7..a57ad12 100644 --- a/cpu/mpc824x/Makefile +++ b/cpu/mpc824x/Makefile @@ -44,7 +44,7 @@ $(LIB): $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) $(obj)bedbug_603e.c: - ln -s $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c + ln -sf $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c ######################################################################### -- cgit v1.1 From 0e3ece33801e377be67ffa29f083421ad820f28b Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 14 Jan 2009 23:26:05 +0100 Subject: Prepare 2009.01-rc2 Update CHANGELOG. Signed-off-by: Wolfgang Denk --- CHANGELOG | 588 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 588 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 9af36c1..17c5691 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,579 @@ +commit e92c9a860e44c14513c8909ce4299e253a775eeb +Author: Wolfgang Denk +Date: Wed Jan 14 22:35:30 2009 +0100 + + cpu/mpc824x/Makefile: fix warning with parallel builds + + Parallel builds would occasionally issue this build warning: + + ln: creating symbolic link `cpu/mpc824x/bedbug_603e.c': File exists + + Use "ln -sf" as quick work around for the issue. + + Signed-off-by: Wolfgang Denk + +commit b5f65dfa9aa8e068e62aba4733dc4fd97b1d9bf6 +Author: Haiying Wang +Date: Tue Jan 13 16:29:28 2009 -0500 + + Some changes of TLB entry setting for MPC8572DS + + - Move the TLB entry of PIXIS_BASE from TLB0 to TLB1[8], because in CAMP mode, + all the TLB0 entries will be invalidated after cpu1 brings up kernel, thus cpu0 + can not access PIXIS_BASE anymore (any access will cause DataTLBError exception) + + - Set CONFIG_SYS_DDR_TLB_START to 9 for MPC8572DS board. + + Signed-off-by: Haiying Wang + +commit 950264317eb9594b2b5ee2fb65206200a1c6007a +Author: Haiying Wang +Date: Tue Jan 13 16:29:22 2009 -0500 + + Change DDR tlb start entry to CONFIG param for 85xx + + So that we can locate the DDR tlb start entry to the value other than 8. By + default, it is still 8. + + Signed-off-by: Haiying Wang + +commit 6d3a10f73ece7ffb736890c10e023222612a4aa0 +Author: Roy Zang +Date: Fri Jan 9 16:02:35 2009 +0800 + + Change PCIE1&2 deciide logic on MPC8544DS board more readable + + The IO port selection for MPC8544DS board: + Port cfg_io_ports + PCIE1 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 + PCIE2 0x4, 0x5, 0x6, 0x7 + PCIE3 0x6, 0x7 + This patch changes the PCIE12 and PCIE2 logic more readable. + Signed-off-by: Roy Zang + +commit 028e116811d28a031660f1ad9e20ac1293b3c5c7 +Author: Roy Zang +Date: Fri Jan 9 16:01:52 2009 +0800 + + PCIE2 and PCIE3 are decided by corresponing bit in devdisr instead of PCIE1 bit + + PCIE2 and PCIE3 should be decided by corresponing bit in devdisr instead of + PCIE1 bit. + On MPC8572DS board, PCIE refers to PCIE1. + Signed-off-by: Roy Zang + +commit 9afc2ef0307aecf52482df67c31b75d5f9e66b47 +Author: Roy Zang +Date: Fri Jan 9 16:00:55 2009 +0800 + + Fix IO port selection issue on MPC8544DS and MPC8572DS boards + + The IO port selection is not correct on MPC8572DS and MPC8544DS board. + This patch fixes this issue. + For MPC8572 + Port cfg_io_ports + PCIE1 0x2, 0x3, 0x7, 0xb, 0xc, 0xf + PCIE2 0x3, 0x7 + PCIE3 0x7 + + For MPC8544 + Port cfg_io_ports + PCIE1 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 + PCIE2 0x4, 0x5, 0x6, 0x7 + PCIE3 0x6, 0x7 + Signed-off-by: Roy Zang + +commit 3e3fffe3baf3befde287fec1fcbfe55052fb8946 +Author: Becky Bruce +Date: Wed Dec 3 22:36:44 2008 -0600 + + mpc8610hpcd: Fix PCI mapping concepts + + Rename _BASE to _BUS, as it's actually a PCI bus address, + separate virtual and physical addresses into _VIRT and _PHYS, + and use each appopriately. This makes the code easier to read + and understand, and facilitates mapping changes going forward. + + Signed-off-by: Becky Bruce + +commit 79e436cad3b4a7db88408c3f05175028f30d700d +Author: Becky Bruce +Date: Wed Dec 3 22:36:26 2008 -0600 + + sbc8641d: Fix PCI mapping concepts + + Rename _BASE to _BUS, as it's actually a PCI bus address, + separate virtual and physical addresses into _VIRT and _PHYS, + and use each appopriately. This makes the code easier to read + and understand, and facilitates mapping changes going forward. + + Signed-off-by: Becky Bruce + +commit a9f3acbcd07da72b5446ce557531a3ed8b8beff0 +Author: Wolfgang Denk +Date: Mon Jan 12 14:50:35 2009 +0100 + + MPC86xx: fix build warnings + + Signed-off-by: Wolfgang Denk + +commit 032a1c934ef4dc003281f57302b6e693062c1868 +Author: Mike Frysinger +Date: Mon Jan 5 16:09:44 2009 -0500 + + bf537-stamp/nand: fix board_nand_init prototype + + The board_nand_init() function should return an int, not void. + + Signed-off-by: Mike Frysinger + +commit 687f952e4119594ab913be11c90f7f018c2a7a79 +Author: Mike Frysinger +Date: Thu Dec 11 07:04:48 2008 -0500 + + Blackfin: drop CONFIG_SPI handling in board init + + The eeprom SPI init functions are duplicated as the common code already + executes these for us. + + Signed-off-by: Mike Frysinger + +commit e7e684b10d73a303902208594c7c3e7e0d753282 +Author: Mike Frysinger +Date: Fri Oct 24 17:51:57 2008 -0400 + + Blackfin: fix out-of-tree building with ldscripts + + Many of the Blackfin board linker scripts are preprocessed, so make sure we + output the linker script into the build tree rather than the source tree. + + Signed-off-by: Mike Frysinger + +commit b9eecc342f767b50e1476fbc1aad7d88dd4ce5eb +Author: Mike Frysinger +Date: Fri Oct 24 17:48:54 2008 -0400 + + Blackfin: fix linker scripts to work with --gc-sections + + Make sure all .text sections get pulled in and the entry point is properly + referenced so they don't get discarded when linking with --gc-sections. + + Signed-off-by: Mike Frysinger + +commit 509fc553bc6087a6f705b3bf52f3950d7d1eaa58 +Author: Mike Frysinger +Date: Sat Oct 11 20:45:44 2008 -0400 + + Blackfin: set proper LDRFLAGS for parallel booting LDRs + + In order to boot an LDR out of parallel flash, the ldr utility needs a few + flags to tell it to generate the right header. + + Signed-off-by: Mike Frysinger + +commit 3dd9395a0d7ce69a335d0e743c04b9caedd681d3 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Jan 6 21:41:59 2009 +0100 + + at91rm9200: move define from lowlevel_init to header + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 8a48686fac2030287765f1970ea046bd5734b733 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Jan 3 17:22:26 2009 +0100 + + m501sk: move to the common memory setup + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit d481c80d78f954133c035dae6c7d22de3625795d +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Jan 3 17:22:25 2009 +0100 + + at91rm9200: rename lowlevel init value to CONFIG_SYS_ + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 4e170b16625291aa10d0d9abc3f34e8a5945d157 +Author: Nicolas Ferre +Date: Tue Jan 6 21:13:14 2009 +0100 + + at91: add at91sam9xeek board support + + At91sam9xe is basically an at91sam9260 with embedded flash. We can manage + it as another entry for at91sam9260 in the Makefile. + + Check documentation at : + http://www.atmel.com/dyn/products/product_card.asp?part_id=4263 + + Signed-off-by: Nicolas Ferre + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 9ffd53db870a7da134f9a1ae76894a6b31237be5 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Jan 6 21:15:57 2009 +0100 + + fix bmp_logo.h make dependencies to allow parallel build + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit e12d9a8fb48d24176efffccc072b445e60a3afe4 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Jan 3 17:22:24 2009 +0100 + + at91: Fix Atmel's at91sam9 boards out of tree build + + introduced in commit 89a7a87f084c + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 0668236bafaa1c11c521652a2facebc74beecbf0 +Author: Wolfgang Denk +Date: Tue Dec 30 22:56:11 2008 +0100 + + README: update mailing list name and hits to patch submission. + + Signed-off-by: Wolfgang Denk + +commit d9011f9b75561a0bd9254934c2bb2bc799d4f645 +Author: Peter Tyser +Date: Tue Dec 23 16:32:01 2008 -0600 + + 85xx: Enable inbound PCI config cycles for X-ES boards cleanup + + Signed-off-by: Peter Tyser + +commit 1f03cbfae221b24ba1341a0a3f62ff01c5c874df +Author: Peter Tyser +Date: Tue Dec 23 16:32:00 2008 -0600 + + XPedite5200 board support cleanup + + Signed-off-by: Peter Tyser + +commit fea91edee8ae0295e3c30b1ff544df51f4d668e1 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Dec 2 21:58:04 2008 +0100 + + usb_kbd: fix usb_kbd_deregister when DEVICE_DEREGISTER not enable + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Remy Böhmer + +commit ada591d2a0ecff5f9bc5ed1ebf310f439c3d0a28 +Author: Trent Piepho +Date: Wed Dec 3 15:16:37 2008 -0800 + + mpc8[56]xx: Put localbus clock in sysinfo and gd + + Currently MPC85xx and MPC86xx boards just calculate the localbus frequency + and print it out, but don't save it. + + This changes where its calculated and stored to be more consistent with the + CPU, CCB, TB, and DDR frequencies and the MPC83xx localbus clock. + + The localbus frequency is added to sysinfo and calculated when sysinfo is + set up, in cpu/mpc8[56]xx/speed.c, the same as the other frequencies are. + + get_clocks() copies the frequency into the global data, as the other + frequencies are, into a new field that is only enabled for MPC85xx and + MPC86xx. + + checkcpu() in cpu/mpc8[56]xx/cpu.c will print out the local bus frequency + from sysinfo, like the other frequencies, instead of calculating it on the + spot. + + Signed-off-by: Trent Piepho + Acked-by: Kumar Gala + Acked-by: Jon Loeliger + +commit 9863d6aca11405e1e0d8aba2045d78aeec4d4ee7 +Author: Trent Piepho +Date: Wed Dec 3 15:16:36 2008 -0800 + + mpc86xx: Double local bus clock divider + + The local bus clock divider should be doubled for both 8610 and 8641. + + Signed-off-by: Trent Piepho + Acked-by: Kumar Gala + Acked-by: Jon Loeliger + +commit 446c381e3e16f19857b72ea0d06241267b8b9d58 +Author: Trent Piepho +Date: Wed Dec 3 15:16:35 2008 -0800 + + mpc8568: Double local bus clock divider + + The clock divider for the MPC8568 local bus should be doubled, like the + other newer MPC85xx chips. + + Since there are now more chips with a 2x divider than a 1x, and any new + 85xx chips will probably be 2x, invert the sense of the #if so that it + lists the 1x chips instead of the 2x ones. + + Signed-off-by: Trent Piepho + Acked-by: Kumar Gala + Acked-by: Jon Loeliger + +commit f51f07eb58fad12de9294ba4ee6c09a0ddeaee03 +Author: Dave Liu +Date: Tue Dec 16 12:09:27 2008 +0800 + + 85xx: Fix the boot window issue + + If one custom board is using the 8MB flash, it is set + as FLASH_BASE = 0xef000000, TEXT_BASE = 0xef780000. + The current start.S code will be broken at switch_as. + + It is because the TLB1[15] is set as 16MB page size, + EPN = TEXT_BASE & 0xff000000, RPN = 0xff000000. + + For the 8MB flash case, the EPN = 0xefxxxxxx, + RPN = 0xffxxxxxx. Assume the virt address of switch_as + is 0xef7ff18c, the real address of the instruction at + switch_as should be 0xff7ff18c. the 0xff7ff18c is out + of the range of the default 8MB boot LAW window + 0xff800000 - 0xffffffff. + + So when we switch to AS1 address space at switch_as, + the core can't fetch the instruction at switch_as any + more. It will cause broken issue. + + Signed-off-by: Dave Liu + +commit 58da8890d5fbd074746037722a423de9ac408616 +Author: Paul Gortmaker +Date: Thu Dec 11 15:47:50 2008 -0500 + + sbc8548: use proper PHY address + + The values given for the PHY address were wrong, so the code + read no valid PHY ID, and fell through to the generic PHY + support, which would work on 1000M but would not auto negotiate + down to 100M or 10M. + + Signed-off-by: Paul Gortmaker + +commit ad22f9273c6f24fbfa917e867680e9688e0c59c5 +Author: Paul Gortmaker +Date: Thu Dec 11 15:47:51 2008 -0500 + + sbc8548: enable command line editing by default. + + Lets make things a bit more user friendly. It isn't 1985 anymore. + + Signed-off-by: Paul Gortmaker + +commit bd93105fa171184a71ca8b22be03dc2705cfbd3f +Author: Paul Gortmaker +Date: Thu Dec 11 15:47:49 2008 -0500 + + sbc8548: don't enable the 3rd and 4th eTSEC + + These interfaces don't have usable connectors on the board, so don't + bother enumerating or configuring them. + + Signed-off-by: Paul Gortmaker + +commit 181a3650113883728927928b3ac81ad6dade4b2c +Author: Haiying Wang +Date: Wed Dec 3 10:08:19 2008 -0500 + + Set IVPR to kenrel entry point in second core boot page + + Assuming the OSes exception vectors start from the base of kernel address, and + the kernel physical starting address can be relocated to an non-zero address. + This patch enables the second core to have a valid IVPR for debugger before + kernel setting IVPR in CAMP mode. Otherwise, IVPR is 0x0 and it is not a valid + value for second core which runs kernel at different physical address other + than 0x0. + + Signed-off-by: Haiying Wang + +commit a5d212a263c58cc746481bf1fc878510533ce7d6 +Author: Trent Piepho +Date: Wed Dec 3 15:16:34 2008 -0800 + + mpc8xxx: LCRR[CLKDIV] is sometimes five bits + + On newer CPUs, 8536, 8572, and 8610, the CLKDIV field of LCRR is five bits + instead of four. + + In order to avoid an ifdef, LCRR_CLKDIV is set to 0x1f on all systems. It + should be safe as the fifth bit was defined as reserved and set to 0. + + Code that was using a hard coded 0x0f is changed to use LCRR_CLKDIV. + + Signed-off-by: Trent Piepho + Acked-by: Kumar Gala + Acked-by: Jon Loeliger + +commit 58ec4866ed916c7e422f5107bb27b0822084728e +Author: Trent Piepho +Date: Wed Dec 3 15:16:38 2008 -0800 + + mpc8[56]xx: Put localbus clock in device tree + + Export the localbus frequency in the device tree, the same way the CPU, TB, + CCB, and various other frequencies are exported in their respective device + tree nodes. + + Some localbus devices need this information to be programed correctly, so + it makes sense to export it along with the other frequencies. + + Unfortunately, when someone wrote the localbus dts bindings, they didn't + bother to define what the "compatible" property should be. So it seems no + one was quite sure what to put in their dts files. + + Based on current existing dts files in the kernel source, I've used + "fsl,pq3-localbus" and "fsl,elbc" for MPC85xx, which are used by almost all + of the 85xx devices, and are looked for by the Linux code. The eLBC is + apparently not entirely backward compatible with the pq3 LBC and so eLBC + equipped platforms like 8572 won't use pq3-localbus. + + For MPC86xx, I've used "fsl,elbc" which is used by some of the 86xx systems + and is also looked for by the Linux code. On MPC8641, I've also used + "fsl,mpc8641-localbus" as it is also commonly used in dts files, some of + which don't use "fsl,elbc" or any other acceptable name to match on. + + Signed-off-by: Trent Piepho + Acked-by: Kumar Gala + Acked-by: Jon Loeliger + +commit 9d94aff699eed38b286814fcbb335f3eb8516a0e +Author: Kumar Gala +Date: Tue Dec 16 14:59:22 2008 -0600 + + NAND FSL elbc: Use virt_to_phys to determine which bank is in use + + The current code that determines which bank/chipselect is used for a + given NAND instance only worked for 32-bit addresses and assumed + a 1:1 mapping. This breaks in 36-bit physical configs. + + The proper way to handle this is to use the virt_to_phys() and + BR_PHYS_ADDR() routinues to match the 34-bit lbc bus address + with the the virtual address the NAND code uses. + + Signed-off-by: Kumar Gala + Acked-by: Scott Wood + +commit 77c8115b1f1871811633eae77a5a700fac1f0e50 +Author: Kumar Gala +Date: Tue Dec 16 14:59:21 2008 -0600 + + ppc: Use addrmap in virt_to_phys and map_physmem. + + If we have addr map support enabled use the mapping functions to + implement virt_to_phys() and map_physmem(). + + Signed-off-by: Kumar Gala + +commit ecf5b98c7a6a2e2256dfddd48fab26678dcd6b90 +Author: Kumar Gala +Date: Tue Dec 16 14:59:20 2008 -0600 + + 85xx: Add support to populate addr map based on TLB settings + + Signed-off-by: Kumar Gala + +commit 78bbc5ce151c5a484bb51bf1866b4a993ffc16ec +Author: Peter Tyser +Date: Mon Dec 1 13:47:13 2008 -0600 + + XPedite5200 board support + + Initial support for Extreme Engineering Solutions XPedite5200 - + a MPC8548-based PMC single board computer. + + Signed-off-by: Peter Tyser + +commit 487dcb4fb89be0992bc06ec1341090017bd9cf2f +Author: Peter Tyser +Date: Wed Oct 29 12:39:27 2008 -0500 + + 85xx: Enable inbound PCI config cycles for X-ES boards + + Update X-ES Freescale boards to allow inbound PCI configuration + cycles when configured as agent/endpoint. + + Signed-off-by: Peter Tyser + +commit ccf0fdd02b97323f8caae18d06cc9daeac2f192f +Author: Peter Tyser +Date: Wed Dec 17 16:36:23 2008 -0600 + + XPedite5370 board support + + Initial support for Extreme Engineering Solutions XPedite5370 - + a MPC8572-based 3U VPX single board computer with a PMC/XMC + site. + + Signed-off-by: Peter Tyser + +commit e92739d34e2d6b6aca93b2598248210710897ce8 +Author: Peter Tyser +Date: Wed Dec 17 16:36:21 2008 -0600 + + Add support for PCA953x I2C gpio devices + + Initial support for NXP's 4 and 8 bit I2C gpio expanders + (eg pca9537, pca9557, etc). The CONFIG_PCA953X define + enables support for the devices while the CONFIG_CMD_PCA953X + define enables the pca953x command. The CONFIG_CMD_PCA953X_INFO + define enables an 'info' sub-command which provides summary + information for the given pca953x device. + + Signed-off-by: Peter Tyser + +commit 7a8979591171676417ab36852d8811a8c46accd8 +Author: Peter Tyser +Date: Wed Oct 29 12:39:26 2008 -0500 + + pci/fsl_pci_init: Enable inbound PCI config cycles + + Add fsl_pci_config_unlock() function to enable a + PCI/PCIe interface configured in agent/endpoint mode to + respond to inbound PCI configuration cycles. + + Signed-off-by: Peter Tyser + +commit b616f2b545f73757669b37386f0b37bb61fc6797 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Mon Sep 8 22:27:18 2008 +0200 + + MIPS: qemu_mips: update doc to generate and to use qemu flash, ide file + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Shinya Kuribayashi + +commit 16cdf816779f5b602a9b3b4d2ea4dea05095c35b +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Dec 16 22:10:31 2008 +0100 + + MIPS: qemu_mips: update doc to use all disk and boot linux kernel + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Shinya Kuribayashi + +commit 13095b2f07dacb1f863772266c1789d47a523a8a +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Tue Dec 16 22:10:30 2008 +0100 + + MIPS: qemu_mips: move env storage just after u-boot + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Shinya Kuribayashi + +commit aced78d852d0b009e8aaa1445af8cb40861ee549 +Author: Wolfgang Denk +Date: Tue Dec 16 23:48:27 2008 +0100 + + Prepare 2009.01-rc1 + + Signed-off-by: Wolfgang Denk + commit 9e2a79b4c585ad31138fb90b68fd0234d64a8da8 Author: Wolfgang Denk Date: Tue Dec 16 23:13:46 2008 +0100 @@ -21,6 +597,18 @@ Date: Tue Dec 16 22:32:25 2008 +0100 Signed-off-by: Wolfgang Denk +commit ff49ea8977b56916edd5b1766d9939010e30b181 +Author: Scott Wood +Date: Tue Dec 16 14:24:16 2008 -0600 + + NAND: Mark the BBT as scanned prior to calling scan_bbt. + + Otherwise, recursion can occur if scan_bbt does not find a bad block + table, and tries to write one, and the attempt to erase the BBT area + causes a bad block check. + + Signed-off-by: Scott Wood + commit 584eedab66d0828f2d571a24b10526c4e65f547b Author: Ilya Yanok Date: Thu Dec 11 05:51:57 2008 +0300 -- cgit v1.1 From 1e15ff999322e81af4c0c0c548908f38944ba39c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 20 Dec 2008 15:25:22 +0100 Subject: sh: update sh timer coding style Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- lib_sh/time.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib_sh/time.c b/lib_sh/time.c index 2bd7715..8fccce3 100644 --- a/lib_sh/time.c +++ b/lib_sh/time.c @@ -49,21 +49,21 @@ int timer_init (void) { /* Divide clock by TMU_CLK_DIVIDER */ u16 bit = 0; - switch( TMU_CLK_DIVIDER ){ - case 4: - bit = 0; - break; - case 16: - bit = 1; - break; - case 64: bit = 2; + + switch (TMU_CLK_DIVIDER) { + case 1024: + bit = 4; break; case 256: bit = 3; break; - case 1024: - bit = 4; + case 64: + bit = 2; break; + case 16: + bit = 1; + break; + case 4: default: bit = 0; break; @@ -71,7 +71,7 @@ int timer_init (void) writew(readw(TCR0) | bit, TCR0); /* Clock adjustment calc */ - clk_adj = (int)(1.0/((1.0/CONFIG_SYS_HZ)*1000000)); + clk_adj = (int)(1.0 / ((1.0 / CONFIG_SYS_HZ) * 1000000)); if (clk_adj < 1) clk_adj = 1; @@ -102,8 +102,8 @@ void udelay (unsigned long usec) unsigned long get_timer (unsigned long base) { - /* return msec */ - return ((get_usec()/clk_adj)/1000) - base; + /* return msec */ + return ((get_usec() / clk_adj) / 1000) - base; } void set_timer (unsigned long t) -- cgit v1.1 From 85cb052ee41675ca361e6a4c69455dc715c8f2d9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 20 Dec 2008 15:27:45 +0100 Subject: sh: update sh2/sh2a timer coding style Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- lib_sh/time_sh2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_sh/time_sh2.c b/lib_sh/time_sh2.c index 4f893c8..5c6c9d4 100644 --- a/lib_sh/time_sh2.c +++ b/lib_sh/time_sh2.c @@ -28,7 +28,7 @@ #include #include -#define CMT_CMCSR_INIT 0x0001 /* PCLK/32 */ +#define CMT_CMCSR_INIT 0x0001 /* PCLK/32 */ #define CMT_CMCSR_CALIB 0x0000 #define CMT_MAX_COUNTER (0xFFFFFFFF) #define CMT_TIMER_RESET (0xFFFF) @@ -87,7 +87,7 @@ static unsigned long get_usec (void) /* return msec */ ulong get_timer(ulong base) { - return (get_usec()/1000) - base; + return (get_usec() / 1000) - base; } void set_timer(ulong t) -- cgit v1.1 From e4430779623af500de1cee7892c379f07ef59813 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 20 Dec 2008 19:29:48 +0100 Subject: sh: lowlevel_init coding style cleanup Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- board/mpr2/lowlevel_init.S | 44 ++-- board/ms7722se/lowlevel_init.S | 34 +-- board/ms7750se/lowlevel_init.S | 150 +++++------ board/renesas/MigoR/lowlevel_init.S | 10 +- board/renesas/ap325rxa/lowlevel_init.S | 86 +++--- board/renesas/r2dplus/lowlevel_init.S | 126 ++++----- board/renesas/r7780mp/lowlevel_init.S | 446 ++++++++++++++++---------------- board/renesas/rsk7203/lowlevel_init.S | 214 +++++++-------- board/renesas/sh7763rdp/lowlevel_init.S | 162 ++++++------ board/renesas/sh7785lcr/lowlevel_init.S | 2 +- 10 files changed, 640 insertions(+), 634 deletions(-) diff --git a/board/mpr2/lowlevel_init.S b/board/mpr2/lowlevel_init.S index 060957a..187b5bb 100644 --- a/board/mpr2/lowlevel_init.S +++ b/board/mpr2/lowlevel_init.S @@ -33,17 +33,17 @@ lowlevel_init: /* * Set frequency multipliers and dividers in FRQCR. */ - mov.l WTCSR_A,r1 - mov.l WTCSR_D,r0 - mov.w r0,@r1 + mov.l WTCSR_A, r1 + mov.l WTCSR_D, r0 + mov.w r0, @r1 - mov.l WTCNT_A,r1 - mov.l WTCNT_D,r0 - mov.w r0,@r1 + mov.l WTCNT_A, r1 + mov.l WTCNT_D, r0 + mov.w r0, @r1 - mov.l FRQCR_A,r1 - mov.l FRQCR_D,r0 - mov.w r0,@r1 + mov.l FRQCR_A, r1 + mov.l FRQCR_D, r0 + mov.w r0, @r1 /* * Setup CS0 (Flash). @@ -112,21 +112,27 @@ WTCSR_D: .long 0xA507 /* divide by 4096 */ /* * Spansion S29GL256N11 @ 48 MHz */ -CS0BCR_D: .long 0x12490400 /* 1 idle cycle inserted, normal space, 16 bit */ -CS0WCR_D: .long 0x00000340 /* tSW=0.5ck, 6 wait cycles, NO external wait, tHW=0.5ck */ +/* 1 idle cycle inserted, normal space, 16 bit */ +CS0BCR_D: .long 0x12490400 +/* tSW=0.5ck, 6 wait cycles, NO external wait, tHW=0.5ck */ +CS0WCR_D: .long 0x00000340 /* * Samsung K4S511632B-UL75 @ 48 MHz * Micron MT48LC32M16A2-75 @ 48 MHz */ -CS3BCR_D: .long 0x10004400 /* CS3BCR = 0x10004400, minimum idle cycles, SDRAM, 16 bit */ -CS3WCR_D: .long 0x00000091 /* tRP=1ck, tRCD=1ck, CL=2, tRWL=2ck, tRC=4ck */ -SDCR_D1: .long 0x00000012 /* no refresh, 13 rows, 10 cols, NO bank active mode */ -SDCR_D2: .long 0x00000812 /* refresh */ -RTCSR_D: .long 0xA55A0008 /* 1/4, once */ -RTCNT_D: .long 0xA55A005D /* count 93 */ -RTCOR_D: .long 0xa55a005d /* count 93 */ -SDMR3_D: .long 0x440 /* mode register CL2, burst read and SINGLE WRITE */ +/* CS3BCR = 0x10004400, minimum idle cycles, SDRAM, 16 bit */ +CS3BCR_D: .long 0x10004400 +/* tRP=1ck, tRCD=1ck, CL=2, tRWL=2ck, tRC=4ck */ +CS3WCR_D: .long 0x00000091 +/* no refresh, 13 rows, 10 cols, NO bank active mode */ +SDCR_D1: .long 0x00000012 +SDCR_D2: .long 0x00000812 /* refresh */ +RTCSR_D: .long 0xA55A0008 /* 1/4, once */ +RTCNT_D: .long 0xA55A005D /* count 93 */ +RTCOR_D: .long 0xa55a005d /* count 93 */ +/* mode register CL2, burst read and SINGLE WRITE */ +SDMR3_D: .long 0x440 /* * Registers diff --git a/board/ms7722se/lowlevel_init.S b/board/ms7722se/lowlevel_init.S index 8b46595..3e887cf 100644 --- a/board/ms7722se/lowlevel_init.S +++ b/board/ms7722se/lowlevel_init.S @@ -29,11 +29,11 @@ #include /* - * Board specific low level init code, called _very_ early in the - * startup sequence. Relocation to SDRAM has not happened yet, no - * stack is available, bss section has not been initialised, etc. + * Board specific low level init code, called _very_ early in the + * startup sequence. Relocation to SDRAM has not happened yet, no + * stack is available, bss section has not been initialised, etc. * - * (Note: As no stack is available, no subroutines can be called...). + * (Note: As no stack is available, no subroutines can be called...). */ .global lowlevel_init @@ -203,7 +203,7 @@ bsc_init: mov #0x00, r0 ! SDMR3 data -> R0 mov.b r0, @r1 ! SDMR3 set - ! BL bit off (init = ON) (?!?) + ! BL bit off (init = ON) (?!?) stc sr, r0 ! BL bit off(init=ON) mov.l SR_MASK_D, r1 @@ -232,28 +232,28 @@ MSTPCR0_D: .long 0x00001001 MSTPCR2_D: .long 0xffffffff FRQCR_D: .long 0x07022538 -PSELA_A: .long 0xa405014E -PSELA_D: .word 0x0A10 +PSELA_A: .long 0xa405014E +PSELA_D: .word 0x0A10 .align 2 -DRVCR_A: .long 0xa405018A -DRVCR_D: .word 0x0554 +DRVCR_A: .long 0xa405018A +DRVCR_D: .word 0x0554 .align 2 -PCCR_A: .long 0xa4050104 -PCCR_D: .word 0x8800 +PCCR_A: .long 0xa4050104 +PCCR_D: .word 0x8800 .align 2 -PECR_A: .long 0xa4050108 -PECR_D: .word 0x0000 +PECR_A: .long 0xa4050108 +PECR_D: .word 0x0000 .align 2 -PJCR_A: .long 0xa4050110 -PJCR_D: .word 0x1000 +PJCR_A: .long 0xa4050110 +PJCR_D: .word 0x1000 .align 2 -PXCR_A: .long 0xa4050148 -PXCR_D: .word 0x0AAA +PXCR_A: .long 0xa4050148 +PXCR_D: .word 0x0AAA .align 2 CMNCR_A: .long CMNCR diff --git a/board/ms7750se/lowlevel_init.S b/board/ms7750se/lowlevel_init.S index d3e3cd5..de05dd9 100644 --- a/board/ms7750se/lowlevel_init.S +++ b/board/ms7750se/lowlevel_init.S @@ -31,118 +31,118 @@ #include #ifdef CONFIG_CPU_SH7751 -#define BCR2_D_VALUE 0x2FFC /* Area 1-6 width: 32/32/32/32/32/16 */ -#define WCR1_D_VALUE 0x02770771 /* DMA:0 A6:2 A3:0 A0:1 Others:15 */ +#define BCR2_D_VALUE 0x2FFC /* Area 1-6 width: 32/32/32/32/32/16 */ +#define WCR1_D_VALUE 0x02770771 /* DMA:0 A6:2 A3:0 A0:1 Others:15 */ #ifdef CONFIG_MARUBUN_PCCARD -#define WCR2_D_VALUE 0xFFFE4FE7 /* A6:15 A6B:7 A5:15 A5B:7 A4:15 - A3:2 A2:15 A1:15 A0:6 A0B:7 */ +#define WCR2_D_VALUE 0xFFFE4FE7 /* A6:15 A6B:7 A5:15 A5B:7 A4:15 + A3:2 A2:15 A1:15 A0:6 A0B:7 */ #else /* CONFIG_MARUBUN_PCCARD */ -#define WCR2_D_VALUE 0x7FFE4FE7 /* A6:3 A6B:7 A5:15 A5B:7 A4:15 - A3:2 A2:15 A1:15 A0:6 A0B:7 */ +#define WCR2_D_VALUE 0x7FFE4FE7 /* A6:3 A6B:7 A5:15 A5B:7 A4:15 + A3:2 A2:15 A1:15 A0:6 A0B:7 */ #endif /* CONFIG_MARUBUN_PCCARD */ -#define WCR3_D_VALUE 0x01777771 /* A6: 0-1 A5: 1-3 A4: 1-3 A3: 1-3 - A2: 1-3 A1: 1-3 A0: 0-1 */ -#define RTCOR_D_VALUE 0xA50D /* Write code A5, data 0D (~15us?) */ -#define SDMR3_ADDRESS 0xFF940088 /* SDMR3 address on 32-bit bus */ -#define MCR_D1_VALUE 0x100901B4 /* SDRAM 32-bit, CAS/RAS Refresh, ... */ -#define MCR_D2_VALUE 0x500901B4 /* Same w/MRSET now 1 (mode reg cmd) */ +#define WCR3_D_VALUE 0x01777771 /* A6: 0-1 A5: 1-3 A4: 1-3 A3: 1-3 + A2: 1-3 A1: 1-3 A0: 0-1 */ +#define RTCOR_D_VALUE 0xA50D /* Write code A5, data 0D (~15us?) */ +#define SDMR3_ADDRESS 0xFF940088 /* SDMR3 address on 32-bit bus */ +#define MCR_D1_VALUE 0x100901B4 /* SDRAM 32-bit, CAS/RAS Refresh, .. */ +#define MCR_D2_VALUE 0x500901B4 /* Same w/MRSET now 1 (mode reg cmd) */ #else /* CONFIG_CPU_SH7751 */ -#define BCR2_D_VALUE 0x2E3C /* Area 1-6 width: 32/32/64/16/32/16 */ -#define WCR1_D_VALUE 0x02720777 /* DMA:0 A6:2 A4:2 A3:0 Others:15 */ -#define WCR2_D_VALUE 0xFFFE4FFF /* A6:15 A6B:7 A5:15 A5B:7 A4:15 - A3:2 A2:15 A1:15 A0:15 A0B:7 */ -#define WCR3_D_VALUE 0x01717771 /* A6: 0-1 A5: 1-3 A4: 0-1 A3: 1-3 - A2: 1-3 A1: 1-3 A0: 0-1 */ -#define RTCOR_D_VALUE 0xA510 /* Write code A5, data 10 (~15us?) */ -#define SDMR3_ADDRESS 0xFF940110 /* SDMR3 address on 64-bit bus */ -#define MCR_D1_VALUE 0x8801001C /* SDRAM 64-bit, CAS/RAS Refresh, ... */ -#define MCR_D2_VALUE 0xC801001C /* Same w/MRSET now 1 (mode reg cmd) */ +#define BCR2_D_VALUE 0x2E3C /* Area 1-6 width: 32/32/64/16/32/16 */ +#define WCR1_D_VALUE 0x02720777 /* DMA:0 A6:2 A4:2 A3:0 Others:15 */ +#define WCR2_D_VALUE 0xFFFE4FFF /* A6:15 A6B:7 A5:15 A5B:7 A4:15 + A3:2 A2:15 A1:15 A0:15 A0B:7 */ +#define WCR3_D_VALUE 0x01717771 /* A6: 0-1 A5: 1-3 A4: 0-1 A3: 1-3 + A2: 1-3 A1: 1-3 A0: 0-1 */ +#define RTCOR_D_VALUE 0xA510 /* Write code A5, data 10 (~15us?) */ +#define SDMR3_ADDRESS 0xFF940110 /* SDMR3 address on 64-bit bus */ +#define MCR_D1_VALUE 0x8801001C /* SDRAM 64-bit, CAS/RAS Refresh, .. */ +#define MCR_D2_VALUE 0xC801001C /* Same w/MRSET now 1 (mode reg cmd) */ #endif /* CONFIG_CPU_SH7751 */ .global lowlevel_init .text - .align 2 + .align 2 lowlevel_init: - mov.l CCR_A, r1 ! CCR Address - mov.l CCR_D_DISABLE, r0 ! CCR Data - mov.l r0, @r1 + mov.l CCR_A, r1 ! CCR Address + mov.l CCR_D_DISABLE, r0 ! CCR Data + mov.l r0, @r1 init_bsc: - mov.l FRQCR_A,r1 /* FRQCR Address */ - mov.l FRQCR_D,r0 /* FRQCR Data */ - mov.w r0,@r1 + mov.l FRQCR_A, r1 /* FRQCR Address */ + mov.l FRQCR_D, r0 /* FRQCR Data */ + mov.w r0, @r1 - mov.l BCR1_A,r1 /* BCR1 Address */ - mov.l BCR1_D,r0 /* BCR1 Data */ - mov.l r0,@r1 + mov.l BCR1_A, r1 /* BCR1 Address */ + mov.l BCR1_D, r0 /* BCR1 Data */ + mov.l r0, @r1 - mov.l BCR2_A,r1 /* BCR2 Address */ - mov.l BCR2_D,r0 /* BCR2 Data */ - mov.w r0,@r1 + mov.l BCR2_A, r1 /* BCR2 Address */ + mov.l BCR2_D, r0 /* BCR2 Data */ + mov.w r0, @r1 - mov.l WCR1_A,r1 /* WCR1 Address */ - mov.l WCR1_D,r0 /* WCR1 Data */ - mov.l r0,@r1 + mov.l WCR1_A, r1 /* WCR1 Address */ + mov.l WCR1_D, r0 /* WCR1 Data */ + mov.l r0, @r1 - mov.l WCR2_A,r1 /* WCR2 Address */ - mov.l WCR2_D,r0 /* WCR2 Data */ - mov.l r0,@r1 + mov.l WCR2_A, r1 /* WCR2 Address */ + mov.l WCR2_D, r0 /* WCR2 Data */ + mov.l r0, @r1 - mov.l WCR3_A,r1 /* WCR3 Address */ - mov.l WCR3_D,r0 /* WCR3 Data */ - mov.l r0,@r1 + mov.l WCR3_A, r1 /* WCR3 Address */ + mov.l WCR3_D, r0 /* WCR3 Data */ + mov.l r0, @r1 - mov.l MCR_A,r1 /* MCR Address */ - mov.l MCR_D1,r0 /* MCR Data1 */ - mov.l r0,@r1 + mov.l MCR_A, r1 /* MCR Address */ + mov.l MCR_D1, r0 /* MCR Data1 */ + mov.l r0, @r1 - mov.l SDMR3_A,r1 /* Set SDRAM mode */ - mov #0,r0 - mov.b r0,@r1 + mov.l SDMR3_A, r1 /* Set SDRAM mode */ + mov #0, r0 + mov.b r0, @r1 ! Do you need PCMCIA setting? ! If so, please add the lines here... - mov.l RTCNT_A,r1 /* RTCNT Address */ - mov.l RTCNT_D,r0 /* RTCNT Data */ - mov.w r0,@r1 + mov.l RTCNT_A, r1 /* RTCNT Address */ + mov.l RTCNT_D, r0 /* RTCNT Data */ + mov.w r0, @r1 - mov.l RTCOR_A,r1 /* RTCOR Address */ - mov.l RTCOR_D,r0 /* RTCOR Data */ - mov.w r0,@r1 + mov.l RTCOR_A, r1 /* RTCOR Address */ + mov.l RTCOR_D, r0 /* RTCOR Data */ + mov.w r0, @r1 - mov.l RTCSR_A,r1 /* RTCSR Address */ - mov.l RTCSR_D,r0 /* RTCSR Data */ - mov.w r0,@r1 + mov.l RTCSR_A, r1 /* RTCSR Address */ + mov.l RTCSR_D, r0 /* RTCSR Data */ + mov.w r0, @r1 - mov.l RFCR_A,r1 /* RFCR Address */ - mov.l RFCR_D,r0 /* RFCR Data */ - mov.w r0,@r1 /* Clear reflesh counter */ + mov.l RFCR_A, r1 /* RFCR Address */ + mov.l RFCR_D, r0 /* RFCR Data */ + mov.w r0, @r1 /* Clear reflesh counter */ /* Wait DRAM refresh 30 times */ - mov #30,r3 + mov #30, r3 1: - mov.w @r1,r0 - extu.w r0,r2 - cmp/hi r3,r2 + mov.w @r1, r0 + extu.w r0, r2 + cmp/hi r3, r2 bf 1b - mov.l MCR_A,r1 /* MCR Address */ - mov.l MCR_D2,r0 /* MCR Data2 */ - mov.l r0,@r1 + mov.l MCR_A, r1 /* MCR Address */ + mov.l MCR_D2, r0 /* MCR Data2 */ + mov.l r0, @r1 - mov.l SDMR3_A,r1 /* Set SDRAM mode */ - mov #0,r0 - mov.b r0,@r1 + mov.l SDMR3_A, r1 /* Set SDRAM mode */ + mov #0, r0 + mov.b r0, @r1 rts - nop + nop .align 2 -CCR_A: .long CCR -CCR_D_DISABLE: .long 0x0808 +CCR_A: .long CCR +CCR_D_DISABLE: .long 0x0808 FRQCR_A: .long FRQCR FRQCR_D: #ifdef CONFIG_CPU_TYPE_R diff --git a/board/renesas/MigoR/lowlevel_init.S b/board/renesas/MigoR/lowlevel_init.S index 4c1900e..13c83bf 100644 --- a/board/renesas/MigoR/lowlevel_init.S +++ b/board/renesas/MigoR/lowlevel_init.S @@ -29,11 +29,11 @@ #include /* - * Board specific low level init code, called _very_ early in the - * startup sequence. Relocation to SDRAM has not happened yet, no - * stack is available, bss section has not been initialised, etc. + * Board specific low level init code, called _very_ early in the + * startup sequence. Relocation to SDRAM has not happened yet, no + * stack is available, bss section has not been initialised, etc. * - * (Note: As no stack is available, no subroutines can be called...). + * (Note: As no stack is available, no subroutines can be called...). */ .global lowlevel_init @@ -176,7 +176,7 @@ bsc_init: mov #0x00, r0 ! SDMR3 data -> R0 mov.b r0, @r1 ! SDMR3 set - ! BL bit off (init = ON) (?!?) + ! BL bit off (init = ON) (?!?) stc sr, r0 ! BL bit off(init=ON) mov.l SR_MASK_D, r1 diff --git a/board/renesas/ap325rxa/lowlevel_init.S b/board/renesas/ap325rxa/lowlevel_init.S index 4f66588..558e779 100644 --- a/board/renesas/ap325rxa/lowlevel_init.S +++ b/board/renesas/ap325rxa/lowlevel_init.S @@ -39,111 +39,111 @@ lowlevel_init: mov.l DRVCRA_A, r1 - mov.l DRVCRA_D, r0 + mov.l DRVCRA_D, r0 mov.w r0, @r1 mov.l DRVCRB_A, r1 - mov.l DRVCRB_D, r0 + mov.l DRVCRB_D, r0 mov.w r0, @r1 mov.l RWTCSR_A, r1 - mov.l RWTCSR_D1, r0 + mov.l RWTCSR_D1, r0 mov.w r0, @r1 mov.l RWTCNT_A, r1 - mov.l RWTCNT_D, r0 + mov.l RWTCNT_D, r0 mov.w r0, @r1 mov.l RWTCSR_A, r1 - mov.l RWTCSR_D2, r0 + mov.l RWTCSR_D2, r0 mov.w r0, @r1 mov.l FRQCR_A, r1 - mov.l FRQCR_D, r0 + mov.l FRQCR_D, r0 mov.l r0, @r1 mov.l CMNCR_A, r1 mov.l CMNCR_D, r0 mov.l r0, @r1 - mov.l CS0BCR_A ,r1 - mov.l CS0BCR_D ,r0 + mov.l CS0BCR_A, r1 + mov.l CS0BCR_D, r0 mov.l r0, @r1 - mov.l CS4BCR_A ,r1 - mov.l CS4BCR_D ,r0 + mov.l CS4BCR_A, r1 + mov.l CS4BCR_D, r0 mov.l r0, @r1 - mov.l CS5ABCR_A ,r1 - mov.l CS5ABCR_D ,r0 + mov.l CS5ABCR_A, r1 + mov.l CS5ABCR_D, r0 mov.l r0, @r1 - mov.l CS5BBCR_A ,r1 - mov.l CS5BBCR_D ,r0 + mov.l CS5BBCR_A, r1 + mov.l CS5BBCR_D, r0 mov.l r0, @r1 - mov.l CS6ABCR_A ,r1 - mov.l CS6ABCR_D ,r0 + mov.l CS6ABCR_A, r1 + mov.l CS6ABCR_D, r0 mov.l r0, @r1 - mov.l CS6BBCR_A ,r1 - mov.l CS6BBCR_D ,r0 + mov.l CS6BBCR_A, r1 + mov.l CS6BBCR_D, r0 mov.l r0, @r1 - mov.l CS0WCR_A ,r1 - mov.l CS0WCR_D ,r0 + mov.l CS0WCR_A, r1 + mov.l CS0WCR_D, r0 mov.l r0, @r1 - mov.l CS4WCR_A ,r1 - mov.l CS4WCR_D ,r0 + mov.l CS4WCR_A, r1 + mov.l CS4WCR_D, r0 mov.l r0, @r1 - mov.l CS5AWCR_A ,r1 - mov.l CS5AWCR_D ,r0 + mov.l CS5AWCR_A, r1 + mov.l CS5AWCR_D, r0 mov.l r0, @r1 - mov.l CS5BWCR_A ,r1 - mov.l CS5BWCR_D ,r0 + mov.l CS5BWCR_A, r1 + mov.l CS5BWCR_D, r0 mov.l r0, @r1 - mov.l CS6AWCR_A ,r1 - mov.l CS6AWCR_D ,r0 + mov.l CS6AWCR_A, r1 + mov.l CS6AWCR_D, r0 mov.l r0, @r1 - mov.l CS6BWCR_A ,r1 - mov.l CS6BWCR_D ,r0 + mov.l CS6BWCR_A, r1 + mov.l CS6BWCR_D, r0 mov.l r0, @r1 mov.l SBSC_SDCR_A, r1 - mov.l SBSC_SDCR_D1, r0 + mov.l SBSC_SDCR_D1, r0 mov.l r0, @r1 mov.l SBSC_SDWCR_A, r1 - mov.l SBSC_SDWCR_D, r0 + mov.l SBSC_SDWCR_D, r0 mov.l r0, @r1 mov.l SBSC_SDPCR_A, r1 - mov.l SBSC_SDPCR_D, r0 + mov.l SBSC_SDPCR_D, r0 mov.l r0, @r1 mov.l SBSC_RTCSR_A, r1 - mov.l SBSC_RTCSR_D, r0 + mov.l SBSC_RTCSR_D, r0 mov.l r0, @r1 mov.l SBSC_RTCNT_A, r1 - mov.l SBSC_RTCNT_D, r0 + mov.l SBSC_RTCNT_D, r0 mov.l r0, @r1 mov.l SBSC_RTCOR_A, r1 - mov.l SBSC_RTCOR_D, r0 + mov.l SBSC_RTCOR_D, r0 mov.l r0, @r1 mov.l SBSC_SDMR3_A1, r1 - mov.l SBSC_SDMR3_D, r0 + mov.l SBSC_SDMR3_D, r0 mov.b r0, @r1 mov.l SBSC_SDMR3_A2, r1 - mov.l SBSC_SDMR3_D, r0 + mov.l SBSC_SDMR3_D, r0 mov.b r0, @r1 mov.l SLEEP_CNT, r1 @@ -153,18 +153,18 @@ lowlevel_init: dt r1 mov.l SBSC_SDMR3_A3, r1 - mov.l SBSC_SDMR3_D, r0 + mov.l SBSC_SDMR3_D, r0 mov.b r0, @r1 mov.l SBSC_SDCR_A, r1 - mov.l SBSC_SDCR_D2, r0 + mov.l SBSC_SDCR_D2, r0 mov.l r0, @r1 mov.l CCR_A, r1 - mov.l CCR_D, r0 + mov.l CCR_D, r0 mov.l r0, @r1 - ! BL bit off (init = ON) (?!?) + ! BL bit off (init = ON) (?!?) stc sr, r0 ! BL bit off(init=ON) mov.l SR_MASK_D, r1 @@ -211,7 +211,7 @@ SBSC_SDMR3_D: .long 0x00 CMNCR_A: .long CMNCR CS0BCR_A: .long CS0BCR CS4BCR_A: .long CS4BCR -CS5ABCR_A: .long CS5ABCR +CS5ABCR_A: .long CS5ABCR CS5BBCR_A: .long CS5BBCR CS6ABCR_A: .long CS6ABCR CS6BBCR_A: .long CS6BBCR diff --git a/board/renesas/r2dplus/lowlevel_init.S b/board/renesas/r2dplus/lowlevel_init.S index 28d2b37..a057370 100644 --- a/board/renesas/r2dplus/lowlevel_init.S +++ b/board/renesas/r2dplus/lowlevel_init.S @@ -17,92 +17,92 @@ lowlevel_init: mov.l CCR_A, r1 mov.l CCR_D_D, r0 - mov.l r0,@r1 + mov.l r0, @r1 - mov.l MMUCR_A,r1 - mov.l MMUCR_D,r0 - mov.l r0,@r1 + mov.l MMUCR_A, r1 + mov.l MMUCR_D, r0 + mov.l r0, @r1 - mov.l BCR1_A,r1 - mov.l BCR1_D,r0 - mov.l r0,@r1 + mov.l BCR1_A, r1 + mov.l BCR1_D, r0 + mov.l r0, @r1 - mov.l BCR2_A,r1 - mov.l BCR2_D,r0 - mov.w r0,@r1 + mov.l BCR2_A, r1 + mov.l BCR2_D, r0 + mov.w r0, @r1 - mov.l BCR3_A,r1 - mov.l BCR3_D,r0 - mov.w r0,@r1 + mov.l BCR3_A, r1 + mov.l BCR3_D, r0 + mov.w r0, @r1 - mov.l BCR4_A,r1 - mov.l BCR4_D,r0 - mov.l r0,@r1 + mov.l BCR4_A, r1 + mov.l BCR4_D, r0 + mov.l r0, @r1 - mov.l WCR1_A,r1 - mov.l WCR1_D,r0 - mov.l r0,@r1 + mov.l WCR1_A, r1 + mov.l WCR1_D, r0 + mov.l r0, @r1 - mov.l WCR2_A,r1 - mov.l WCR2_D,r0 - mov.l r0,@r1 + mov.l WCR2_A, r1 + mov.l WCR2_D, r0 + mov.l r0, @r1 - mov.l WCR3_A,r1 - mov.l WCR3_D,r0 - mov.l r0,@r1 + mov.l WCR3_A, r1 + mov.l WCR3_D, r0 + mov.l r0, @r1 - mov.l PCR_A,r1 - mov.l PCR_D,r0 - mov.w r0,@r1 + mov.l PCR_A, r1 + mov.l PCR_D, r0 + mov.w r0, @r1 - mov.l LED_A,r1 - mov #0xff,r0 - mov.w r0,@r1 + mov.l LED_A, r1 + mov #0xff, r0 + mov.w r0, @r1 - mov.l MCR_A,r1 - mov.l MCR_D1,r0 - mov.l r0,@r1 + mov.l MCR_A, r1 + mov.l MCR_D1, r0 + mov.l r0, @r1 - mov.l RTCNT_A,r1 - mov.l RTCNT_D,r0 - mov.w r0,@r1 + mov.l RTCNT_A, r1 + mov.l RTCNT_D, r0 + mov.w r0, @r1 - mov.l RTCOR_A,r1 - mov.l RTCOR_D,r0 - mov.w r0,@r1 + mov.l RTCOR_A, r1 + mov.l RTCOR_D, r0 + mov.w r0, @r1 - mov.l RFCR_A,r1 - mov.l RFCR_D,r0 - mov.w r0,@r1 + mov.l RFCR_A, r1 + mov.l RFCR_D, r0 + mov.w r0, @r1 - mov.l RTCSR_A,r1 - mov.l RTCSR_D,r0 - mov.w r0,@r1 + mov.l RTCSR_A, r1 + mov.l RTCSR_D, r0 + mov.w r0, @r1 - mov.l SDMR3_A,r1 - mov #0x55,r0 - mov.b r0,@r1 + mov.l SDMR3_A, r1 + mov #0x55, r0 + mov.b r0, @r1 /* Wait DRAM refresh 30 times */ - mov.l RFCR_A,r1 - mov #30,r3 + mov.l RFCR_A, r1 + mov #30, r3 1: - mov.w @r1,r0 - extu.w r0,r2 - cmp/hi r3,r2 + mov.w @r1, r0 + extu.w r0, r2 + cmp/hi r3, r2 bf 1b - mov.l MCR_A,r1 - mov.l MCR_D2,r0 - mov.l r0,@r1 + mov.l MCR_A, r1 + mov.l MCR_D2, r0 + mov.l r0, @r1 - mov.l SDMR3_A,r1 - mov #0,r0 - mov.b r0,@r1 + mov.l SDMR3_A, r1 + mov #0, r0 + mov.b r0, @r1 - mov.l IRLMASK_A,r1 - mov.l IRLMASK_D,r0 - mov.l r0,@r1 + mov.l IRLMASK_A, r1 + mov.l IRLMASK_D, r0 + mov.l r0, @r1 mov.l CCR_A, r1 mov.l CCR_D_E, r0 diff --git a/board/renesas/r7780mp/lowlevel_init.S b/board/renesas/r7780mp/lowlevel_init.S index ab0499a..0df8c84 100644 --- a/board/renesas/r7780mp/lowlevel_init.S +++ b/board/renesas/r7780mp/lowlevel_init.S @@ -24,11 +24,11 @@ #include /* - * Board specific low level init code, called _very_ early in the - * startup sequence. Relocation to SDRAM has not happened yet, no - * stack is available, bss section has not been initialised, etc. + * Board specific low level init code, called _very_ early in the + * startup sequence. Relocation to SDRAM has not happened yet, no + * stack is available, bss section has not been initialised, etc. * - * (Note: As no stack is available, no subroutines can be called...). + * (Note: As no stack is available, no subroutines can be called...). */ .global lowlevel_init @@ -47,54 +47,54 @@ lowlevel_init: mov.l r0, @r1 /* pin_multi_setting */ - mov.l BBG_PMMR_A,r1 - mov.l BBG_PMMR_D_PMSR1,r0 - mov.l r0,@r1 + mov.l BBG_PMMR_A, r1 + mov.l BBG_PMMR_D_PMSR1, r0 + mov.l r0, @r1 - mov.l BBG_PMSR1_A,r1 - mov.l BBG_PMSR1_D,r0 - mov.l r0,@r1 + mov.l BBG_PMSR1_A, r1 + mov.l BBG_PMSR1_D, r0 + mov.l r0, @r1 - mov.l BBG_PMMR_A,r1 - mov.l BBG_PMMR_D_PMSR2,r0 - mov.l r0,@r1 + mov.l BBG_PMMR_A, r1 + mov.l BBG_PMMR_D_PMSR2, r0 + mov.l r0, @r1 - mov.l BBG_PMSR2_A,r1 - mov.l BBG_PMSR2_D,r0 - mov.l r0,@r1 + mov.l BBG_PMSR2_A, r1 + mov.l BBG_PMSR2_D, r0 + mov.l r0, @r1 - mov.l BBG_PMMR_A,r1 - mov.l BBG_PMMR_D_PMSR3,r0 - mov.l r0,@r1 + mov.l BBG_PMMR_A, r1 + mov.l BBG_PMMR_D_PMSR3, r0 + mov.l r0, @r1 - mov.l BBG_PMSR3_A,r1 - mov.l BBG_PMSR3_D,r0 - mov.l r0,@r1 + mov.l BBG_PMSR3_A, r1 + mov.l BBG_PMSR3_D, r0 + mov.l r0, @r1 - mov.l BBG_PMMR_A,r1 - mov.l BBG_PMMR_D_PMSR4,r0 - mov.l r0,@r1 + mov.l BBG_PMMR_A, r1 + mov.l BBG_PMMR_D_PMSR4, r0 + mov.l r0, @r1 - mov.l BBG_PMSR4_A,r1 - mov.l BBG_PMSR4_D,r0 - mov.l r0,@r1 + mov.l BBG_PMSR4_A, r1 + mov.l BBG_PMSR4_D, r0 + mov.l r0, @r1 - mov.l BBG_PMMR_A,r1 - mov.l BBG_PMMR_D_PMSRG,r0 - mov.l r0,@r1 + mov.l BBG_PMMR_A, r1 + mov.l BBG_PMMR_D_PMSRG, r0 + mov.l r0, @r1 - mov.l BBG_PMSRG_A,r1 - mov.l BBG_PMSRG_D,r0 - mov.l r0,@r1 + mov.l BBG_PMSRG_A, r1 + mov.l BBG_PMSRG_D, r0 + mov.l r0, @r1 /* cpg_setting */ - mov.l FRQCR_A,r1 - mov.l FRQCR_D,r0 - mov.l r0,@r1 + mov.l FRQCR_A, r1 + mov.l FRQCR_D, r0 + mov.l r0, @r1 - mov.l DLLCSR_A,r1 - mov.l DLLCSR_D,r0 - mov.l r0,@r1 + mov.l DLLCSR_A, r1 + mov.l DLLCSR_D, r0 + mov.l r0, @r1 nop nop @@ -108,111 +108,111 @@ lowlevel_init: nop /* wait 200us */ - mov.l REPEAT0_R3,r3 - mov #0,r2 + mov.l REPEAT0_R3, r3 + mov #0, r2 repeat0: - add #1,r2 - cmp/hs r3,r2 - bf repeat0 + add #1, r2 + cmp/hs r3, r2 + bf repeat0 nop /* bsc_setting */ - mov.l MMSELR_A,r1 - mov.l MMSELR_D,r0 - mov.l r0,@r1 + mov.l MMSELR_A, r1 + mov.l MMSELR_D, r0 + mov.l r0, @r1 - mov.l BCR_A,r1 - mov.l BCR_D,r0 - mov.l r0,@r1 + mov.l BCR_A, r1 + mov.l BCR_D, r0 + mov.l r0, @r1 - mov.l CS0BCR_A,r1 - mov.l CS0BCR_D,r0 - mov.l r0,@r1 + mov.l CS0BCR_A, r1 + mov.l CS0BCR_D, r0 + mov.l r0, @r1 - mov.l CS1BCR_A,r1 - mov.l CS1BCR_D,r0 - mov.l r0,@r1 + mov.l CS1BCR_A, r1 + mov.l CS1BCR_D, r0 + mov.l r0, @r1 - mov.l CS2BCR_A,r1 - mov.l CS2BCR_D,r0 - mov.l r0,@r1 + mov.l CS2BCR_A, r1 + mov.l CS2BCR_D, r0 + mov.l r0, @r1 - mov.l CS4BCR_A,r1 - mov.l CS4BCR_D,r0 - mov.l r0,@r1 + mov.l CS4BCR_A, r1 + mov.l CS4BCR_D, r0 + mov.l r0, @r1 - mov.l CS5BCR_A,r1 - mov.l CS5BCR_D,r0 - mov.l r0,@r1 + mov.l CS5BCR_A, r1 + mov.l CS5BCR_D, r0 + mov.l r0, @r1 - mov.l CS6BCR_A,r1 - mov.l CS6BCR_D,r0 - mov.l r0,@r1 + mov.l CS6BCR_A, r1 + mov.l CS6BCR_D, r0 + mov.l r0, @r1 - mov.l CS0WCR_A,r1 - mov.l CS0WCR_D,r0 - mov.l r0,@r1 + mov.l CS0WCR_A, r1 + mov.l CS0WCR_D, r0 + mov.l r0, @r1 - mov.l CS1WCR_A,r1 - mov.l CS1WCR_D,r0 - mov.l r0,@r1 + mov.l CS1WCR_A, r1 + mov.l CS1WCR_D, r0 + mov.l r0, @r1 - mov.l CS2WCR_A,r1 - mov.l CS2WCR_D,r0 - mov.l r0,@r1 + mov.l CS2WCR_A, r1 + mov.l CS2WCR_D, r0 + mov.l r0, @r1 - mov.l CS4WCR_A,r1 - mov.l CS4WCR_D,r0 - mov.l r0,@r1 + mov.l CS4WCR_A, r1 + mov.l CS4WCR_D, r0 + mov.l r0, @r1 - mov.l CS5WCR_A,r1 - mov.l CS5WCR_D,r0 - mov.l r0,@r1 + mov.l CS5WCR_A, r1 + mov.l CS5WCR_D, r0 + mov.l r0, @r1 - mov.l CS6WCR_A,r1 - mov.l CS6WCR_D,r0 - mov.l r0,@r1 + mov.l CS6WCR_A, r1 + mov.l CS6WCR_D, r0 + mov.l r0, @r1 - mov.l CS5PCR_A,r1 - mov.l CS5PCR_D,r0 - mov.l r0,@r1 + mov.l CS5PCR_A, r1 + mov.l CS5PCR_D, r0 + mov.l r0, @r1 - mov.l CS6PCR_A,r1 - mov.l CS6PCR_D,r0 - mov.l r0,@r1 + mov.l CS6PCR_A, r1 + mov.l CS6PCR_D, r0 + mov.l r0, @r1 /* ddr_setting */ /* wait 200us */ - mov.l REPEAT0_R3,r3 - mov #0,r2 + mov.l REPEAT0_R3, r3 + mov #0, r2 repeat1: - add #1,r2 - cmp/hs r3,r2 - bf repeat1 + add #1, r2 + cmp/hs r3, r2 + bf repeat1 nop - mov.l MIM_U_A,r0 - mov.l MIM_U_D,r1 + mov.l MIM_U_A, r0 + mov.l MIM_U_D, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco - mov.l MIM_L_A,r0 - mov.l MIM_L_D0,r1 + mov.l MIM_L_A, r0 + mov.l MIM_L_D0, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco - mov.l STR_L_A,r0 - mov.l STR_L_D,r1 + mov.l STR_L_A, r0 + mov.l STR_L_D, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco - mov.l SDR_L_A,r0 - mov.l SDR_L_D,r1 + mov.l SDR_L_A, r0 + mov.l SDR_L_D, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop @@ -220,193 +220,193 @@ repeat1: nop nop - mov.l SCR_L_A,r0 - mov.l SCR_L_D0,r1 + mov.l SCR_L_A, r0 + mov.l SCR_L_D0, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco - mov.l SCR_L_A,r0 - mov.l SCR_L_D1,r1 + mov.l SCR_L_A, r0 + mov.l SCR_L_D1, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l EMRS_A,r0 - mov.l EMRS_D,r1 + mov.l EMRS_A, r0 + mov.l EMRS_D, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l MRS1_A,r0 - mov.l MRS1_D,r1 + mov.l MRS1_A, r0 + mov.l MRS1_D, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l SCR_L_A,r0 - mov.l SCR_L_D2,r1 + mov.l SCR_L_A, r0 + mov.l SCR_L_D2, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l SCR_L_A,r0 - mov.l SCR_L_D3,r1 + mov.l SCR_L_A, r0 + mov.l SCR_L_D3, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l SCR_L_A,r0 - mov.l SCR_L_D4,r1 + mov.l SCR_L_A, r0 + mov.l SCR_L_D4, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l MRS2_A,r0 - mov.l MRS2_D,r1 + mov.l MRS2_A, r0 + mov.l MRS2_D, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco nop nop nop - mov.l SCR_L_A,r0 - mov.l SCR_L_D5,r1 + mov.l SCR_L_A, r0 + mov.l SCR_L_D5, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco /* wait 200us */ - mov.l REPEAT0_R1,r3 - mov #0,r2 + mov.l REPEAT0_R1, r3 + mov #0, r2 repeat2: - add #1,r2 - cmp/hs r3,r2 - bf repeat2 + add #1, r2 + cmp/hs r3, r2 + bf repeat2 synco - mov.l MIM_L_A,r0 - mov.l MIM_L_D1,r1 + mov.l MIM_L_A, r0 + mov.l MIM_L_D1, r1 synco - mov.l r1,@r0 + mov.l r1, @r0 synco rts nop .align 4 -RWTCSR_D_1: .word 0xA507 -RWTCSR_D_2: .word 0xA507 -RWTCNT_D: .word 0x5A00 +RWTCSR_D_1: .word 0xA507 +RWTCSR_D_2: .word 0xA507 +RWTCNT_D: .word 0x5A00 .align 2 -BBG_PMMR_A: .long 0xFF800010 -BBG_PMSR1_A: .long 0xFF800014 -BBG_PMSR2_A: .long 0xFF800018 -BBG_PMSR3_A: .long 0xFF80001C -BBG_PMSR4_A: .long 0xFF800020 -BBG_PMSRG_A: .long 0xFF800024 - -BBG_PMMR_D_PMSR1: .long 0xffffbffd -BBG_PMSR1_D: .long 0x00004002 -BBG_PMMR_D_PMSR2: .long 0xfc21a7ff -BBG_PMSR2_D: .long 0x03de5800 -BBG_PMMR_D_PMSR3: .long 0xfffffff8 -BBG_PMSR3_D: .long 0x00000007 -BBG_PMMR_D_PMSR4: .long 0xdffdfff9 -BBG_PMSR4_D: .long 0x20020006 -BBG_PMMR_D_PMSRG: .long 0xffffffff -BBG_PMSRG_D: .long 0x00000000 - -FRQCR_A: .long FRQCR -DLLCSR_A: .long 0xffc40010 -FRQCR_D: .long 0x40233035 -DLLCSR_D: .long 0x00000000 +BBG_PMMR_A: .long 0xFF800010 +BBG_PMSR1_A: .long 0xFF800014 +BBG_PMSR2_A: .long 0xFF800018 +BBG_PMSR3_A: .long 0xFF80001C +BBG_PMSR4_A: .long 0xFF800020 +BBG_PMSRG_A: .long 0xFF800024 + +BBG_PMMR_D_PMSR1: .long 0xffffbffd +BBG_PMSR1_D: .long 0x00004002 +BBG_PMMR_D_PMSR2: .long 0xfc21a7ff +BBG_PMSR2_D: .long 0x03de5800 +BBG_PMMR_D_PMSR3: .long 0xfffffff8 +BBG_PMSR3_D: .long 0x00000007 +BBG_PMMR_D_PMSR4: .long 0xdffdfff9 +BBG_PMSR4_D: .long 0x20020006 +BBG_PMMR_D_PMSRG: .long 0xffffffff +BBG_PMSRG_D: .long 0x00000000 + +FRQCR_A: .long FRQCR +DLLCSR_A: .long 0xffc40010 +FRQCR_D: .long 0x40233035 +DLLCSR_D: .long 0x00000000 /* for DDR-SDRAM */ -MIM_U_A: .long MIM_1 -MIM_L_A: .long MIM_2 -SCR_U_A: .long SCR_1 -SCR_L_A: .long SCR_2 -STR_U_A: .long STR_1 -STR_L_A: .long STR_2 -SDR_U_A: .long SDR_1 -SDR_L_A: .long SDR_2 - -EMRS_A: .long 0xFEC02000 -MRS1_A: .long 0xFEC00B08 -MRS2_A: .long 0xFEC00308 - -MIM_U_D: .long 0x00004000 -MIM_L_D0: .long 0x03e80009 -MIM_L_D1: .long 0x03e80209 -SCR_L_D0: .long 0x3 -SCR_L_D1: .long 0x2 -SCR_L_D2: .long 0x2 -SCR_L_D3: .long 0x4 -SCR_L_D4: .long 0x4 -SCR_L_D5: .long 0x0 -STR_L_D: .long 0x000f0000 -SDR_L_D: .long 0x00000400 -EMRS_D: .long 0x0 -MRS1_D: .long 0x0 -MRS2_D: .long 0x0 +MIM_U_A: .long MIM_1 +MIM_L_A: .long MIM_2 +SCR_U_A: .long SCR_1 +SCR_L_A: .long SCR_2 +STR_U_A: .long STR_1 +STR_L_A: .long STR_2 +SDR_U_A: .long SDR_1 +SDR_L_A: .long SDR_2 + +EMRS_A: .long 0xFEC02000 +MRS1_A: .long 0xFEC00B08 +MRS2_A: .long 0xFEC00308 + +MIM_U_D: .long 0x00004000 +MIM_L_D0: .long 0x03e80009 +MIM_L_D1: .long 0x03e80209 +SCR_L_D0: .long 0x3 +SCR_L_D1: .long 0x2 +SCR_L_D2: .long 0x2 +SCR_L_D3: .long 0x4 +SCR_L_D4: .long 0x4 +SCR_L_D5: .long 0x0 +STR_L_D: .long 0x000f0000 +SDR_L_D: .long 0x00000400 +EMRS_D: .long 0x0 +MRS1_D: .long 0x0 +MRS2_D: .long 0x0 /* Cache Controller */ -CCR_A: .long CCR -MMUCR_A: .long MMUCR -RWTCNT_A: .long WTCNT +CCR_A: .long CCR +MMUCR_A: .long MMUCR +RWTCNT_A: .long WTCNT -CCR_D: .long 0x0000090b -CCR_D_2: .long 0x00000103 -MMUCR_D: .long 0x00000004 -MSTPCR0_D: .long 0x00001001 -MSTPCR2_D: .long 0xffffffff +CCR_D: .long 0x0000090b +CCR_D_2: .long 0x00000103 +MMUCR_D: .long 0x00000004 +MSTPCR0_D: .long 0x00001001 +MSTPCR2_D: .long 0xffffffff /* local Bus State Controller */ -MMSELR_A: .long MMSELR -BCR_A: .long BCR -CS0BCR_A: .long CS0BCR -CS1BCR_A: .long CS1BCR -CS2BCR_A: .long CS2BCR -CS4BCR_A: .long CS4BCR -CS5BCR_A: .long CS5BCR -CS6BCR_A: .long CS6BCR -CS0WCR_A: .long CS0WCR -CS1WCR_A: .long CS1WCR -CS2WCR_A: .long CS2WCR -CS4WCR_A: .long CS4WCR -CS5WCR_A: .long CS5WCR -CS6WCR_A: .long CS6WCR -CS5PCR_A: .long CS5PCR -CS6PCR_A: .long CS6PCR +MMSELR_A: .long MMSELR +BCR_A: .long BCR +CS0BCR_A: .long CS0BCR +CS1BCR_A: .long CS1BCR +CS2BCR_A: .long CS2BCR +CS4BCR_A: .long CS4BCR +CS5BCR_A: .long CS5BCR +CS6BCR_A: .long CS6BCR +CS0WCR_A: .long CS0WCR +CS1WCR_A: .long CS1WCR +CS2WCR_A: .long CS2WCR +CS4WCR_A: .long CS4WCR +CS5WCR_A: .long CS5WCR +CS6WCR_A: .long CS6WCR +CS5PCR_A: .long CS5PCR +CS6PCR_A: .long CS6PCR MMSELR_D: .long 0xA5A50003 BCR_D: .long 0x00000000 @@ -425,5 +425,5 @@ CS6WCR_D: .long 0x77777703 CS5PCR_D: .long 0x77000000 CS6PCR_D: .long 0x77000000 -REPEAT0_R3: .long 0x00002000 -REPEAT0_R1: .long 0x0000200 +REPEAT0_R3: .long 0x00002000 +REPEAT0_R1: .long 0x0000200 diff --git a/board/renesas/rsk7203/lowlevel_init.S b/board/renesas/rsk7203/lowlevel_init.S index e4d6f9e..f6a6231 100644 --- a/board/renesas/rsk7203/lowlevel_init.S +++ b/board/renesas/rsk7203/lowlevel_init.S @@ -29,153 +29,153 @@ lowlevel_init: /* Cache setting */ - mov.l CCR1_A ,r1 - mov.l CCR1_D ,r0 - mov.l r0,@r1 + mov.l CCR1_A, r1 + mov.l CCR1_D, r0 + mov.l r0, @r1 /* ConfigurePortPins */ - mov.l PECRL3_A, r1 - mov.l PECRL3_D, r0 - mov.w r0,@r1 + mov.l PECRL3_A, r1 + mov.l PECRL3_D, r0 + mov.w r0, @r1 - mov.l PCCRL4_A, r1 - mov.l PCCRL4_D0, r0 - mov.w r0,@r1 + mov.l PCCRL4_A, r1 + mov.l PCCRL4_D0, r0 + mov.w r0, @r1 - mov.l PECRL4_A, r1 - mov.l PECRL4_D0, r0 - mov.w r0,@r1 + mov.l PECRL4_A, r1 + mov.l PECRL4_D0, r0 + mov.w r0, @r1 - mov.l PEIORL_A, r1 - mov.l PEIORL_D0, r0 - mov.w r0,@r1 + mov.l PEIORL_A, r1 + mov.l PEIORL_D0, r0 + mov.w r0, @r1 - mov.l PCIORL_A, r1 - mov.l PCIORL_D, r0 - mov.w r0,@r1 + mov.l PCIORL_A, r1 + mov.l PCIORL_D, r0 + mov.w r0, @r1 - mov.l PFCRH2_A, r1 - mov.l PFCRH2_D, r0 - mov.w r0,@r1 + mov.l PFCRH2_A, r1 + mov.l PFCRH2_D, r0 + mov.w r0, @r1 - mov.l PFCRH3_A, r1 - mov.l PFCRH3_D, r0 - mov.w r0,@r1 + mov.l PFCRH3_A, r1 + mov.l PFCRH3_D, r0 + mov.w r0, @r1 - mov.l PFCRH1_A, r1 - mov.l PFCRH1_D, r0 - mov.w r0,@r1 + mov.l PFCRH1_A, r1 + mov.l PFCRH1_D, r0 + mov.w r0, @r1 - mov.l PFIORH_A, r1 - mov.l PFIORH_D, r0 - mov.w r0,@r1 + mov.l PFIORH_A, r1 + mov.l PFIORH_D, r0 + mov.w r0, @r1 - mov.l PECRL1_A, r1 - mov.l PECRL1_D0, r0 - mov.w r0,@r1 + mov.l PECRL1_A, r1 + mov.l PECRL1_D0, r0 + mov.w r0, @r1 - mov.l PEIORL_A, r1 - mov.l PEIORL_D1, r0 - mov.w r0,@r1 + mov.l PEIORL_A, r1 + mov.l PEIORL_D1, r0 + mov.w r0, @r1 /* Configure Operating Frequency */ - mov.l WTCSR_A ,r1 - mov.l WTCSR_D0 ,r0 - mov.w r0,@r1 + mov.l WTCSR_A, r1 + mov.l WTCSR_D0, r0 + mov.w r0, @r1 - mov.l WTCSR_A ,r1 - mov.l WTCSR_D1 ,r0 - mov.w r0,@r1 + mov.l WTCSR_A, r1 + mov.l WTCSR_D1, r0 + mov.w r0, @r1 - mov.l WTCNT_A ,r1 - mov.l WTCNT_D ,r0 - mov.w r0,@r1 + mov.l WTCNT_A, r1 + mov.l WTCNT_D, r0 + mov.w r0, @r1 /* Set clock mode*/ - mov.l FRQCR_A,r1 - mov.l FRQCR_D,r0 - mov.w r0,@r1 + mov.l FRQCR_A, r1 + mov.l FRQCR_D, r0 + mov.w r0, @r1 /* Configure Bus And Memory */ init_bsc_cs0: - mov.l PCCRL4_A,r1 - mov.l PCCRL4_D1,r0 - mov.w r0,@r1 + mov.l PCCRL4_A, r1 + mov.l PCCRL4_D1, r0 + mov.w r0, @r1 - mov.l PECRL1_A,r1 - mov.l PECRL1_D1,r0 - mov.w r0,@r1 + mov.l PECRL1_A, r1 + mov.l PECRL1_D1, r0 + mov.w r0, @r1 - mov.l CMNCR_A,r1 - mov.l CMNCR_D,r0 - mov.l r0,@r1 + mov.l CMNCR_A, r1 + mov.l CMNCR_D, r0 + mov.l r0, @r1 - mov.l SC0BCR_A,r1 - mov.l SC0BCR_D,r0 - mov.l r0,@r1 + mov.l SC0BCR_A, r1 + mov.l SC0BCR_D, r0 + mov.l r0, @r1 - mov.l CS0WCR_A,r1 - mov.l CS0WCR_D,r0 - mov.l r0,@r1 + mov.l CS0WCR_A, r1 + mov.l CS0WCR_D, r0 + mov.l r0, @r1 init_bsc_cs1: - mov.l PECRL4_A,r1 - mov.l PECRL4_D1,r0 - mov.w r0,@r1 + mov.l PECRL4_A, r1 + mov.l PECRL4_D1, r0 + mov.w r0, @r1 - mov.l CS1WCR_A,r1 - mov.l CS1WCR_D,r0 - mov.l r0,@r1 + mov.l CS1WCR_A, r1 + mov.l CS1WCR_D, r0 + mov.l r0, @r1 init_sdram: - mov.l PCCRL2_A,r1 - mov.l PCCRL2_D,r0 - mov.w r0,@r1 + mov.l PCCRL2_A, r1 + mov.l PCCRL2_D, r0 + mov.w r0, @r1 - mov.l PCCRL4_A,r1 - mov.l PCCRL4_D2,r0 - mov.w r0,@r1 + mov.l PCCRL4_A, r1 + mov.l PCCRL4_D2, r0 + mov.w r0, @r1 - mov.l PCCRL1_A,r1 - mov.l PCCRL1_D,r0 - mov.w r0,@r1 + mov.l PCCRL1_A, r1 + mov.l PCCRL1_D, r0 + mov.w r0, @r1 - mov.l PCCRL3_A,r1 - mov.l PCCRL3_D,r0 - mov.w r0,@r1 + mov.l PCCRL3_A, r1 + mov.l PCCRL3_D, r0 + mov.w r0, @r1 - mov.l CS3BCR_A,r1 - mov.l CS3BCR_D,r0 - mov.l r0,@r1 + mov.l CS3BCR_A, r1 + mov.l CS3BCR_D, r0 + mov.l r0, @r1 - mov.l CS3WCR_A,r1 - mov.l CS3WCR_D,r0 - mov.l r0,@r1 + mov.l CS3WCR_A, r1 + mov.l CS3WCR_D, r0 + mov.l r0, @r1 - mov.l SDCR_A,r1 - mov.l SDCR_D,r0 - mov.l r0,@r1 + mov.l SDCR_A, r1 + mov.l SDCR_D, r0 + mov.l r0, @r1 - mov.l RTCOR_A,r1 - mov.l RTCOR_D,r0 - mov.l r0,@r1 + mov.l RTCOR_A, r1 + mov.l RTCOR_D, r0 + mov.l r0, @r1 - mov.l RTCSR_A,r1 - mov.l RTCSR_D,r0 - mov.l r0,@r1 + mov.l RTCSR_A, r1 + mov.l RTCSR_D, r0 + mov.l r0, @r1 /* wait 200us */ - mov.l REPEAT_D,r3 - mov #0,r2 + mov.l REPEAT_D, r3 + mov #0, r2 repeat0: - add #1,r2 - cmp/hs r3,r2 - bf repeat0 + add #1, r2 + cmp/hs r3, r2 + bf repeat0 nop - mov.l SDRAM_MODE, r1 - mov #0,r0 - mov.l r0, @r1 + mov.l SDRAM_MODE, r1 + mov #0, r0 + mov.l r0, @r1 nop rts @@ -208,8 +208,8 @@ PECRL1_D0: .long 0x00000033 WTCSR_A: .long 0xFFFE0000 -WTCSR_D0: .long 0x0000A518 -WTCSR_D1: .long 0x0000A51D +WTCSR_D0: .long 0x0000A518 +WTCSR_D1: .long 0x0000A51D WTCNT_A: .long 0xFFFE0002 WTCNT_D: .long 0x00005A84 FRQCR_A: .long 0xFFFE0010 @@ -259,7 +259,7 @@ STBCR4_A: .long 0xFFFE040C STBCR4_D: .long 0x00000008 STBCR5_A: .long 0xFFFE0410 STBCR5_D: .long 0x00000000 -STBCR6_A: .long 0xFFFE0414 +STBCR6_A: .long 0xFFFE0414 STBCR6_D: .long 0x00000002 SDRAM_MODE: .long 0xFFFC5040 REPEAT_D: .long 0x00009C40 diff --git a/board/renesas/sh7763rdp/lowlevel_init.S b/board/renesas/sh7763rdp/lowlevel_init.S index 2a44eee..715e75f 100644 --- a/board/renesas/sh7763rdp/lowlevel_init.S +++ b/board/renesas/sh7763rdp/lowlevel_init.S @@ -33,17 +33,17 @@ lowlevel_init: - mov.l WDTCSR_A, r1 /* Watchdog Control / Status Register */ - mov.l WDTCSR_D, r0 - mov.l r0, @r1 + mov.l WDTCSR_A, r1 /* Watchdog Control / Status Register */ + mov.l WDTCSR_D, r0 + mov.l r0, @r1 - mov.l WDTST_A, r1 /* Watchdog Stop Time Register */ - mov.l WDTST_D, r0 - mov.l r0, @r1 + mov.l WDTST_A, r1 /* Watchdog Stop Time Register */ + mov.l WDTST_D, r0 + mov.l r0, @r1 - mov.l WDTBST_A, r1 /* 0xFFCC0008 (Watchdog Base Stop Time Register */ - mov.l WDTBST_D, r0 - mov.l r0, @r1 + mov.l WDTBST_A, r1 /* 0xFFCC0008 (Watchdog Base Stop Time Register */ + mov.l WDTBST_D, r0 + mov.l r0, @r1 mov.l CCR_A, r1 /* Address of Cache Control Register */ mov.l CCR_CACHE_ICI_D, r0 /* Instruction Cache Invalidate */ @@ -61,107 +61,107 @@ lowlevel_init: mov.l MSTPCR1_D, r0 mov.l r0, @r1 - mov.l RAMCR_A,r1 - mov.l RAMCR_D,r0 + mov.l RAMCR_A, r1 + mov.l RAMCR_D, r0 mov.l r0, @r1 - mov.l MMSELR_A,r1 - mov.l MMSELR_D,r0 + mov.l MMSELR_A, r1 + mov.l MMSELR_D, r0 synco mov.l r0, @r1 - mov.l @r1,r2 /* execute two reads after setting MMSELR*/ - mov.l @r1,r2 + mov.l @r1, r2 /* execute two reads after setting MMSELR*/ + mov.l @r1, r2 synco /* issue memory read */ - mov.l DDRSD_START_A,r1 /* memory address to read*/ - mov.l @r1,r0 + mov.l DDRSD_START_A, r1 /* memory address to read*/ + mov.l @r1, r0 synco - mov.l MIM8_A,r1 - mov.l MIM8_D,r0 - mov.l r0,@r1 + mov.l MIM8_A, r1 + mov.l MIM8_D, r0 + mov.l r0, @r1 - mov.l MIMC_A,r1 - mov.l MIMC_D1,r0 - mov.l r0,@r1 + mov.l MIMC_A, r1 + mov.l MIMC_D1, r0 + mov.l r0, @r1 - mov.l STRC_A,r1 - mov.l STRC_D,r0 - mov.l r0,@r1 + mov.l STRC_A, r1 + mov.l STRC_D, r0 + mov.l r0, @r1 - mov.l SDR4_A,r1 - mov.l SDR4_D,r0 - mov.l r0,@r1 + mov.l SDR4_A, r1 + mov.l SDR4_D, r0 + mov.l r0, @r1 - mov.l MIMC_A,r1 - mov.l MIMC_D2,r0 - mov.l r0,@r1 + mov.l MIMC_A, r1 + mov.l MIMC_D2, r0 + mov.l r0, @r1 nop nop nop - mov.l SCR4_A,r1 - mov.l SCR4_D3,r0 - mov.l r0,@r1 + mov.l SCR4_A, r1 + mov.l SCR4_D3, r0 + mov.l r0, @r1 - mov.l SCR4_A,r1 - mov.l SCR4_D2,r0 - mov.l r0,@r1 + mov.l SCR4_A, r1 + mov.l SCR4_D2, r0 + mov.l r0, @r1 - mov.l SDMR02000_A,r1 - mov.l SDMR02000_D,r0 - mov.l r0,@r1 + mov.l SDMR02000_A, r1 + mov.l SDMR02000_D, r0 + mov.l r0, @r1 - mov.l SDMR00B08_A,r1 - mov.l SDMR00B08_D,r0 - mov.l r0,@r1 + mov.l SDMR00B08_A, r1 + mov.l SDMR00B08_D, r0 + mov.l r0, @r1 - mov.l SCR4_A,r1 - mov.l SCR4_D2,r0 - mov.l r0,@r1 + mov.l SCR4_A, r1 + mov.l SCR4_D2, r0 + mov.l r0, @r1 - mov.l SCR4_A,r1 - mov.l SCR4_D4,r0 - mov.l r0,@r1 + mov.l SCR4_A, r1 + mov.l SCR4_D4, r0 + mov.l r0, @r1 nop nop nop nop - mov.l SCR4_A,r1 - mov.l SCR4_D4,r0 - mov.l r0,@r1 + mov.l SCR4_A, r1 + mov.l SCR4_D4, r0 + mov.l r0, @r1 nop nop nop nop - mov.l SDMR00308_A,r1 - mov.l SDMR00308_D,r0 - mov.l r0,@r1 + mov.l SDMR00308_A, r1 + mov.l SDMR00308_D, r0 + mov.l r0, @r1 - mov.l MIMC_A,r1 - mov.l MIMC_D3,r0 - mov.l r0,@r1 + mov.l MIMC_A, r1 + mov.l MIMC_D3, r0 + mov.l r0, @r1 - mov.l SCR4_A,r1 - mov.l SCR4_D1,r0 - mov.l DELAY60_D,r3 + mov.l SCR4_A, r1 + mov.l SCR4_D1, r0 + mov.l DELAY60_D, r3 delay_loop_60: - mov.l r0,@r1 + mov.l r0, @r1 dt r3 bf delay_loop_60 nop - mov.l CCR_A, r1 /* Address of Cache Control Register */ - mov.l CCR_CACHE_D_2, r0 - mov.l r0, @r1 + mov.l CCR_A, r1 /* Address of Cache Control Register */ + mov.l CCR_CACHE_D_2, r0 + mov.l r0, @r1 bsc_init: mov.l BCR_A, r1 @@ -172,9 +172,9 @@ bsc_init: mov.l CS0BCR_D, r0 mov.l r0, @r1 - mov.l CS1BCR_A,r1 - mov.l CS1BCR_D,r0 - mov.l r0,@r1 + mov.l CS1BCR_A, r1 + mov.l CS1BCR_D, r0 + mov.l r0, @r1 mov.l CS2BCR_A, r1 mov.l CS2BCR_D, r0 @@ -224,27 +224,27 @@ bsc_init: mov.l CS6PCR_D, r0 mov.l r0, @r1 - mov.l DELAY200_D,r3 + mov.l DELAY200_D, r3 delay_loop_200: dt r3 bf delay_loop_200 nop - mov.l PSEL0_A,r1 - mov.l PSEL0_D,r0 - mov.w r0,@r1 + mov.l PSEL0_A, r1 + mov.l PSEL0_D, r0 + mov.w r0, @r1 - mov.l PSEL1_A,r1 - mov.l PSEL1_D,r0 - mov.w r0,@r1 + mov.l PSEL1_A, r1 + mov.l PSEL1_D, r0 + mov.w r0, @r1 - mov.l ICR0_A,r1 - mov.l ICR0_D,r0 - mov.l r0,@r1 + mov.l ICR0_A, r1 + mov.l ICR0_D, r0 + mov.l r0, @r1 stc sr, r0 /* BL bit off(init=ON) */ - mov.l SR_MASK_D, r1 + mov.l SR_MASK_D, r1 and r1, r0 ldc r0, sr @@ -321,7 +321,7 @@ CS4BCR_D: .long 0x77777670 CS5BCR_D: .long 0x77777670 CS6BCR_D: .long 0x77777670 CS0WCR_D: .long 0x7777770F -CS1WCR_D: .long 0x22000002 +CS1WCR_D: .long 0x22000002 CS2WCR_D: .long 0x7777770F CS4WCR_D: .long 0x7777770F CS5WCR_D: .long 0x7777770F diff --git a/board/renesas/sh7785lcr/lowlevel_init.S b/board/renesas/sh7785lcr/lowlevel_init.S index 50e1789..4cb1d9d 100644 --- a/board/renesas/sh7785lcr/lowlevel_init.S +++ b/board/renesas/sh7785lcr/lowlevel_init.S @@ -305,7 +305,7 @@ CS4WCR_D: .long 0x00101012 CS_USB_BCR_D: .long 0x11111200 CS_USB_WCR_D: .long 0x00020004 -/* SD setting : 32bit mode = CS3, 29bit mode = CS6 */ +/* SD setting : 32bit mode = CS3, 29bit mode = CS6 */ CS_SD_BCR_D: .long 0x00000300 CS_SD_WCR_D: .long 0x00030108 -- cgit v1.1 From f7e78f3b74aae9caca2997bad865a72338326c0a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 20 Dec 2008 19:29:49 +0100 Subject: sh: use write{8,16,32} in all lowlevel_init Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- board/mpr2/lowlevel_init.S | 49 +++------ board/ms7722se/lowlevel_init.S | 160 +++++++++-------------------- board/ms7750se/lowlevel_init.S | 64 ++++-------- board/renesas/MigoR/lowlevel_init.S | 141 ++++++++------------------ board/renesas/ap325rxa/lowlevel_init.S | 121 ++++++---------------- board/renesas/r2dplus/lowlevel_init.S | 85 ++++------------ board/renesas/r7780mp/lowlevel_init.S | 122 ++++++---------------- board/renesas/rsk7203/lowlevel_init.S | 129 ++++++------------------ board/renesas/sh7763rdp/lowlevel_init.S | 172 +++++++++----------------------- board/renesas/sh7785lcr/lowlevel_init.S | 28 +----- include/asm-sh/macro.h | 52 ++++++++++ 11 files changed, 338 insertions(+), 785 deletions(-) create mode 100644 include/asm-sh/macro.h diff --git a/board/mpr2/lowlevel_init.S b/board/mpr2/lowlevel_init.S index 187b5bb..5f02bd4 100644 --- a/board/mpr2/lowlevel_init.S +++ b/board/mpr2/lowlevel_init.S @@ -22,6 +22,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ +#include .global lowlevel_init @@ -33,59 +34,35 @@ lowlevel_init: /* * Set frequency multipliers and dividers in FRQCR. */ - mov.l WTCSR_A, r1 - mov.l WTCSR_D, r0 - mov.w r0, @r1 + write16 WTCSR_A, WTCSR_D - mov.l WTCNT_A, r1 - mov.l WTCNT_D, r0 - mov.w r0, @r1 + write16 WTCNT_A, WTCNT_D - mov.l FRQCR_A, r1 - mov.l FRQCR_D, r0 - mov.w r0, @r1 + write16 FRQCR_A, FRQCR_D /* * Setup CS0 (Flash). */ - mov.l CS0BCR_A, r1 - mov.l CS0BCR_D, r0 - mov.l r0, @r1 + write32 CS0BCR_A, CS0BCR_D - mov.l CS0WCR_A, r1 - mov.l CS0WCR_D, r0 - mov.l r0, @r1 + write32 CS0WCR_A, CS0WCR_D /* * Setup CS3 (SDRAM). */ - mov.l CS3BCR_A, r1 - mov.l CS3BCR_D, r0 - mov.l r0, @r1 + write32 CS3BCR_A, CS3BCR_D - mov.l CS3WCR_A, r1 - mov.l CS3WCR_D, r0 - mov.l r0, @r1 + write32 CS3WCR_A, CS3WCR_D - mov.l SDCR_A, r1 - mov.l SDCR_D1, r0 - mov.l r0, @r1 + write32 SDCR_A, SDCR_D1 - mov.l RTCSR_A, r1 - mov.l RTCSR_D, r0 - mov.l r0, @r1 + write32 RTCSR_A, RTCSR_D - mov.l RTCNT_A, r1 - mov.l RTCNT_D, r0 - mov.l r0, @r1 + write32 RTCNT_A, RTCNT_D - mov.l RTCOR_A, r1 - mov.l RTCOR_D, r0 - mov.l r0, @r1 + write32 RTCOR_A, RTCOR_D - mov.l SDCR_A, r1 - mov.l SDCR_D2, r0 - mov.l r0, @r1 + write32 SDCR_A, SDCR_D2 mov.l SDMR3_A, r1 mov.l SDMR3_D, r0 diff --git a/board/ms7722se/lowlevel_init.S b/board/ms7722se/lowlevel_init.S index 3e887cf..9144e10 100644 --- a/board/ms7722se/lowlevel_init.S +++ b/board/ms7722se/lowlevel_init.S @@ -27,6 +27,7 @@ #include #include +#include /* * Board specific low level init code, called _very_ early in the @@ -43,165 +44,94 @@ lowlevel_init: - /* Address of Cache Control Register */ - mov.l CCR_A, r1 - /*Instruction Cache Invalidate */ - mov.l CCR_D, r0 - mov.l r0, @r1 + /* + * Cache Control Register + * Instruction Cache Invalidate + */ + write32 CCR_A, CCR_D - /* Address of MMU Control Register */ - mov.l MMUCR_A, r1 - /* TI == TLB Invalidate bit */ - mov.l MMUCR_D, r0 - mov.l r0, @r1 + /* + * Address of MMU Control Register + * TI == TLB Invalidate bit + */ + write32 MMUCR_A, MMUCR_D /* Address of Power Control Register 0 */ - mov.l MSTPCR0_A, r1 - mov.l MSTPCR0_D, r0 - mov.l r0, @r1 + write32 MSTPCR0_A, MSTPCR0_D /* Address of Power Control Register 2 */ - mov.l MSTPCR2_A, r1 - mov.l MSTPCR2_D, r0 - mov.l r0, @r1 + write32 MSTPCR2_A, MSTPCR2_D - mov.l SBSCR_A, r1 - mov.w SBSCR_D, r0 - mov.w r0, @r1 + write16 SBSCR_A, SBSCR_D - mov.l PSCR_A, r1 - mov.w PSCR_D, r0 - mov.w r0, @r1 + write16 PSCR_A, PSCR_D /* 0xA4520004 (Watchdog Control / Status Register) */ -! mov.l RWTCSR_A, r1 - /* 0xA507 -> timer_STOP/WDT_CLK=max */ -! mov.w RWTCSR_D_1, r0 -! mov.w r0, @r1 +! write16 RWTCSR_A, RWTCSR_D_1 /* 0xA507 -> timer_STOP/WDT_CLK=max */ /* 0xA4520000 (Watchdog Count Register) */ - mov.l RWTCNT_A, r1 - /*0x5A00 -> Clear */ - mov.w RWTCNT_D, r0 - mov.w r0, @r1 + write16 RWTCNT_A, RWTCNT_D /*0x5A00 -> Clear */ /* 0xA4520004 (Watchdog Control / Status Register) */ - mov.l RWTCSR_A, r1 - /* 0xA504 -> timer_STOP/CLK=500ms */ - mov.w RWTCSR_D_2, r0 - mov.w r0, @r1 + write16 RWTCSR_A, RWTCSR_D_2 /* 0xA504 -> timer_STOP/CLK=500ms */ /* 0xA4150000 Frequency control register */ - mov.l FRQCR_A, r1 - mov.l FRQCR_D, r0 ! - mov.l r0, @r1 + write32 FRQCR_A, FRQCR_D - mov.l CCR_A, r1 - mov.l CCR_D_2, r0 - mov.l r0, @r1 + write32 CCR_A, CCR_D_2 bsc_init: - mov.l PSELA_A, r1 - mov.w PSELA_D, r0 - mov.w r0, @r1 + write16 PSELA_A, PSELA_D - mov.l DRVCR_A, r1 - mov.w DRVCR_D, r0 - mov.w r0, @r1 + write16 DRVCR_A, DRVCR_D - mov.l PCCR_A, r1 - mov.w PCCR_D, r0 - mov.w r0, @r1 + write16 PCCR_A, PCCR_D - mov.l PECR_A, r1 - mov.w PECR_D, r0 - mov.w r0, @r1 + write16 PECR_A, PECR_D - mov.l PJCR_A, r1 - mov.w PJCR_D, r0 - mov.w r0, @r1 + write16 PJCR_A, PJCR_D - mov.l PXCR_A, r1 - mov.w PXCR_D, r0 - mov.w r0, @r1 + write16 PXCR_A, PXCR_D - mov.l CMNCR_A, r1 ! CMNCR address -> R1 - mov.l CMNCR_D, r0 ! CMNCR data -> R0 - mov.l r0, @r1 ! CMNCR set + write32 CMNCR_A, CMNCR_D - mov.l CS0BCR_A, r1 ! CS0BCR address -> R1 - mov.l CS0BCR_D, r0 ! CS0BCR data -> R0 - mov.l r0, @r1 ! CS0BCR set + write32 CS0BCR_A, CS0BCR_D - mov.l CS2BCR_A, r1 ! CS2BCR address -> R1 - mov.l CS2BCR_D, r0 ! CS2BCR data -> R0 - mov.l r0, @r1 ! CS2BCR set + write32 CS2BCR_A, CS2BCR_D - mov.l CS4BCR_A, r1 ! CS4BCR address -> R1 - mov.l CS4BCR_D, r0 ! CS4BCR data -> R0 - mov.l r0, @r1 ! CS4BCR set + write32 CS4BCR_A, CS4BCR_D - mov.l CS5ABCR_A, r1 ! CS5ABCR address -> R1 - mov.l CS5ABCR_D, r0 ! CS5ABCR data -> R0 - mov.l r0, @r1 ! CS5ABCR set + write32 CS5ABCR_A, CS5ABCR_D - mov.l CS5BBCR_A, r1 ! CS5BBCR address -> R1 - mov.l CS5BBCR_D, r0 ! CS5BBCR data -> R0 - mov.l r0, @r1 ! CS5BBCR set + write32 CS5BBCR_A, CS5BBCR_D - mov.l CS6ABCR_A, r1 ! CS6ABCR address -> R1 - mov.l CS6ABCR_D, r0 ! CS6ABCR data -> R0 - mov.l r0, @r1 ! CS6ABCR set + write32 CS6ABCR_A, CS6ABCR_D - mov.l CS0WCR_A, r1 ! CS0WCR address -> R1 - mov.l CS0WCR_D, r0 ! CS0WCR data -> R0 - mov.l r0, @r1 ! CS0WCR set + write32 CS0WCR_A, CS0WCR_D - mov.l CS2WCR_A, r1 ! CS2WCR address -> R1 - mov.l CS2WCR_D, r0 ! CS2WCR data -> R0 - mov.l r0, @r1 ! CS2WCR set + write32 CS2WCR_A, CS2WCR_D - mov.l CS4WCR_A, r1 ! CS4WCR address -> R1 - mov.l CS4WCR_D, r0 ! CS4WCR data -> R0 - mov.l r0, @r1 ! CS4WCR set + write32 CS4WCR_A, CS4WCR_D - mov.l CS5AWCR_A, r1 ! CS5AWCR address -> R1 - mov.l CS5AWCR_D, r0 ! CS5AWCR data -> R0 - mov.l r0, @r1 ! CS5AWCR set + write32 CS5AWCR_A, CS5AWCR_D - mov.l CS5BWCR_A, r1 ! CS5BWCR address -> R1 - mov.l CS5BWCR_D, r0 ! CS5BWCR data -> R0 - mov.l r0, @r1 ! CS5BWCR set + write32 CS5BWCR_A, CS5BWCR_D - mov.l CS6AWCR_A, r1 ! CS6AWCR address -> R1 - mov.l CS6AWCR_D, r0 ! CS6AWCR data -> R0 - mov.l r0, @r1 ! CS6AWCR set + write32 CS6AWCR_A, CS6AWCR_D ! SDRAM initialization - mov.l SDCR_A, r1 ! SB_SDCR address -> R1 - mov.l SDCR_D, r0 ! SB_SDCR data -> R0 - mov.l r0, @r1 ! SB_SDCR set + write32 SDCR_A, SDCR_D - mov.l SDWCR_A, r1 ! SB_SDWCR address -> R1 - mov.l SDWCR_D, r0 ! SB_SDWCR data -> R0 - mov.l r0, @r1 ! SB_SDWCR set + write32 SDWCR_A, SDWCR_D - mov.l SDPCR_A, r1 ! SB_SDPCR address -> R1 - mov.l SDPCR_D, r0 ! SB_SDPCR data -> R0 - mov.l r0, @r1 ! SB_SDPCR set + write32 SDPCR_A, SDPCR_D - mov.l RTCOR_A, r1 ! SB_RTCOR address -> R1 - mov.l RTCOR_D, r0 ! SB_RTCOR data -> R0 - mov.l r0, @r1 ! SB_RTCOR set + write32 RTCOR_A, RTCOR_D - mov.l RTCSR_A, r1 ! SB_RTCSR address -> R1 - mov.l RTCSR_D, r0 ! SB_RTCSR data -> R0 - mov.l r0, @r1 ! SB_RTCSR set + write32 RTCSR_A, RTCSR_D - mov.l SDMR3_A, r1 ! SDMR3 address -> R1 - mov #0x00, r0 ! SDMR3 data -> R0 - mov.b r0, @r1 ! SDMR3 set + write8 SDMR3_A, #0x00 ! BL bit off (init = ON) (?!?) diff --git a/board/ms7750se/lowlevel_init.S b/board/ms7750se/lowlevel_init.S index de05dd9..7108019 100644 --- a/board/ms7750se/lowlevel_init.S +++ b/board/ms7750se/lowlevel_init.S @@ -29,6 +29,7 @@ #include #include +#include #ifdef CONFIG_CPU_SH7751 #define BCR2_D_VALUE 0x2FFC /* Area 1-6 width: 32/32/32/32/32/16 */ @@ -65,61 +66,37 @@ lowlevel_init: - mov.l CCR_A, r1 ! CCR Address - mov.l CCR_D_DISABLE, r0 ! CCR Data - mov.l r0, @r1 + write32 CCR_A, CCR_D_DISABLE init_bsc: - mov.l FRQCR_A, r1 /* FRQCR Address */ - mov.l FRQCR_D, r0 /* FRQCR Data */ - mov.w r0, @r1 + write16 FRQCR_A, FRQCR_D - mov.l BCR1_A, r1 /* BCR1 Address */ - mov.l BCR1_D, r0 /* BCR1 Data */ - mov.l r0, @r1 + write32 BCR1_A, BCR1_D - mov.l BCR2_A, r1 /* BCR2 Address */ - mov.l BCR2_D, r0 /* BCR2 Data */ - mov.w r0, @r1 + write16 BCR2_A, BCR2_D - mov.l WCR1_A, r1 /* WCR1 Address */ - mov.l WCR1_D, r0 /* WCR1 Data */ - mov.l r0, @r1 + write32 WCR1_A, WCR1_D - mov.l WCR2_A, r1 /* WCR2 Address */ - mov.l WCR2_D, r0 /* WCR2 Data */ - mov.l r0, @r1 + write32 WCR2_A, WCR2_D - mov.l WCR3_A, r1 /* WCR3 Address */ - mov.l WCR3_D, r0 /* WCR3 Data */ - mov.l r0, @r1 + write32 WCR3_A, WCR3_D - mov.l MCR_A, r1 /* MCR Address */ - mov.l MCR_D1, r0 /* MCR Data1 */ - mov.l r0, @r1 + write32 MCR_A, MCR_D1 - mov.l SDMR3_A, r1 /* Set SDRAM mode */ - mov #0, r0 - mov.b r0, @r1 + /* Set SDRAM mode */ + write8 SDMR3_A, #0 ! Do you need PCMCIA setting? ! If so, please add the lines here... - mov.l RTCNT_A, r1 /* RTCNT Address */ - mov.l RTCNT_D, r0 /* RTCNT Data */ - mov.w r0, @r1 + write16 RTCNT_A, RTCNT_D - mov.l RTCOR_A, r1 /* RTCOR Address */ - mov.l RTCOR_D, r0 /* RTCOR Data */ - mov.w r0, @r1 + write16 RTCOR_A, RTCOR_D - mov.l RTCSR_A, r1 /* RTCSR Address */ - mov.l RTCSR_D, r0 /* RTCSR Data */ - mov.w r0, @r1 + write16 RTCSR_A, RTCSR_D + + write16 RFCR_A, RFCR_D - mov.l RFCR_A, r1 /* RFCR Address */ - mov.l RFCR_D, r0 /* RFCR Data */ - mov.w r0, @r1 /* Clear reflesh counter */ /* Wait DRAM refresh 30 times */ mov #30, r3 1: @@ -128,13 +105,10 @@ init_bsc: cmp/hi r3, r2 bf 1b - mov.l MCR_A, r1 /* MCR Address */ - mov.l MCR_D2, r0 /* MCR Data2 */ - mov.l r0, @r1 + write32 MCR_A, MCR_D2 - mov.l SDMR3_A, r1 /* Set SDRAM mode */ - mov #0, r0 - mov.b r0, @r1 + /* Set SDRAM mode */ + write8 SDMR3_A, #0 rts nop diff --git a/board/renesas/MigoR/lowlevel_init.S b/board/renesas/MigoR/lowlevel_init.S index 13c83bf..1da603a 100644 --- a/board/renesas/MigoR/lowlevel_init.S +++ b/board/renesas/MigoR/lowlevel_init.S @@ -27,6 +27,7 @@ #include #include +#include /* * Board specific low level init code, called _very_ early in the @@ -42,139 +43,81 @@ .align 2 lowlevel_init: - mov.l CCR_A, r1 ! Address of Cache Control Register - mov.l CCR_D, r0 ! Instruction Cache Invalidate - mov.l r0, @r1 + write32 CCR_A, CCR_D ! Address of Cache Control Register + ! Instruction Cache Invalidate - mov.l MMUCR_A, r1 ! Address of MMU Control Register - mov.l MMUCR_D, r0 ! TI == TLB Invalidate bit - mov.l r0, @r1 + write32 MMUCR_A, MMUCR_D ! Address of MMU Control Register + ! TI == TLB Invalidate bit - mov.l MSTPCR0_A, r1 ! Address of Power Control Register 0 - mov.l MSTPCR0_D, r0 ! - mov.l r0, @r1 + write32 MSTPCR0_A, MSTPCR0_D ! Address of Power Control Register 0 - mov.l MSTPCR2_A, r1 ! Address of Power Control Register 2 - mov.l MSTPCR2_D, r0 ! - mov.l r0, @r1 + write32 MSTPCR2_A, MSTPCR2_D ! Address of Power Control Register 2 - mov.l PFC_PULCR_A, r1 - mov.w PFC_PULCR_D, r0 - mov.w r0,@r1 + write16 PFC_PULCR_A, PFC_PULCR_D - mov.l PFC_DRVCR_A, r1 - mov.w PFC_DRVCR_D, r0 - mov.w r0, @r1 + write16 PFC_DRVCR_A, PFC_DRVCR_D - mov.l SBSCR_A, r1 ! - mov.w SBSCR_D, r0 ! - mov.w r0, @r1 + write16 SBSCR_A, SBSCR_D - mov.l PSCR_A, r1 ! - mov.w PSCR_D, r0 ! - mov.w r0, @r1 + write16 PSCR_A, PSCR_D - mov.l RWTCSR_A, r1 ! 0xA4520004 (Watchdog Control / Status Register) - mov.w RWTCSR_D_1, r0 ! 0xA507 -> timer_STOP/WDT_CLK=max - mov.w r0, @r1 + write16 RWTCSR_A, RWTCSR_D_1 ! 0xA4520004 (Watchdog Control / Status Register) + ! 0xA507 -> timer_STOP / WDT_CLK = max - mov.l RWTCNT_A, r1 ! 0xA4520000 (Watchdog Count Register) - mov.w RWTCNT_D, r0 ! 0x5A00 -> Clear - mov.w r0, @r1 + write16 RWTCNT_A, RWTCNT_D ! 0xA4520000 (Watchdog Count Register) + ! 0x5A00 -> Clear - mov.l RWTCSR_A, r1 ! 0xA4520004 (Watchdog Control / Status Register) - mov.w RWTCSR_D_2, r0 ! 0xA504 -> timer_STOP/CLK=500ms - mov.w r0, @r1 + write16 RWTCSR_A, RWTCSR_D_2 ! 0xA4520004 (Watchdog Control / Status Register) + ! 0xA504 -> timer_STOP / CLK = 500ms - mov.l DLLFRQ_A, r1 ! 20080115 - mov.l DLLFRQ_D, r0 ! 20080115 - mov.l r0, @r1 + write32 DLLFRQ_A, DLLFRQ_D ! 20080115 + ! 20080115 - mov.l FRQCR_A, r1 ! 0xA4150000 Frequency control register - mov.l FRQCR_D, r0 ! 20080115 - mov.l r0, @r1 + write32 FRQCR_A, FRQCR_D ! 0xA4150000 Frequency control register + ! 20080115 - mov.l CCR_A, r1 ! Address of Cache Control Register - mov.l CCR_D_2, r0 ! ?? - mov.l r0, @r1 + write32 CCR_A, CCR_D_2 ! Address of Cache Control Register + ! ?? bsc_init: - mov.l CMNCR_A, r1 ! CMNCR address -> R1 - mov.l CMNCR_D, r0 ! CMNCR data -> R0 - mov.l r0, @r1 ! CMNCR set + write32 CMNCR_A, CMNCR_D - mov.l CS0BCR_A, r1 ! CS0BCR address -> R1 - mov.l CS0BCR_D, r0 ! CS0BCR data -> R0 - mov.l r0, @r1 ! CS0BCR set + write32 CS0BCR_A, CS0BCR_D - mov.l CS4BCR_A, r1 ! CS4BCR address -> R1 - mov.l CS4BCR_D, r0 ! CS4BCR data -> R0 - mov.l r0, @r1 ! CS4BCR set + write32 CS4BCR_A, CS4BCR_D - mov.l CS5ABCR_A, r1 ! CS5ABCR address -> R1 - mov.l CS5ABCR_D, r0 ! CS5ABCR data -> R0 - mov.l r0, @r1 ! CS5ABCR set + write32 CS5ABCR_A, CS5ABCR_D - mov.l CS5BBCR_A, r1 ! CS5BBCR address -> R1 - mov.l CS5BBCR_D, r0 ! CS5BBCR data -> R0 - mov.l r0, @r1 ! CS5BBCR set + write32 CS5BBCR_A, CS5BBCR_D - mov.l CS6ABCR_A, r1 ! CS6ABCR address -> R1 - mov.l CS6ABCR_D, r0 ! CS6ABCR data -> R0 - mov.l r0, @r1 ! CS6ABCR set + write32 CS6ABCR_A, CS6ABCR_D - mov.l CS0WCR_A, r1 ! CS0WCR address -> R1 - mov.l CS0WCR_D, r0 ! CS0WCR data -> R0 - mov.l r0, @r1 ! CS0WCR set + write32 CS0WCR_A, CS0WCR_D - mov.l CS4WCR_A, r1 ! CS4WCR address -> R1 - mov.l CS4WCR_D, r0 ! CS4WCR data -> R0 - mov.l r0, @r1 ! CS4WCR set + write32 CS4WCR_A, CS4WCR_D - mov.l CS5AWCR_A, r1 ! CS5AWCR address -> R1 - mov.l CS5AWCR_D, r0 ! CS5AWCR data -> R0 - mov.l r0, @r1 ! CS5AWCR set + write32 CS5AWCR_A, CS5AWCR_D - mov.l CS5BWCR_A, r1 ! CS5BWCR address -> R1 - mov.l CS5BWCR_D, r0 ! CS5BWCR data -> R0 - mov.l r0, @r1 ! CS5BWCR set + write32 CS5BWCR_A, CS5BWCR_D - mov.l CS6AWCR_A, r1 ! CS6AWCR address -> R1 - mov.l CS6AWCR_D, r0 ! CS6AWCR data -> R0 - mov.l r0, @r1 ! CS6AWCR set + write32 CS6AWCR_A, CS6AWCR_D ! SDRAM initialization - mov.l SDCR_A, r1 ! SB_SDCR address -> R1 - mov.l SDCR_D, r0 ! SB_SDCR data -> R0 - mov.l r0, @r1 ! SB_SDCR set + write32 SDCR_A, SDCR_D - mov.l SDWCR_A, r1 ! SB_SDWCR address -> R1 - mov.l SDWCR_D, r0 ! SB_SDWCR data -> R0 - mov.l r0, @r1 ! SB_SDWCR set + write32 SDWCR_A, SDWCR_D - mov.l SDPCR_A, r1 ! SB_SDPCR address -> R1 - mov.l SDPCR_D, r0 ! SB_SDPCR data -> R0 - mov.l r0, @r1 ! SB_SDPCR set + write32 SDPCR_A, SDPCR_D - mov.l RTCOR_A, r1 ! SB_RTCOR address -> R1 - mov.l RTCOR_D, r0 ! SB_RTCOR data -> R0 - mov.l r0, @r1 ! SB_RTCOR set + write32 RTCOR_A, RTCOR_D - mov.l RTCNT_A, r1 ! SB_RTCNT address -> R1 - mov.l RTCNT_D, r0 ! SB_RTCNT data -> R0 - mov.l r0, @r1 + write32 RTCNT_A, RTCNT_D - mov.l RTCSR_A, r1 ! SB_RTCSR address -> R1 - mov.l RTCSR_D, r0 ! SB_RTCSR data -> R0 - mov.l r0, @r1 ! SB_RTCSR set + write32 RTCSR_A, RTCSR_D - mov.l RFCR_A, r1 ! SB_RFCR address -> R1 - mov.l RFCR_D, r0 ! SB_RFCR data -> R0 - mov.l r0, @r1 + write32 RFCR_A, RFCR_D - mov.l SDMR3_A, r1 ! SDMR3 address -> R1 - mov #0x00, r0 ! SDMR3 data -> R0 - mov.b r0, @r1 ! SDMR3 set + write8 SDMR3_A, #0x00 ! BL bit off (init = ON) (?!?) diff --git a/board/renesas/ap325rxa/lowlevel_init.S b/board/renesas/ap325rxa/lowlevel_init.S index 558e779..b32f491 100644 --- a/board/renesas/ap325rxa/lowlevel_init.S +++ b/board/renesas/ap325rxa/lowlevel_init.S @@ -23,6 +23,7 @@ #include #include #include +#include /* * Board specific low level init code, called _very_ early in the @@ -38,113 +39,59 @@ .align 2 lowlevel_init: - mov.l DRVCRA_A, r1 - mov.l DRVCRA_D, r0 - mov.w r0, @r1 + write16 DRVCRA_A, DRVCRA_D - mov.l DRVCRB_A, r1 - mov.l DRVCRB_D, r0 - mov.w r0, @r1 + write16 DRVCRB_A, DRVCRB_D - mov.l RWTCSR_A, r1 - mov.l RWTCSR_D1, r0 - mov.w r0, @r1 + write16 RWTCSR_A, RWTCSR_D1 - mov.l RWTCNT_A, r1 - mov.l RWTCNT_D, r0 - mov.w r0, @r1 + write16 RWTCNT_A, RWTCNT_D - mov.l RWTCSR_A, r1 - mov.l RWTCSR_D2, r0 - mov.w r0, @r1 + write16 RWTCSR_A, RWTCSR_D2 - mov.l FRQCR_A, r1 - mov.l FRQCR_D, r0 - mov.l r0, @r1 + write32 FRQCR_A, FRQCR_D - mov.l CMNCR_A, r1 - mov.l CMNCR_D, r0 - mov.l r0, @r1 + write32 CMNCR_A, CMNCR_D - mov.l CS0BCR_A, r1 - mov.l CS0BCR_D, r0 - mov.l r0, @r1 + write32 CS0BCR_A, CS0BCR_D - mov.l CS4BCR_A, r1 - mov.l CS4BCR_D, r0 - mov.l r0, @r1 + write32 CS4BCR_A, CS4BCR_D - mov.l CS5ABCR_A, r1 - mov.l CS5ABCR_D, r0 - mov.l r0, @r1 + write32 CS5ABCR_A, CS5ABCR_D - mov.l CS5BBCR_A, r1 - mov.l CS5BBCR_D, r0 - mov.l r0, @r1 + write32 CS5BBCR_A, CS5BBCR_D - mov.l CS6ABCR_A, r1 - mov.l CS6ABCR_D, r0 - mov.l r0, @r1 + write32 CS6ABCR_A, CS6ABCR_D - mov.l CS6BBCR_A, r1 - mov.l CS6BBCR_D, r0 - mov.l r0, @r1 + write32 CS6BBCR_A, CS6BBCR_D - mov.l CS0WCR_A, r1 - mov.l CS0WCR_D, r0 - mov.l r0, @r1 + write32 CS0WCR_A, CS0WCR_D - mov.l CS4WCR_A, r1 - mov.l CS4WCR_D, r0 - mov.l r0, @r1 + write32 CS4WCR_A, CS4WCR_D - mov.l CS5AWCR_A, r1 - mov.l CS5AWCR_D, r0 - mov.l r0, @r1 + write32 CS5AWCR_A, CS5AWCR_D - mov.l CS5BWCR_A, r1 - mov.l CS5BWCR_D, r0 - mov.l r0, @r1 + write32 CS5BWCR_A, CS5BWCR_D - mov.l CS6AWCR_A, r1 - mov.l CS6AWCR_D, r0 - mov.l r0, @r1 + write32 CS6AWCR_A, CS6AWCR_D - mov.l CS6BWCR_A, r1 - mov.l CS6BWCR_D, r0 - mov.l r0, @r1 + write32 CS6BWCR_A, CS6BWCR_D - mov.l SBSC_SDCR_A, r1 - mov.l SBSC_SDCR_D1, r0 - mov.l r0, @r1 + write32 SBSC_SDCR_A, SBSC_SDCR_D1 - mov.l SBSC_SDWCR_A, r1 - mov.l SBSC_SDWCR_D, r0 - mov.l r0, @r1 + write32 SBSC_SDWCR_A, SBSC_SDWCR_D - mov.l SBSC_SDPCR_A, r1 - mov.l SBSC_SDPCR_D, r0 - mov.l r0, @r1 + write32 SBSC_SDPCR_A, SBSC_SDPCR_D - mov.l SBSC_RTCSR_A, r1 - mov.l SBSC_RTCSR_D, r0 - mov.l r0, @r1 + write32 SBSC_RTCSR_A, SBSC_RTCSR_D - mov.l SBSC_RTCNT_A, r1 - mov.l SBSC_RTCNT_D, r0 - mov.l r0, @r1 + write32 SBSC_RTCNT_A, SBSC_RTCNT_D - mov.l SBSC_RTCOR_A, r1 - mov.l SBSC_RTCOR_D, r0 - mov.l r0, @r1 + write32 SBSC_RTCOR_A, SBSC_RTCOR_D - mov.l SBSC_SDMR3_A1, r1 - mov.l SBSC_SDMR3_D, r0 - mov.b r0, @r1 + write8 SBSC_SDMR3_A1, SBSC_SDMR3_D - mov.l SBSC_SDMR3_A2, r1 - mov.l SBSC_SDMR3_D, r0 - mov.b r0, @r1 + write8 SBSC_SDMR3_A2, SBSC_SDMR3_D mov.l SLEEP_CNT, r1 2: tst r1, r1 @@ -152,17 +99,11 @@ lowlevel_init: bf/s 2b dt r1 - mov.l SBSC_SDMR3_A3, r1 - mov.l SBSC_SDMR3_D, r0 - mov.b r0, @r1 + write8 SBSC_SDMR3_A3, SBSC_SDMR3_D - mov.l SBSC_SDCR_A, r1 - mov.l SBSC_SDCR_D2, r0 - mov.l r0, @r1 + write32 SBSC_SDCR_A, SBSC_SDCR_D2 - mov.l CCR_A, r1 - mov.l CCR_D, r0 - mov.l r0, @r1 + write32 CCR_A, CCR_D ! BL bit off (init = ON) (?!?) diff --git a/board/renesas/r2dplus/lowlevel_init.S b/board/renesas/r2dplus/lowlevel_init.S index a057370..2f6a9b7 100644 --- a/board/renesas/r2dplus/lowlevel_init.S +++ b/board/renesas/r2dplus/lowlevel_init.S @@ -8,6 +8,7 @@ #include #include +#include .global lowlevel_init .text @@ -15,73 +16,39 @@ lowlevel_init: - mov.l CCR_A, r1 - mov.l CCR_D_D, r0 - mov.l r0, @r1 + write32 CCR_A, CCR_D_D - mov.l MMUCR_A, r1 - mov.l MMUCR_D, r0 - mov.l r0, @r1 + write32 MMUCR_A, MMUCR_D - mov.l BCR1_A, r1 - mov.l BCR1_D, r0 - mov.l r0, @r1 + write32 BCR1_A, BCR1_D - mov.l BCR2_A, r1 - mov.l BCR2_D, r0 - mov.w r0, @r1 + write16 BCR2_A, BCR2_D - mov.l BCR3_A, r1 - mov.l BCR3_D, r0 - mov.w r0, @r1 + write16 BCR3_A, BCR3_D - mov.l BCR4_A, r1 - mov.l BCR4_D, r0 - mov.l r0, @r1 + write32 BCR4_A, BCR4_D - mov.l WCR1_A, r1 - mov.l WCR1_D, r0 - mov.l r0, @r1 + write32 WCR1_A, WCR1_D - mov.l WCR2_A, r1 - mov.l WCR2_D, r0 - mov.l r0, @r1 + write32 WCR2_A, WCR2_D - mov.l WCR3_A, r1 - mov.l WCR3_D, r0 - mov.l r0, @r1 + write32 WCR3_A, WCR3_D - mov.l PCR_A, r1 - mov.l PCR_D, r0 - mov.w r0, @r1 + write16 PCR_A, PCR_D - mov.l LED_A, r1 - mov #0xff, r0 - mov.w r0, @r1 + write16 LED_A, #0xff - mov.l MCR_A, r1 - mov.l MCR_D1, r0 - mov.l r0, @r1 + write32 MCR_A, MCR_D1 - mov.l RTCNT_A, r1 - mov.l RTCNT_D, r0 - mov.w r0, @r1 + write16 RTCNT_A, RTCNT_D - mov.l RTCOR_A, r1 - mov.l RTCOR_D, r0 - mov.w r0, @r1 + write16 RTCOR_A, RTCOR_D - mov.l RFCR_A, r1 - mov.l RFCR_D, r0 - mov.w r0, @r1 + write16 RFCR_A, RFCR_D - mov.l RTCSR_A, r1 - mov.l RTCSR_D, r0 - mov.w r0, @r1 + write16 RTCSR_A, RTCSR_D - mov.l SDMR3_A, r1 - mov #0x55, r0 - mov.b r0, @r1 + write8 SDMR3_A, #0x55 /* Wait DRAM refresh 30 times */ mov.l RFCR_A, r1 @@ -92,21 +59,13 @@ lowlevel_init: cmp/hi r3, r2 bf 1b - mov.l MCR_A, r1 - mov.l MCR_D2, r0 - mov.l r0, @r1 + write32 MCR_A, MCR_D2 - mov.l SDMR3_A, r1 - mov #0, r0 - mov.b r0, @r1 + write8 SDMR3_A, #0 - mov.l IRLMASK_A, r1 - mov.l IRLMASK_D, r0 - mov.l r0, @r1 + write32 IRLMASK_A, IRLMASK_D - mov.l CCR_A, r1 - mov.l CCR_D_E, r0 - mov.l r0, @r1 + write32 CCR_A, CCR_D_E rts nop diff --git a/board/renesas/r7780mp/lowlevel_init.S b/board/renesas/r7780mp/lowlevel_init.S index 0df8c84..bbea621 100644 --- a/board/renesas/r7780mp/lowlevel_init.S +++ b/board/renesas/r7780mp/lowlevel_init.S @@ -22,6 +22,7 @@ #include #include #include +#include /* * Board specific low level init code, called _very_ early in the @@ -38,63 +39,36 @@ lowlevel_init: - mov.l CCR_A, r1 /* Address of Cache Control Register */ - mov.l CCR_D, r0 /* Instruction Cache Invalidate */ - mov.l r0, @r1 + write32 CCR_A, CCR_D /* Address of Cache Control Register */ + /* Instruction Cache Invalidate */ - mov.l FRQCR_A, r1 /* Frequency control register */ - mov.l FRQCR_D, r0 - mov.l r0, @r1 + write32 FRQCR_A, FRQCR_D /* Frequency control register */ /* pin_multi_setting */ - mov.l BBG_PMMR_A, r1 - mov.l BBG_PMMR_D_PMSR1, r0 - mov.l r0, @r1 + write32 BBG_PMMR_A, BBG_PMMR_D_PMSR1 - mov.l BBG_PMSR1_A, r1 - mov.l BBG_PMSR1_D, r0 - mov.l r0, @r1 + write32 BBG_PMSR1_A, BBG_PMSR1_D - mov.l BBG_PMMR_A, r1 - mov.l BBG_PMMR_D_PMSR2, r0 - mov.l r0, @r1 + write32 BBG_PMMR_A, BBG_PMMR_D_PMSR2 - mov.l BBG_PMSR2_A, r1 - mov.l BBG_PMSR2_D, r0 - mov.l r0, @r1 + write32 BBG_PMSR2_A, BBG_PMSR2_D - mov.l BBG_PMMR_A, r1 - mov.l BBG_PMMR_D_PMSR3, r0 - mov.l r0, @r1 + write32 BBG_PMMR_A, BBG_PMMR_D_PMSR3 - mov.l BBG_PMSR3_A, r1 - mov.l BBG_PMSR3_D, r0 - mov.l r0, @r1 + write32 BBG_PMSR3_A, BBG_PMSR3_D - mov.l BBG_PMMR_A, r1 - mov.l BBG_PMMR_D_PMSR4, r0 - mov.l r0, @r1 + write32 BBG_PMMR_A, BBG_PMMR_D_PMSR4 - mov.l BBG_PMSR4_A, r1 - mov.l BBG_PMSR4_D, r0 - mov.l r0, @r1 + write32 BBG_PMSR4_A, BBG_PMSR4_D - mov.l BBG_PMMR_A, r1 - mov.l BBG_PMMR_D_PMSRG, r0 - mov.l r0, @r1 + write32 BBG_PMMR_A, BBG_PMMR_D_PMSRG - mov.l BBG_PMSRG_A, r1 - mov.l BBG_PMSRG_D, r0 - mov.l r0, @r1 + write32 BBG_PMSRG_A, BBG_PMSRG_D /* cpg_setting */ - mov.l FRQCR_A, r1 - mov.l FRQCR_D, r0 - mov.l r0, @r1 + write32 FRQCR_A, FRQCR_D - mov.l DLLCSR_A, r1 - mov.l DLLCSR_D, r0 - mov.l r0, @r1 + write32 DLLCSR_A, DLLCSR_D nop nop @@ -117,69 +91,37 @@ repeat0: nop /* bsc_setting */ - mov.l MMSELR_A, r1 - mov.l MMSELR_D, r0 - mov.l r0, @r1 + write32 MMSELR_A, MMSELR_D - mov.l BCR_A, r1 - mov.l BCR_D, r0 - mov.l r0, @r1 + write32 BCR_A, BCR_D - mov.l CS0BCR_A, r1 - mov.l CS0BCR_D, r0 - mov.l r0, @r1 + write32 CS0BCR_A, CS0BCR_D - mov.l CS1BCR_A, r1 - mov.l CS1BCR_D, r0 - mov.l r0, @r1 + write32 CS1BCR_A, CS1BCR_D - mov.l CS2BCR_A, r1 - mov.l CS2BCR_D, r0 - mov.l r0, @r1 + write32 CS2BCR_A, CS2BCR_D - mov.l CS4BCR_A, r1 - mov.l CS4BCR_D, r0 - mov.l r0, @r1 + write32 CS4BCR_A, CS4BCR_D - mov.l CS5BCR_A, r1 - mov.l CS5BCR_D, r0 - mov.l r0, @r1 + write32 CS5BCR_A, CS5BCR_D - mov.l CS6BCR_A, r1 - mov.l CS6BCR_D, r0 - mov.l r0, @r1 + write32 CS6BCR_A, CS6BCR_D - mov.l CS0WCR_A, r1 - mov.l CS0WCR_D, r0 - mov.l r0, @r1 + write32 CS0WCR_A, CS0WCR_D - mov.l CS1WCR_A, r1 - mov.l CS1WCR_D, r0 - mov.l r0, @r1 + write32 CS1WCR_A, CS1WCR_D - mov.l CS2WCR_A, r1 - mov.l CS2WCR_D, r0 - mov.l r0, @r1 + write32 CS2WCR_A, CS2WCR_D - mov.l CS4WCR_A, r1 - mov.l CS4WCR_D, r0 - mov.l r0, @r1 + write32 CS4WCR_A, CS4WCR_D - mov.l CS5WCR_A, r1 - mov.l CS5WCR_D, r0 - mov.l r0, @r1 + write32 CS5WCR_A, CS5WCR_D - mov.l CS6WCR_A, r1 - mov.l CS6WCR_D, r0 - mov.l r0, @r1 + write32 CS6WCR_A, CS6WCR_D - mov.l CS5PCR_A, r1 - mov.l CS5PCR_D, r0 - mov.l r0, @r1 + write32 CS5PCR_A, CS5PCR_D - mov.l CS6PCR_A, r1 - mov.l CS6PCR_D, r0 - mov.l r0, @r1 + write32 CS6PCR_A, CS6PCR_D /* ddr_setting */ /* wait 200us */ diff --git a/board/renesas/rsk7203/lowlevel_init.S b/board/renesas/rsk7203/lowlevel_init.S index f6a6231..7b9ecd8 100644 --- a/board/renesas/rsk7203/lowlevel_init.S +++ b/board/renesas/rsk7203/lowlevel_init.S @@ -21,6 +21,7 @@ #include #include +#include .global lowlevel_init @@ -29,140 +30,76 @@ lowlevel_init: /* Cache setting */ - mov.l CCR1_A, r1 - mov.l CCR1_D, r0 - mov.l r0, @r1 + write32 CCR1_A ,CCR1_D /* ConfigurePortPins */ - mov.l PECRL3_A, r1 - mov.l PECRL3_D, r0 - mov.w r0, @r1 + write16 PECRL3_A, PECRL3_D - mov.l PCCRL4_A, r1 - mov.l PCCRL4_D0, r0 - mov.w r0, @r1 + write16 PCCRL4_A, PCCRL4_D0 - mov.l PECRL4_A, r1 - mov.l PECRL4_D0, r0 - mov.w r0, @r1 + write16 PECRL4_A, PECRL4_D0 - mov.l PEIORL_A, r1 - mov.l PEIORL_D0, r0 - mov.w r0, @r1 + write16 PEIORL_A, PEIORL_D0 - mov.l PCIORL_A, r1 - mov.l PCIORL_D, r0 - mov.w r0, @r1 + write16 PCIORL_A, PCIORL_D - mov.l PFCRH2_A, r1 - mov.l PFCRH2_D, r0 - mov.w r0, @r1 + write16 PFCRH2_A, PFCRH2_D - mov.l PFCRH3_A, r1 - mov.l PFCRH3_D, r0 - mov.w r0, @r1 + write16 PFCRH3_A, PFCRH3_D - mov.l PFCRH1_A, r1 - mov.l PFCRH1_D, r0 - mov.w r0, @r1 + write16 PFCRH1_A, PFCRH1_D - mov.l PFIORH_A, r1 - mov.l PFIORH_D, r0 - mov.w r0, @r1 + write16 PFIORH_A, PFIORH_D - mov.l PECRL1_A, r1 - mov.l PECRL1_D0, r0 - mov.w r0, @r1 + write16 PECRL1_A, PECRL1_D0 - mov.l PEIORL_A, r1 - mov.l PEIORL_D1, r0 - mov.w r0, @r1 + write16 PEIORL_A, PEIORL_D1 /* Configure Operating Frequency */ - mov.l WTCSR_A, r1 - mov.l WTCSR_D0, r0 - mov.w r0, @r1 + write16 WTCSR_A, WTCSR_D0 - mov.l WTCSR_A, r1 - mov.l WTCSR_D1, r0 - mov.w r0, @r1 + write16 WTCSR_A, WTCSR_D1 - mov.l WTCNT_A, r1 - mov.l WTCNT_D, r0 - mov.w r0, @r1 + write16 WTCNT_A, WTCNT_D /* Set clock mode*/ - mov.l FRQCR_A, r1 - mov.l FRQCR_D, r0 - mov.w r0, @r1 + write16 FRQCR_A, FRQCR_D /* Configure Bus And Memory */ init_bsc_cs0: - mov.l PCCRL4_A, r1 - mov.l PCCRL4_D1, r0 - mov.w r0, @r1 + write16 PCCRL4_A, PCCRL4_D1 - mov.l PECRL1_A, r1 - mov.l PECRL1_D1, r0 - mov.w r0, @r1 + write16 PECRL1_A, PECRL1_D1 - mov.l CMNCR_A, r1 - mov.l CMNCR_D, r0 - mov.l r0, @r1 + write32 CMNCR_A, CMNCR_D - mov.l SC0BCR_A, r1 - mov.l SC0BCR_D, r0 - mov.l r0, @r1 + write32 SC0BCR_A, SC0BCR_D - mov.l CS0WCR_A, r1 - mov.l CS0WCR_D, r0 - mov.l r0, @r1 + write32 CS0WCR_A, CS0WCR_D init_bsc_cs1: - mov.l PECRL4_A, r1 - mov.l PECRL4_D1, r0 - mov.w r0, @r1 + write16 PECRL4_A, PECRL4_D1 - mov.l CS1WCR_A, r1 - mov.l CS1WCR_D, r0 - mov.l r0, @r1 + write32 CS1WCR_A, CS1WCR_D init_sdram: - mov.l PCCRL2_A, r1 - mov.l PCCRL2_D, r0 - mov.w r0, @r1 + write16 PCCRL2_A, PCCRL2_D - mov.l PCCRL4_A, r1 - mov.l PCCRL4_D2, r0 - mov.w r0, @r1 + write16 PCCRL4_A, PCCRL4_D2 - mov.l PCCRL1_A, r1 - mov.l PCCRL1_D, r0 - mov.w r0, @r1 + write16 PCCRL1_A, PCCRL1_D - mov.l PCCRL3_A, r1 - mov.l PCCRL3_D, r0 - mov.w r0, @r1 + write16 PCCRL3_A, PCCRL3_D - mov.l CS3BCR_A, r1 - mov.l CS3BCR_D, r0 - mov.l r0, @r1 + write32 CS3BCR_A, CS3BCR_D - mov.l CS3WCR_A, r1 - mov.l CS3WCR_D, r0 - mov.l r0, @r1 + write32 CS3WCR_A, CS3WCR_D - mov.l SDCR_A, r1 - mov.l SDCR_D, r0 - mov.l r0, @r1 + write32 SDCR_A, SDCR_D - mov.l RTCOR_A, r1 - mov.l RTCOR_D, r0 - mov.l r0, @r1 + write32 RTCOR_A, RTCOR_D - mov.l RTCSR_A, r1 - mov.l RTCSR_D, r0 - mov.l r0, @r1 + write32 RTCSR_A, RTCSR_D /* wait 200us */ mov.l REPEAT_D, r3 diff --git a/board/renesas/sh7763rdp/lowlevel_init.S b/board/renesas/sh7763rdp/lowlevel_init.S index 715e75f..3747bf6 100644 --- a/board/renesas/sh7763rdp/lowlevel_init.S +++ b/board/renesas/sh7763rdp/lowlevel_init.S @@ -25,6 +25,7 @@ #include #include +#include .global lowlevel_init @@ -33,44 +34,33 @@ lowlevel_init: - mov.l WDTCSR_A, r1 /* Watchdog Control / Status Register */ - mov.l WDTCSR_D, r0 - mov.l r0, @r1 + write32 WDTCSR_A, WDTCSR_D /* Watchdog Control / Status Register */ - mov.l WDTST_A, r1 /* Watchdog Stop Time Register */ - mov.l WDTST_D, r0 - mov.l r0, @r1 + write32 WDTST_A, WDTST_D /* Watchdog Stop Time Register */ - mov.l WDTBST_A, r1 /* 0xFFCC0008 (Watchdog Base Stop Time Register */ - mov.l WDTBST_D, r0 - mov.l r0, @r1 + write32 WDTBST_A, WDTBST_D /* + * 0xFFCC0008 + * Watchdog Base Stop Time Register + */ - mov.l CCR_A, r1 /* Address of Cache Control Register */ - mov.l CCR_CACHE_ICI_D, r0 /* Instruction Cache Invalidate */ - mov.l r0, @r1 + write32 CCR_A, CCR_CACHE_ICI_D /* Address of Cache Control Register */ + /* Instruction Cache Invalidate */ - mov.l MMUCR_A, r1 /* Address of MMU Control Register */ - mov.l MMU_CONTROL_TI_D, r0 /* TI == TLB Invalidate bit */ - mov.l r0, @r1 + write32 MMUCR_A, MMU_CONTROL_TI_D /* MMU Control Register */ + /* TI == TLB Invalidate bit */ - mov.l MSTPCR0_A, r1 /* Address of Power Control Register 0 */ - mov.l MSTPCR0_D, r0 - mov.l r0, @r1 + write32 MSTPCR0_A, MSTPCR0_D /* Address of Power Control Register 0 */ - mov.l MSTPCR1_A, r1 /*i Address of Power Control Register 1 */ - mov.l MSTPCR1_D, r0 - mov.l r0, @r1 + write32 MSTPCR1_A, MSTPCR1_D /* Address of Power Control Register 1 */ - mov.l RAMCR_A, r1 - mov.l RAMCR_D, r0 - mov.l r0, @r1 + write32 RAMCR_A, RAMCR_D mov.l MMSELR_A, r1 mov.l MMSELR_D, r0 synco mov.l r0, @r1 - mov.l @r1, r2 /* execute two reads after setting MMSELR*/ + mov.l @r1, r2 /* execute two reads after setting MMSELR */ mov.l @r1, r2 synco @@ -79,75 +69,47 @@ lowlevel_init: mov.l @r1, r0 synco - mov.l MIM8_A, r1 - mov.l MIM8_D, r0 - mov.l r0, @r1 + write32 MIM8_A, MIM8_D - mov.l MIMC_A, r1 - mov.l MIMC_D1, r0 - mov.l r0, @r1 + write32 MIMC_A, MIMC_D1 - mov.l STRC_A, r1 - mov.l STRC_D, r0 - mov.l r0, @r1 + write32 STRC_A, STRC_D - mov.l SDR4_A, r1 - mov.l SDR4_D, r0 - mov.l r0, @r1 + write32 SDR4_A, SDR4_D - mov.l MIMC_A, r1 - mov.l MIMC_D2, r0 - mov.l r0, @r1 + write32 MIMC_A, MIMC_D2 nop nop nop - mov.l SCR4_A, r1 - mov.l SCR4_D3, r0 - mov.l r0, @r1 + write32 SCR4_A, SCR4_D3 - mov.l SCR4_A, r1 - mov.l SCR4_D2, r0 - mov.l r0, @r1 + write32 SCR4_A, SCR4_D2 - mov.l SDMR02000_A, r1 - mov.l SDMR02000_D, r0 - mov.l r0, @r1 + write32 SDMR02000_A, SDMR02000_D - mov.l SDMR00B08_A, r1 - mov.l SDMR00B08_D, r0 - mov.l r0, @r1 + write32 SDMR00B08_A, SDMR00B08_D - mov.l SCR4_A, r1 - mov.l SCR4_D2, r0 - mov.l r0, @r1 + write32 SCR4_A, SCR4_D2 - mov.l SCR4_A, r1 - mov.l SCR4_D4, r0 - mov.l r0, @r1 + write32 SCR4_A, SCR4_D4 nop nop nop nop - mov.l SCR4_A, r1 - mov.l SCR4_D4, r0 - mov.l r0, @r1 + write32 SCR4_A, SCR4_D4 nop nop nop nop - mov.l SDMR00308_A, r1 - mov.l SDMR00308_D, r0 - mov.l r0, @r1 + write32 SDMR00308_A, SDMR00308_D - mov.l MIMC_A, r1 - mov.l MIMC_D3, r0 - mov.l r0, @r1 + write32 MIMC_A, MIMC_D3 mov.l SCR4_A, r1 mov.l SCR4_D1, r0 @@ -159,70 +121,38 @@ delay_loop_60: bf delay_loop_60 nop - mov.l CCR_A, r1 /* Address of Cache Control Register */ - mov.l CCR_CACHE_D_2, r0 - mov.l r0, @r1 + write32 CCR_A, CCR_CACHE_D_2 /* Address of Cache Control Register */ bsc_init: - mov.l BCR_A, r1 - mov.l BCR_D, r0 - mov.l r0, @r1 + write32 BCR_A, BCR_D - mov.l CS0BCR_A, r1 - mov.l CS0BCR_D, r0 - mov.l r0, @r1 + write32 CS0BCR_A, CS0BCR_D - mov.l CS1BCR_A, r1 - mov.l CS1BCR_D, r0 - mov.l r0, @r1 + write32 CS1BCR_A, CS1BCR_D - mov.l CS2BCR_A, r1 - mov.l CS2BCR_D, r0 - mov.l r0, @r1 + write32 CS2BCR_A, CS2BCR_D - mov.l CS4BCR_A, r1 - mov.l CS4BCR_D, r0 - mov.l r0, @r1 + write32 CS4BCR_A, CS4BCR_D - mov.l CS5BCR_A, r1 - mov.l CS5BCR_D, r0 - mov.l r0, @r1 + write32 CS5BCR_A, CS5BCR_D - mov.l CS6BCR_A, r1 - mov.l CS6BCR_D, r0 - mov.l r0, @r1 + write32 CS6BCR_A, CS6BCR_D - mov.l CS0WCR_A, r1 - mov.l CS0WCR_D, r0 - mov.l r0, @r1 + write32 CS0WCR_A, CS0WCR_D - mov.l CS1WCR_A, r1 - mov.l CS1WCR_D, r0 - mov.l r0, @r1 + write32 CS1WCR_A, CS1WCR_D - mov.l CS2WCR_A, r1 - mov.l CS2WCR_D, r0 - mov.l r0, @r1 + write32 CS2WCR_A, CS2WCR_D - mov.l CS4WCR_A, r1 - mov.l CS4WCR_D, r0 - mov.l r0, @r1 + write32 CS4WCR_A, CS4WCR_D - mov.l CS5WCR_A, r1 - mov.l CS5WCR_D, r0 - mov.l r0, @r1 + write32 CS5WCR_A, CS5WCR_D - mov.l CS6WCR_A, r1 - mov.l CS6WCR_D, r0 - mov.l r0, @r1 + write32 CS6WCR_A, CS6WCR_D - mov.l CS5PCR_A, r1 - mov.l CS5PCR_D, r0 - mov.l r0, @r1 + write32 CS5PCR_A, CS5PCR_D - mov.l CS6PCR_A, r1 - mov.l CS6PCR_D, r0 - mov.l r0, @r1 + write32 CS6PCR_A, CS6PCR_D mov.l DELAY200_D, r3 @@ -231,17 +161,11 @@ delay_loop_200: bf delay_loop_200 nop - mov.l PSEL0_A, r1 - mov.l PSEL0_D, r0 - mov.w r0, @r1 + write16 PSEL0_A, PSEL0_D - mov.l PSEL1_A, r1 - mov.l PSEL1_D, r0 - mov.w r0, @r1 + write16 PSEL1_A, PSEL1_D - mov.l ICR0_A, r1 - mov.l ICR0_D, r0 - mov.l r0, @r1 + write32 ICR0_A, ICR0_D stc sr, r0 /* BL bit off(init=ON) */ mov.l SR_MASK_D, r1 diff --git a/board/renesas/sh7785lcr/lowlevel_init.S b/board/renesas/sh7785lcr/lowlevel_init.S index 4cb1d9d..f5ebeb9 100644 --- a/board/renesas/sh7785lcr/lowlevel_init.S +++ b/board/renesas/sh7785lcr/lowlevel_init.S @@ -19,33 +19,7 @@ #include #include #include - -.macro write32, addr, data - mov.l \addr ,r1 - mov.l \data ,r0 - mov.l r0, @r1 -.endm - -.macro write16, addr, data - mov.l \addr ,r1 - mov.l \data ,r0 - mov.w r0, @r1 -.endm - -.macro write8, addr, data - mov.l \addr ,r1 - mov.l \data ,r0 - mov.b r0, @r1 -.endm - -.macro wait_timer, time - mov.l \time ,r3 -1: - nop - tst r3, r3 - bf/s 1b - dt r3 -.endm +#include #include diff --git a/include/asm-sh/macro.h b/include/asm-sh/macro.h new file mode 100644 index 0000000..61f792a --- /dev/null +++ b/include/asm-sh/macro.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 Yoshihiro Shimoda + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __MACRO_H__ +#define __MACRO_H__ +#ifdef __ASSEMBLY__ + +.macro write32, addr, data + mov.l \addr ,r1 + mov.l \data ,r0 + mov.l r0, @r1 +.endm + +.macro write16, addr, data + mov.l \addr ,r1 + mov.l \data ,r0 + mov.w r0, @r1 +.endm + +.macro write8, addr, data + mov.l \addr ,r1 + mov.l \data ,r0 + mov.b r0, @r1 +.endm + +.macro wait_timer, time + mov.l \time ,r3 +1: + nop + tst r3, r3 + bf/s 1b + dt r3 +.endm + +#endif /* __ASSEMBLY__ */ +#endif /* __MACRO_H__ */ -- cgit v1.1 From a5b04d00bfeb940c62232972ce644d50b45797f9 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 30 Dec 2008 01:16:03 +0000 Subject: sh: Fix up rsk7203 target for out of tree build Fix up rsk7203 target to build successfully using out-of-tree build. Signed-off-by: Kieran Bingham Signed-off-by: Nobuhiro Iwamatsu --- Makefile | 4 ++-- board/renesas/rsk7203/Makefile | 4 ++++ cpu/sh2/Makefile | 21 +++++++++++++-------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index ecde92b..8fb1e2a 100644 --- a/Makefile +++ b/Makefile @@ -3230,8 +3230,8 @@ mimc200_config : unconfig ## sh2 (Renesas SuperH) ######################################################################### rsk7203_config: unconfig - @ >include/config.h - @echo "#define CONFIG_RSK7203 1" >> include/config.h + @mkdir -p $(obj)include + @echo "#define CONFIG_RSK7203 1" > $(obj)/include/config.h @$(MKCONFIG) -a $(@:_config=) sh sh2 rsk7203 renesas ######################################################################### diff --git a/board/renesas/rsk7203/Makefile b/board/renesas/rsk7203/Makefile index 7365d19..5412010 100644 --- a/board/renesas/rsk7203/Makefile +++ b/board/renesas/rsk7203/Makefile @@ -26,6 +26,10 @@ LIB = lib$(BOARD).a OBJS := rsk7203.o SOBJS := lowlevel_init.o +LIB := $(addprefix $(obj),$(LIB)) +OBJS := $(addprefix $(obj),$(OBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + $(LIB): $(obj).depend $(OBJS) $(SOBJS) $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) diff --git a/cpu/sh2/Makefile b/cpu/sh2/Makefile index e33ba0f..346d328 100644 --- a/cpu/sh2/Makefile +++ b/cpu/sh2/Makefile @@ -28,18 +28,23 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a -START = start.o -OBJS = cpu.o interrupts.o watchdog.o +SOBJS = start.o +COBJS = cpu.o interrupts.o watchdog.o -all: .depend $(START) $(LIB) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) -######################################################################### +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend -.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) - $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ +######################################################################### # defines $(obj).depend target include $(SRCTREE)/rules.mk -- cgit v1.1 From c9935c992575922b7ef13eec0656ed8665d324e3 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Sun, 11 Jan 2009 17:48:56 +0900 Subject: sh: Fix compile error on lowlevel_init file lowlevel_init of SH was corrected to use the write/readXX macro. However, there was a problem that was not able to be compiled partially. This patch corrected this. Signed-off-by: Nobuhiro Iwamatsu --- board/ms7722se/lowlevel_init.S | 3 ++- board/ms7750se/lowlevel_init.S | 5 +++-- board/renesas/MigoR/lowlevel_init.S | 3 ++- board/renesas/r2dplus/lowlevel_init.S | 10 ++++++---- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/board/ms7722se/lowlevel_init.S b/board/ms7722se/lowlevel_init.S index 9144e10..1cb57e7 100644 --- a/board/ms7722se/lowlevel_init.S +++ b/board/ms7722se/lowlevel_init.S @@ -131,7 +131,7 @@ bsc_init: write32 RTCSR_A, RTCSR_D - write8 SDMR3_A, #0x00 + write8 SDMR3_A, SDMR3_D ! BL bit off (init = ON) (?!?) @@ -225,6 +225,7 @@ RTCOR_D: .long 0xA55A0034 RTCSR_A: .long SBSC_RTCSR RTCSR_D: .long 0xA55A0010 SDMR3_A: .long 0xFE500180 +SDMR3_D: .long 0x0 .align 1 diff --git a/board/ms7750se/lowlevel_init.S b/board/ms7750se/lowlevel_init.S index 7108019..5e09a39 100644 --- a/board/ms7750se/lowlevel_init.S +++ b/board/ms7750se/lowlevel_init.S @@ -84,7 +84,7 @@ init_bsc: write32 MCR_A, MCR_D1 /* Set SDRAM mode */ - write8 SDMR3_A, #0 + write8 SDMR3_A, SDMR3_D ! Do you need PCMCIA setting? ! If so, please add the lines here... @@ -108,7 +108,7 @@ init_bsc: write32 MCR_A, MCR_D2 /* Set SDRAM mode */ - write8 SDMR3_A, #0 + write8 SDMR3_A, SDMR3_D rts nop @@ -146,6 +146,7 @@ RTCNT_D: .long 0xA500 /* RTCNT Write Code A5h Data 00h */ RTCOR_A: .long RTCOR RTCOR_D: .long RTCOR_D_VALUE /* Set refresh time (about 15us) */ SDMR3_A: .long SDMR3_ADDRESS +SDMR3_D: .long 0x00 MCR_A: .long MCR MCR_D1: .long MCR_D1_VALUE MCR_D2: .long MCR_D2_VALUE diff --git a/board/renesas/MigoR/lowlevel_init.S b/board/renesas/MigoR/lowlevel_init.S index 1da603a..e32a7af 100644 --- a/board/renesas/MigoR/lowlevel_init.S +++ b/board/renesas/MigoR/lowlevel_init.S @@ -117,7 +117,7 @@ bsc_init: write32 RFCR_A, RFCR_D - write8 SDMR3_A, #0x00 + write8 SDMR3_A, SDMR3_D ! BL bit off (init = ON) (?!?) @@ -195,6 +195,7 @@ RFCR_A: .long SBSC_RFCR RFCR_D: .long 0xA55A0221 RTCSR_D: .long 0xA55A009a SDMR3_A: .long 0xFE581180 +SDMR3_D: .long 0x0 SR_MASK_D: .long 0xEFFFFF0F diff --git a/board/renesas/r2dplus/lowlevel_init.S b/board/renesas/r2dplus/lowlevel_init.S index 2f6a9b7..76d3cfc 100644 --- a/board/renesas/r2dplus/lowlevel_init.S +++ b/board/renesas/r2dplus/lowlevel_init.S @@ -36,7 +36,7 @@ lowlevel_init: write16 PCR_A, PCR_D - write16 LED_A, #0xff + write16 LED_A, LED_D write32 MCR_A, MCR_D1 @@ -48,7 +48,7 @@ lowlevel_init: write16 RTCSR_A, RTCSR_D - write8 SDMR3_A, #0x55 + write8 SDMR3_A, SDMR3_D0 /* Wait DRAM refresh 30 times */ mov.l RFCR_A, r1 @@ -61,7 +61,7 @@ lowlevel_init: write32 MCR_A, MCR_D2 - write8 SDMR3_A, #0 + write8 SDMR3_A, SDMR3_D1 write32 IRLMASK_A, IRLMASK_D @@ -92,6 +92,7 @@ WCR2_D: .long 0xcff86fbf WCR3_A: .long WCR3 /* WCR3 Address */ WCR3_D: .long 0x07777707 LED_A: .long 0x04000036 /* LED Address */ +LED_D: .long 0xFF /* LED Data */ RTCNT_A: .long RTCNT /* RTCNT Address */ RTCNT_D: .long 0xA500 /* RTCNT Write Code A5h Data 00h */ RTCOR_A: .long RTCOR /* RTCOR Address */ @@ -99,7 +100,8 @@ RTCOR_D: .long 0xA534 /* RTCOR Write Code */ RTCSR_A: .long RTCSR /* RTCSR Address */ RTCSR_D: .long 0xA510 /* RTCSR Write Code */ SDMR3_A: .long 0xFF9400CC /* SDMR3 Address */ -SDMR3_D: .long 0x55 +SDMR3_D0: .long 0x55 +SDMR3_D1: .long 0x00 MCR_A: .long MCR /* MCR Address */ MCR_D1: .long 0x081901F4 /* MRSET:'0' */ MCR_D2: .long 0x481901F4 /* MRSET:'1' */ -- cgit v1.1 From 9e1fa628bdb64745811cdd26c4f953846c076180 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 11 Jan 2009 16:35:15 +0100 Subject: sh: serial: coding style cleanup Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- drivers/serial/serial_sh.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 1d76a19..e47ec2e 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -49,7 +49,7 @@ # define SCFRDR (vu_char *)(SCIF_BASE + 0x24) #else # define SCFTDR (vu_char *)(SCIF_BASE + 0xC) -# define SCFSR (vu_short *)(SCIF_BASE + 0x10) +# define SCFSR (vu_short *)(SCIF_BASE + 0x10) # define SCFRDR (vu_char *)(SCIF_BASE + 0x14) #endif @@ -64,7 +64,7 @@ #elif defined(CONFIG_CPU_SH7763) # if defined(CONFIG_CONS_SCIF2) # define SCSPTR (vu_short *)(SCIF_BASE + 0x20) -# define SCLSR (vu_short *)(SCIF_BASE + 0x24) +# define SCLSR (vu_short *)(SCIF_BASE + 0x24) # define LSR_ORER 1 # define FIFOLEVEL_MASK 0x1F # else @@ -90,7 +90,7 @@ defined(CONFIG_CPU_SH7722) || \ defined(CONFIG_CPU_SH7203) # define SCSPTR (vu_short *)(SCIF_BASE + 0x20) -# define SCLSR (vu_short *)(SCIF_BASE + 0x24) +# define SCLSR (vu_short *)(SCIF_BASE + 0x24) # define LSR_ORER 1 # define FIFOLEVEL_MASK 0x1F #elif defined(CONFIG_CPU_SH7720) @@ -106,31 +106,32 @@ /* SCBRR register value setting */ #if defined(CONFIG_CPU_SH7720) -# define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) +# define SCBRR_VALUE(bps, clk) (((clk * 2) + 16 * bps) / (32 * bps) - 1) #elif defined(CONFIG_CPU_SH7723) && defined(CONFIG_SCIF_A) /* SH7723 SCIFA use bus clock. So clock *2 */ -# define SCBRR_VALUE(bps, clk) (((clk*2*2)+16*bps)/(32*bps)-1) +# define SCBRR_VALUE(bps, clk) (((clk * 2 * 2) + 16 * bps) / (32 * bps) - 1) #else /* Generic SuperH */ -# define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) +# define SCBRR_VALUE(bps, clk) ((clk + 16 * bps) / (32 * bps) - 1) #endif -#define SCR_RE (1 << 4) -#define SCR_TE (1 << 5) +#define SCR_RE (1 << 4) +#define SCR_TE (1 << 5) #define FCR_RFRST (1 << 1) /* RFCL */ #define FCR_TFRST (1 << 2) /* TFCL */ -#define FSR_DR (1 << 0) -#define FSR_RDF (1 << 1) -#define FSR_FER (1 << 3) -#define FSR_BRK (1 << 4) -#define FSR_FER (1 << 3) -#define FSR_TEND (1 << 6) -#define FSR_ER (1 << 7) +#define FSR_DR (1 << 0) +#define FSR_RDF (1 << 1) +#define FSR_FER (1 << 3) +#define FSR_BRK (1 << 4) +#define FSR_FER (1 << 3) +#define FSR_TEND (1 << 6) +#define FSR_ER (1 << 7) /*----------------------------------------------------------------------*/ void serial_setbrg(void) { DECLARE_GLOBAL_DATA_PTR; + *SCBRR = SCBRR_VALUE(gd->baudrate, CONFIG_SYS_CLK_FREQ); } @@ -191,8 +192,8 @@ int serial_tstc(void) return serial_rx_fifo_level() ? 1 : 0; } -#define FSR_ERR_CLEAR 0x0063 -#define RDRF_CLEAR 0x00fc +#define FSR_ERR_CLEAR 0x0063 +#define RDRF_CLEAR 0x00fc void handle_error(void) { -- cgit v1.1 From fc83c9273cec6e6e542f4a0ea3b653b7d0513ffa Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 11 Jan 2009 16:35:16 +0100 Subject: sh: serial: use readx/writex accessors Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nobuhiro Iwamatsu --- drivers/serial/serial_sh.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index e47ec2e..bfdb2ce 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -18,6 +18,7 @@ */ #include +#include #include #if defined(CONFIG_CONS_SCIF0) @@ -132,17 +133,17 @@ void serial_setbrg(void) { DECLARE_GLOBAL_DATA_PTR; - *SCBRR = SCBRR_VALUE(gd->baudrate, CONFIG_SYS_CLK_FREQ); + writeb(SCBRR_VALUE(gd->baudrate, CONFIG_SYS_CLK_FREQ), SCBRR); } int serial_init(void) { - *SCSCR = (SCR_RE | SCR_TE); - *SCSMR = 0; - *SCSMR = 0; - *SCFCR = (FCR_RFRST | FCR_TFRST); - *SCFCR; - *SCFCR = 0; + writew((SCR_RE | SCR_TE), SCSCR); + writew(0, SCSMR); + writew(0, SCSMR); + writew((FCR_RFRST | FCR_TFRST), SCFCR); + readw(SCFCR); + writew(0, SCFCR); serial_setbrg(); return 0; @@ -151,9 +152,9 @@ int serial_init(void) static int serial_rx_fifo_level(void) { #if defined(SCRFDR) - return (*SCRFDR >> 0) & FIFOLEVEL_MASK; + return (readw(SCRFDR) >> 0) & FIFOLEVEL_MASK; #else - return (*SCFDR >> 0) & FIFOLEVEL_MASK; + return (readw(SCFDR) >> 0) & FIFOLEVEL_MASK; #endif } @@ -162,15 +163,15 @@ void serial_raw_putc(const char c) unsigned int fsr_bits_to_clear; while (1) { - if (*SCFSR & FSR_TEND) { /* Tx fifo is empty */ + if (readw(SCFSR) & FSR_TEND) { /* Tx fifo is empty */ fsr_bits_to_clear = FSR_TEND; break; } } - *SCFTDR = c; + writeb(c, SCFTDR); if (fsr_bits_to_clear != 0) - *SCFSR &= ~fsr_bits_to_clear; + writew(readw(SCFSR) & ~fsr_bits_to_clear, SCFSR); } void serial_putc(const char c) @@ -196,22 +197,21 @@ int serial_tstc(void) #define RDRF_CLEAR 0x00fc void handle_error(void) { - - (void)*SCFSR; - *SCFSR = FSR_ERR_CLEAR; - (void)*SCLSR; - *SCLSR = 0x00; + readw(SCFSR); + writew(FSR_ERR_CLEAR, SCFSR); + readw(SCLSR); + writew(0x00, SCLSR); } int serial_getc_check(void) { unsigned short status; - status = *SCFSR; + status = readw(SCFSR); if (status & (FSR_FER | FSR_ER | FSR_BRK)) handle_error(); - if (*SCLSR & LSR_ORER) + if (readw(SCLSR) & LSR_ORER) handle_error(); return status & (FSR_DR | FSR_RDF); } @@ -224,15 +224,15 @@ int serial_getc(void) while (!serial_getc_check()) ; - ch = *SCFRDR; - status = *SCFSR; + ch = readb(SCFRDR); + status = readw(SCFSR); - *SCFSR = RDRF_CLEAR; + writew(RDRF_CLEAR, SCFSR); if (status & (FSR_FER | FSR_FER | FSR_ER | FSR_BRK)) handle_error(); - if (*SCLSR & LSR_ORER) + if (readw(SCLSR) & LSR_ORER) handle_error(); return ch; -- cgit v1.1 From fadad1573fb16c90025f08a2861d6047d093cba7 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 9 Jan 2009 04:38:17 -0500 Subject: ncb: use socklen_t The recvfrom() function takes a socklen_t, not an int. Signed-off-by: Mike Frysinger --- tools/ncb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ncb.c b/tools/ncb.c index 74deebb..7e123f1 100644 --- a/tools/ncb.c +++ b/tools/ncb.c @@ -8,7 +8,7 @@ int main (int argc, char *argv[]) int s, len, o, port = 6666; char buf[512]; struct sockaddr_in addr; - int addr_len = sizeof addr; + socklen_t addr_len = sizeof addr; if (argc > 1) port = atoi (argv[1]); -- cgit v1.1 From c088a108c75db565e07292fd668dfa5491e85bc2 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 14 Jan 2009 13:52:24 +0100 Subject: fdt_resize(): fix actualsize calculations with unaligned blobs The code in fdt_resize() to extend the fdt size to end on a page boundary is wrong for fdt's not located at an address aligned on a page boundary. What's even worse, the code would make actualsize shrink rather than grow if (blob & 0xfff) was bigger than the amount of padding added by ALIGN(), causing fdt_add_mem_rsv to fail. Fix it by aligning end address (blob + size) to a page boundary instead. For aligned fdt's this is equivalent to what we had before. Signed-off-by: Peter Korsgaard --- common/fdt_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/fdt_support.c b/common/fdt_support.c index 5a83bca..a79bc08 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -610,7 +610,7 @@ int fdt_resize(void *blob) fdt_size_dt_strings(blob) + sizeof(struct fdt_reserve_entry); /* Make it so the fdt ends on a page boundary */ - actualsize = ALIGN(actualsize, 0x1000); + actualsize = ALIGN(actualsize + ((uint)blob & 0xfff), 0x1000); actualsize = actualsize - ((uint)blob & 0xfff); /* Change the fdt header to reflect the correct size */ -- cgit v1.1 From 4cda437898f7873752f0201757cd33f12196ce87 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 17 Jan 2009 13:32:42 -0500 Subject: build system: treat all Darwin's alike The x86 based version of Darwin behaves the same quirky way as the powerpc Darwin, so only check HOSTOS when setting up Darwin workarounds. Signed-off-by: Mike Frysinger --- config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.mk b/config.mk index d770f09..b1254e9 100644 --- a/config.mk +++ b/config.mk @@ -46,7 +46,7 @@ PLATFORM_LDFLAGS = ######################################################################### -ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc) +ifeq ($(HOSTOS),darwin) HOSTCC = cc else HOSTCC = gcc @@ -181,7 +181,7 @@ endif # # So far, this is used only by tools/gdb/Makefile. -ifeq ($(HOSTOS)-$(HOSTARCH),darwin-ppc) +ifeq ($(HOSTOS),darwin) BFD_ROOT_DIR = /usr/local/tools else ifeq ($(HOSTARCH),$(ARCH)) -- cgit v1.1 From 635e5f8fc82365e6e9734b3132bc95135a6de679 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Sun, 18 Jan 2009 21:37:48 +0100 Subject: Prepare 2009.01-rc3 Update CHANGELOG Signed-off-by: Wolfgang Denk --- CHANGELOG | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 17c5691..e582ced 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,128 @@ +commit 4cda437898f7873752f0201757cd33f12196ce87 +Author: Mike Frysinger +Date: Sat Jan 17 13:32:42 2009 -0500 + + build system: treat all Darwin's alike + + The x86 based version of Darwin behaves the same quirky way as the powerpc + Darwin, so only check HOSTOS when setting up Darwin workarounds. + + Signed-off-by: Mike Frysinger + +commit c088a108c75db565e07292fd668dfa5491e85bc2 +Author: Peter Korsgaard +Date: Wed Jan 14 13:52:24 2009 +0100 + + fdt_resize(): fix actualsize calculations with unaligned blobs + + The code in fdt_resize() to extend the fdt size to end on a page boundary + is wrong for fdt's not located at an address aligned on a page boundary. + What's even worse, the code would make actualsize shrink rather than grow + if (blob & 0xfff) was bigger than the amount of padding added by ALIGN(), + causing fdt_add_mem_rsv to fail. + + Fix it by aligning end address (blob + size) to a page boundary instead. + For aligned fdt's this is equivalent to what we had before. + + Signed-off-by: Peter Korsgaard + +commit fadad1573fb16c90025f08a2861d6047d093cba7 +Author: Mike Frysinger +Date: Fri Jan 9 04:38:17 2009 -0500 + + ncb: use socklen_t + + The recvfrom() function takes a socklen_t, not an int. + + Signed-off-by: Mike Frysinger + +commit fc83c9273cec6e6e542f4a0ea3b653b7d0513ffa +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun Jan 11 16:35:16 2009 +0100 + + sh: serial: use readx/writex accessors + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit 9e1fa628bdb64745811cdd26c4f953846c076180 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sun Jan 11 16:35:15 2009 +0100 + + sh: serial: coding style cleanup + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit c9935c992575922b7ef13eec0656ed8665d324e3 +Author: Nobuhiro Iwamatsu +Date: Sun Jan 11 17:48:56 2009 +0900 + + sh: Fix compile error on lowlevel_init file + + lowlevel_init of SH was corrected to use the write/readXX macro. + However, there was a problem that was not able to be compiled partially. + This patch corrected this. + + Signed-off-by: Nobuhiro Iwamatsu + +commit a5b04d00bfeb940c62232972ce644d50b45797f9 +Author: Kieran Bingham +Date: Tue Dec 30 01:16:03 2008 +0000 + + sh: Fix up rsk7203 target for out of tree build + + Fix up rsk7203 target to build successfully using out-of-tree build. + + Signed-off-by: Kieran Bingham + Signed-off-by: Nobuhiro Iwamatsu + +commit f7e78f3b74aae9caca2997bad865a72338326c0a +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Dec 20 19:29:49 2008 +0100 + + sh: use write{8,16,32} in all lowlevel_init + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit e4430779623af500de1cee7892c379f07ef59813 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Dec 20 19:29:48 2008 +0100 + + sh: lowlevel_init coding style cleanup + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit 85cb052ee41675ca361e6a4c69455dc715c8f2d9 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Dec 20 15:27:45 2008 +0100 + + sh: update sh2/sh2a timer coding style + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit 1e15ff999322e81af4c0c0c548908f38944ba39c +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Dec 20 15:25:22 2008 +0100 + + sh: update sh timer coding style + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + Signed-off-by: Nobuhiro Iwamatsu + +commit 0e3ece33801e377be67ffa29f083421ad820f28b +Author: Wolfgang Denk +Date: Wed Jan 14 23:26:05 2009 +0100 + + Prepare 2009.01-rc2 + + Update CHANGELOG. + + Signed-off-by: Wolfgang Denk + commit e92c9a860e44c14513c8909ce4299e253a775eeb Author: Wolfgang Denk Date: Wed Jan 14 22:35:30 2009 +0100 @@ -12,6 +137,57 @@ Date: Wed Jan 14 22:35:30 2009 +0100 Signed-off-by: Wolfgang Denk +commit 3ba605d4beec649438539e7df97b5fedb26592fb +Author: Matthias Fuchs +Date: Fri Jan 2 12:18:49 2009 +0100 + + ppc4xx: Add loadpci command to esd's CPCI4052 and CPCI405AB boards + + This patch adds esd's loadpci BSP command to CPCI4052 and + CPCI405AB board. This requires CONFIG_CMD_BSP and CONFIG_PRAM. + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit 600fe46fb3dab7f07604f9009904f31584415114 +Author: Matthias Fuchs +Date: Fri Jan 2 12:18:12 2009 +0100 + + ppc4xx: Disable pci node in device tree on CPCI405 pci adapters + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit f6a1f490d224c600a09137e58d1026d150b8e679 +Author: Matthias Fuchs +Date: Fri Jan 2 12:17:36 2009 +0100 + + ppc4xx: Cleanup CPCI405 board code + + This patch cleans up CPCI405 board support: + - wrap long lines + - unification of spaces in function calls + - remove dead code + + Use correct io accessors on peripherals. + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + +commit fceebb45a0b97e92f9889861f8c3b9cb885e706f +Author: Matthias Fuchs +Date: Fri Jan 2 12:16:35 2009 +0100 + + ppc4xx: Enable auto RS485 mode on PLU405 boards + + This patch turns on the auto RS485 mode in the 2nd external + uart on PLU405 boards. This is a special mode of the used + Exar XR16C2850 uart. Because these boards only have a 485 physical + layer connected it's a good idea to turn it on by default. + + Signed-off-by: Matthias Fuchs + Signed-off-by: Stefan Roese + commit b5f65dfa9aa8e068e62aba4733dc4fd97b1d9bf6 Author: Haiying Wang Date: Tue Jan 13 16:29:28 2009 -0500 diff --git a/Makefile b/Makefile index 8fb1e2a..9c63643 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ VERSION = 2009 PATCHLEVEL = 01 SUBLEVEL = -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc3 ifneq "$(SUBLEVEL)" "" U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) else -- cgit v1.1 From 72d15e705bc3983884105cb7755c7ba80e74a0a5 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Wed, 21 Jan 2009 23:08:12 +0100 Subject: Prepare v2009.01 Signed-off-by: Wolfgang Denk --- CHANGELOG | 10 ++++++++++ Makefile | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index e582ced..bd3a7b7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +commit 635e5f8fc82365e6e9734b3132bc95135a6de679 +Author: Wolfgang Denk +Date: Sun Jan 18 21:37:48 2009 +0100 + + Prepare 2009.01-rc3 + + Update CHANGELOG + + Signed-off-by: Wolfgang Denk + commit 4cda437898f7873752f0201757cd33f12196ce87 Author: Mike Frysinger Date: Sat Jan 17 13:32:42 2009 -0500 diff --git a/Makefile b/Makefile index 9c63643..d533564 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ VERSION = 2009 PATCHLEVEL = 01 SUBLEVEL = -EXTRAVERSION = -rc3 +EXTRAVERSION = ifneq "$(SUBLEVEL)" "" U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) else -- cgit v1.1