--- /dev/null
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=cris
+BOARD:=etrax
+BOARDNAME:=FOXBOARD (ETRAX 100LX)
+FEATURES:=squashfs jffs2
+LINUX_VERSION:=2.6.19.2
+
+include $(INCLUDE_DIR)/kernel-build.mk
+
+define Target/Description
+ Build fimware images for the FOXBOARD made by acmesystems.it
+endef
+
+define Kernel/Prepare/Fox
+ bzcat $(DL_DIR)/$(LINUX_SOURCE) | tar -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
+ if [ -d ./files ]; then $(CP) ./files/* $(LINUX_DIR)/; fi
+ if [ -d ./patches/generic_2.6 ]; then $(PATCH) $(LINUX_DIR) ./patches/generic_2.6; fi
+ if [ -d ./patches/cris ]; then $(PATCH) $(LINUX_DIR) ./patches/cris; fi
+ ln -sf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/include/asm-cris/arch-v10 $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/include/asm-cris/arch
+ ln -sf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/arch/cris/arch-v10 $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/arch/cris/arch
+endef
+
+define Kernel/Prepare
+ $(call Kernel/Prepare/Fox)
+endef
+
+include $(INCLUDE_DIR)/prereq.mk
+
+$(eval $(call RequireCommand,/usr/local/cris/gcc-cris, \
+ Please install the binary cris toolchain. \
+))
+
+#include the profiles
+-include profiles/*.mk
+
+KERNELNAME:="zImage"
+$(eval $(call BuildKernel))
--- /dev/null
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K stop
+console::askfirst:/bin/ash --login
+tts/0::askfirst:/bin/ash --login
+tty1::askfirst:/bin/ash --login
--- /dev/null
+CONFIG_BASE_SMALL=0
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CRIS=y
+# CONFIG_ETRAX100LX is not set
+CONFIG_ETRAX100LX_V2=y
+# CONFIG_ETRAXFS is not set
+# CONFIG_ETRAXFS_SIM is not set
+CONFIG_ETRAX_ARCH_V10=y
+# CONFIG_ETRAX_ARCH_V32 is not set
+CONFIG_ETRAX_AXISFLASHMAP=y
+# CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE is not set
+CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock1 rootfstype=squashfs,jffs2 init=/etc/preinit noinitrd console=ttyS0,115200"
+# CONFIG_ETRAX_CSP0_LEDS is not set
+# CONFIG_ETRAX_DEBUG_PORT0 is not set
+# CONFIG_ETRAX_DEBUG_PORT1 is not set
+# CONFIG_ETRAX_DEBUG_PORT2 is not set
+# CONFIG_ETRAX_DEBUG_PORT3 is not set
+CONFIG_ETRAX_DEBUG_PORT_NULL=y
+CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x4
+# CONFIG_ETRAX_DEF_R_PORT_G_DIR is not set
+CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0xf0
+CONFIG_ETRAX_DEF_R_PORT_PA_DIR=0x1c
+CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=0x00
+CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0x03
+CONFIG_ETRAX_DEF_R_PORT_PB_DIR=0xce
+CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x09603737
+CONFIG_ETRAX_DEF_R_SDRAM_TIMING=0x80008002
+CONFIG_ETRAX_DEF_R_WAITSTATES=0x95f8
+CONFIG_ETRAX_DRAM_SIZE=32
+CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000
+CONFIG_ETRAX_DS1302=y
+CONFIG_ETRAX_DS1302_RSTBIT=2
+CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT=y
+CONFIG_ETRAX_DS1302_SCLBIT=1
+CONFIG_ETRAX_DS1302_SDABIT=0
+CONFIG_ETRAX_DS1302_TRICKLE_CHARGE=0
+CONFIG_ETRAX_ETHERNET=y
+CONFIG_ETRAX_FAST_TIMER=y
+CONFIG_ETRAX_FLASH1_SIZE=0
+CONFIG_ETRAX_FLASH_BUSWIDTH=2
+CONFIG_ETRAX_GPIO=y
+CONFIG_ETRAX_I2C=y
+CONFIG_ETRAX_I2C_CLK_PORT=1
+CONFIG_ETRAX_I2C_DATA_PORT=0
+# CONFIG_ETRAX_I2C_EEPROM is not set
+CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
+# CONFIG_ETRAX_IDE is not set
+CONFIG_ETRAX_LED1G=2
+CONFIG_ETRAX_LED1R=2
+CONFIG_ETRAX_LED2G=3
+CONFIG_ETRAX_LED2R=3
+CONFIG_ETRAX_LED3G=2
+CONFIG_ETRAX_LED3R=2
+CONFIG_ETRAX_NANDFLASH_BUSWIDTH=1
+CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y
+# CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set
+# CONFIG_ETRAX_NO_LEDS is not set
+# CONFIG_ETRAX_NO_PHY is not set
+CONFIG_ETRAX_PA_CHANGEABLE_BITS=0xFF
+CONFIG_ETRAX_PA_CHANGEABLE_DIR=0xFF
+CONFIG_ETRAX_PA_LEDS=y
+CONFIG_ETRAX_PB_CHANGEABLE_BITS=0xFF
+CONFIG_ETRAX_PB_CHANGEABLE_DIR=0xFF
+# CONFIG_ETRAX_PB_LEDS is not set
+# CONFIG_ETRAX_PCF8563 is not set
+CONFIG_ETRAX_PTABLE_SECTOR=0
+CONFIG_ETRAX_RESCUE_SER0=y
+# CONFIG_ETRAX_RESCUE_SER1 is not set
+# CONFIG_ETRAX_RESCUE_SER2 is not set
+# CONFIG_ETRAX_RESCUE_SER3 is not set
+# CONFIG_ETRAX_RS485 is not set
+CONFIG_ETRAX_RTC=y
+CONFIG_ETRAX_SDRAM=y
+CONFIG_ETRAX_SER0_CD_ON_PA_BIT=-1
+CONFIG_ETRAX_SER0_CD_ON_PB_BIT=-1
+CONFIG_ETRAX_SER0_DSR_ON_PA_BIT=-1
+CONFIG_ETRAX_SER0_DSR_ON_PB_BIT=-1
+CONFIG_ETRAX_SER0_DTR_ON_PA_BIT=-1
+CONFIG_ETRAX_SER0_DTR_ON_PB_BIT=-1
+# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED is not set
+CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE=y
+# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA is not set
+# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
+CONFIG_ETRAX_SER0_RI_ON_PA_BIT=-1
+CONFIG_ETRAX_SER0_RI_ON_PB_BIT=-1
+CONFIG_ETRAX_SER2_CD_ON_PA_BIT=7
+CONFIG_ETRAX_SER2_CD_ON_PB_BIT=-1
+CONFIG_ETRAX_SER2_DSR_ON_PA_BIT=6
+CONFIG_ETRAX_SER2_DSR_ON_PB_BIT=-1
+CONFIG_ETRAX_SER2_DTR_ON_PA_BIT=4
+CONFIG_ETRAX_SER2_DTR_ON_PB_BIT=-1
+# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED is not set
+# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE is not set
+CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA=y
+# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PB is not set
+CONFIG_ETRAX_SER2_RI_ON_PA_BIT=5
+CONFIG_ETRAX_SER2_RI_ON_PB_BIT=-1
+CONFIG_ETRAX_SER3_CD_ON_PA_BIT=-1
+CONFIG_ETRAX_SER3_CD_ON_PB_BIT=-1
+CONFIG_ETRAX_SER3_DSR_ON_PA_BIT=-1
+CONFIG_ETRAX_SER3_DSR_ON_PB_BIT=-1
+CONFIG_ETRAX_SER3_DTR_ON_PA_BIT=-1
+CONFIG_ETRAX_SER3_DTR_ON_PB_BIT=-1
+# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED is not set
+CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE=y
+# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA is not set
+# CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PB is not set
+CONFIG_ETRAX_SER3_RI_ON_PA_BIT=-1
+CONFIG_ETRAX_SER3_RI_ON_PB_BIT=-1
+CONFIG_ETRAX_SERIAL=y
+# CONFIG_ETRAX_SERIAL_FAST_TIMER is not set
+# CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is not set
+CONFIG_ETRAX_SERIAL_PORT0=y
+# CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT is not set
+# CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN is not set
+CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN=y
+CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT=y
+# CONFIG_ETRAX_SERIAL_PORT1 is not set
+CONFIG_ETRAX_SERIAL_PORT2=y
+CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y
+CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y
+# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set
+# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set
+CONFIG_ETRAX_SERIAL_PORT3=y
+CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT=y
+CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN=y
+# CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN is not set
+# CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT is not set
+CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS=5
+# CONFIG_ETRAX_SOFT_SHUTDOWN is not set
+# CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
+CONFIG_ETRAX_SYSFS_NODES=y
+CONFIG_ETRAX_USB_HOST=y
+CONFIG_ETRAX_USB_HOST_PORT1=y
+CONFIG_ETRAX_USB_HOST_PORT2=y
+# CONFIG_ETRAX_WATCHDOG is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_IOMAP=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_IDE is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQ_PER_CPU=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_MTD=y
+CONFIG_MTDRAM_ABS_POS=0x0
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTDRAM_TOTAL_SIZE=0
+# CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLOCK2MTD is not set
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_CONCAT=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+CONFIG_MTD_MTDRAM=y
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_OOM_REBOOT is not set
+# CONFIG_OVERRIDE_SCHED_STARVATION_LIMIT is not set
+# CONFIG_RTC is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SMP is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SVINTO_SIM is not set
+# CONFIG_SYSTEM_PROFILER is not set
+CONFIG_UID16=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_USB=y
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_BLK_DEV_INITRD is not set
--- /dev/null
+/*
+ * Simple bitbanged-GPIO SPI driver for ETRAX FS et al.
+ *
+ * Copyright (c) 2007 Axis Communications AB
+ *
+ * Author: Hans-Peter Nilsson, inspired by earlier work by
+ * Andre Spanberg but mostly by copying large parts of
+ * spi_s3c24xx_gpio.c, hence also:
+ * Copyright (c) 2006 Ben Dooks
+ * Copyright (c) 2006 Simtec Electronics
+ *
+ * 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 <linux/types.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/arch/board.h>
+
+/* Our main driver state. */
+
+struct crisv32_spi_hw_info {
+ struct crisv32_iopin sclk;
+ struct crisv32_iopin mosi;
+ struct crisv32_iopin miso;
+ struct crisv32_iopin cs;
+};
+
+/*
+ * The driver state hides behind the spi_bitbang state. We're
+ * responsible for allocating that, so we can get a little something
+ * for ourselves.
+ */
+
+struct crisv32_spi_gpio_devdata {
+ struct spi_bitbang bitbang;
+ struct crisv32_spi_hw_info pins;
+};
+
+/* Helper function getting the driver state from a spi_device. */
+
+static inline struct crisv32_spi_hw_info *spidev_to_hw(struct spi_device *spi)
+{
+ struct crisv32_spi_gpio_devdata *dd = spi_master_get_devdata(spi->master);
+ return &dd->pins;
+}
+
+/* The SPI-bitbang functions: see spi_bitbang.h at EXPAND_BITBANG_TXRX. */
+
+static inline void setsck(struct spi_device *spi, int is_on)
+{
+ crisv32_io_set(&spidev_to_hw(spi)->sclk, is_on != 0);
+}
+
+static inline void setmosi(struct spi_device *spi, int is_on)
+{
+ crisv32_io_set(&spidev_to_hw(spi)->mosi, is_on != 0);
+}
+
+static inline u32 getmiso(struct spi_device *spi)
+{
+ return crisv32_io_rd(&spidev_to_hw(spi)->miso) != 0 ? 1 : 0;
+}
+
+#define spidelay(x) ndelay(x)
+
+#define EXPAND_BITBANG_TXRX
+#include <linux/spi/spi_bitbang.h>
+
+/*
+ * SPI-bitbang word transmit-functions for the four SPI modes,
+ * dispatching to the inlined functions we just included.
+ */
+
+static u32 crisv32_spi_gpio_txrx_mode0(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+}
+
+static u32 crisv32_spi_gpio_txrx_mode1(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
+}
+
+static u32 crisv32_spi_gpio_txrx_mode2(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
+}
+
+static u32 crisv32_spi_gpio_txrx_mode3(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
+}
+
+/* SPI-bitbang chip-select function. */
+
+static void crisv32_spi_gpio_chipselect(struct spi_device *spi, int value)
+{
+ if (spi->mode & SPI_CS_HIGH)
+ crisv32_io_set(&spidev_to_hw(spi)->cs,
+ value == BITBANG_CS_ACTIVE ? 1 : 0);
+ else
+ crisv32_io_set(&spidev_to_hw(spi)->cs,
+ value == BITBANG_CS_ACTIVE ? 0 : 1);
+}
+
+/* Platform-device probe function. */
+
+static int __devinit crisv32_spi_gpio_probe(struct platform_device *dev)
+{
+ struct spi_master *master;
+ struct crisv32_spi_gpio_devdata *dd;
+ struct resource *res;
+ struct crisv32_spi_gpio_controller_data *gc;
+ int ret = 0;
+
+ /*
+ * We need to get the controller data as a hardware resource,
+ * or else it wouldn't be available until *after* the
+ * spi_bitbang_start call!
+ */
+ res = platform_get_resource_byname(dev, 0, "controller_data_ptr");
+ if (res == NULL) {
+ dev_err(&dev->dev, "can't get controller_data resource\n");
+ return -EIO;
+ }
+
+ gc = (struct crisv32_spi_gpio_controller_data *) res->start;
+
+ master = spi_alloc_master(&dev->dev, sizeof *dd);
+ if (master == NULL) {
+ dev_err(&dev->dev, "failed to allocate spi master\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ dd = spi_master_get_devdata(master);
+ platform_set_drvdata(dev, dd);
+
+ /*
+ * The device data asks for this driver, and holds the id
+ * number, which must be unique among the same-type devices.
+ * We use this as the number of this SPI bus.
+ */
+ master->bus_num = dev->id;
+
+ /*
+ * Allocate pins. Note that thus being allocated as GPIO, we
+ * don't have to deconfigure them at the end or if something
+ * fails.
+ */
+ if ((ret = crisv32_io_get_name(&dd->pins.cs, gc->cs)) != 0
+ || (ret = crisv32_io_get_name(&dd->pins.miso, gc->miso)) != 0
+ || (ret = crisv32_io_get_name(&dd->pins.mosi, gc->mosi)) != 0
+ || (ret = crisv32_io_get_name(&dd->pins.sclk, gc->sclk)) != 0)
+ goto err_no_pins;
+
+ /* Set directions of the SPI pins. */
+ crisv32_io_set_dir(&dd->pins.cs, crisv32_io_dir_out);
+ crisv32_io_set_dir(&dd->pins.sclk, crisv32_io_dir_out);
+ crisv32_io_set_dir(&dd->pins.miso, crisv32_io_dir_in);
+ crisv32_io_set_dir(&dd->pins.mosi, crisv32_io_dir_out);
+
+ /* Set state of the SPI pins. */
+ dev_dbg(&dev->dev, "cs.port 0x%x, pin: %d\n"
+ dd->pins.cs.port, dd->pins.cs.bit);
+
+ /*
+ * Can't use crisv32_spi_gpio_chipselect(spi, 1) here; we
+ * don't have a proper "spi" until after spi_bitbang_start.
+ */
+ crisv32_io_set(&dd->pins.cs, 1);
+ crisv32_io_set(&dd->pins.sclk, 0);
+ crisv32_io_set(&dd->pins.mosi, 0);
+
+ /* Setup SPI bitbang adapter hooks. */
+ dd->bitbang.master = spi_master_get(master);
+ dd->bitbang.chipselect = crisv32_spi_gpio_chipselect;
+
+ dd->bitbang.txrx_word[SPI_MODE_0] = crisv32_spi_gpio_txrx_mode0;
+ dd->bitbang.txrx_word[SPI_MODE_1] = crisv32_spi_gpio_txrx_mode1;
+ dd->bitbang.txrx_word[SPI_MODE_2] = crisv32_spi_gpio_txrx_mode2;
+ dd->bitbang.txrx_word[SPI_MODE_3] = crisv32_spi_gpio_txrx_mode3;
+
+ ret = spi_bitbang_start(&dd->bitbang);
+ if (ret)
+ goto err_no_bitbang;
+
+ printk (KERN_INFO "CRIS v32 SPI driver for GPIO"
+ " (cs: %s, miso: %s, mosi: %s, sclk: %s)\n",
+ gc->cs, gc->miso, gc->mosi, gc->sclk);
+
+ return 0;
+
+ err_no_bitbang:
+ spi_master_put(dd->bitbang.master);
+ err_no_pins:
+ platform_set_drvdata(dev, NULL);
+ err:
+ return ret;
+}
+
+/* Platform-device remove-function. */
+
+static int __devexit crisv32_spi_gpio_remove(struct platform_device *dev)
+{
+ struct crisv32_spi_gpio_devdata *dd = platform_get_drvdata(dev);
+ int ret;
+
+ ret = spi_bitbang_stop(&dd->bitbang);
+ if (ret != 0)
+ return ret;
+
+ spi_master_put(dd->bitbang.master);
+ platform_set_drvdata(dev, NULL);
+ return 0;
+}
+
+/*
+ * For the time being, there's no suspend/resume support to care
+ * about, so we let those handlers default to NULL.
+ */
+static struct platform_driver crisv32_spi_gpio_drv = {
+ .probe = crisv32_spi_gpio_probe,
+ .remove = __devexit_p(crisv32_spi_gpio_remove),
+ .driver = {
+ .name = "spi_crisv32_gpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+/* Module init function. */
+
+static int __devinit crisv32_spi_gpio_init(void)
+{
+ return platform_driver_register(&crisv32_spi_gpio_drv);
+}
+
+/* Module exit function. */
+
+static void __devexit crisv32_spi_gpio_exit(void)
+{
+ platform_driver_unregister(&crisv32_spi_gpio_drv);
+}
+
+module_init(crisv32_spi_gpio_init);
+module_exit(crisv32_spi_gpio_exit);
+
+MODULE_DESCRIPTION("CRIS v32 SPI-GPIO Driver");
+MODULE_AUTHOR("Hans-Peter Nilsson, <hp@axis.com>");
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ * SPI port driver for ETRAX FS et al. using a synchronous serial
+ * port, but simplified by using the spi_bitbang framework.
+ *
+ * Copyright (c) 2007 Axis Communications AB
+ *
+ * Author: Hans-Peter Nilsson, though copying parts of
+ * spi_s3c24xx_gpio.c, hence also:
+ * Copyright (c) 2006 Ben Dooks
+ * Copyright (c) 2006 Simtec Electronics
+ *
+ * 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 driver restricts frequency, polarity, "word" length and endian
+ * much more than the hardware does. I'm happy to unrestrict it, but
+ * only with what I can test myself (at time of writing, just SD/MMC
+ * SPI) and what people actually test and report.
+ */
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/arch/board.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/sser_defs.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/hwregs/dma.h>
+
+/* A size "not much larger" than the max typical transfer size. */
+#define DMA_CHUNKSIZ 512
+
+/*
+ * For a transfer expected to take this long, we busy-wait instead of enabling
+ * interrupts.
+ */
+#define IRQ_USAGE_THRESHOLD_NS 14000
+
+/* A few register access macros to avoid verbiage and reduce typos. */
+#define REG_RD_DI(reg) REG_RD(dma, regi_dmain, reg)
+#define REG_RD_DO(reg) REG_RD(dma, regi_dmaout, reg)
+#define REG_RD_SSER(reg) REG_RD(sser, regi_sser, reg)
+#define REG_WR_DI(reg, val) REG_WR(dma, regi_dmain, reg, val)
+#define REG_WR_DO(reg, val) REG_WR(dma, regi_dmaout, reg, val)
+#define REG_WR_SSER(reg, val) REG_WR(sser, regi_sser, reg, val)
+#define REG_WRINT_DI(reg, val) REG_WR_INT(dma, regi_dmain, reg, val)
+#define REG_WRINT_DO(reg, val) REG_WR_INT(dma, regi_dmaout, reg, val)
+#define REG_WRINT_SSER(reg, val) REG_WR_INT(sser, regi_sser, reg, val)
+#define REG_RDINT_DI(reg) REG_RD_INT(dma, regi_dmain, reg)
+#define REG_RDINT_DO(reg) REG_RD_INT(dma, regi_dmaout, reg)
+#define REG_RDINT_SSER(reg) REG_RD_INT(sser, regi_sser, reg)
+
+#define DMA_WAIT_UNTIL_RESET(inst) \
+ do { \
+ reg_dma_rw_stat r; \
+ do { \
+ r = REG_RD(dma, (inst), rw_stat); \
+ } while (r.mode != regk_dma_rst); \
+ } while (0)
+
+#define DMA_BUSY(inst) (REG_RD(dma, inst, rw_stream_cmd)).busy
+
+/* Our main driver state. */
+struct crisv32_spi_hw_info {
+ struct crisv32_regi_n_int sser;
+ struct crisv32_regi_n_int dmain;
+ struct crisv32_regi_n_int dmaout;
+
+ reg_sser_rw_cfg cfg;
+ reg_sser_rw_frm_cfg frm_cfg;
+ reg_sser_rw_tr_cfg tr_cfg;
+ reg_sser_rw_rec_cfg rec_cfg;
+ reg_sser_rw_extra extra;
+
+ /* We store the speed in kHz, so we can have expressions
+ * multiplying 100MHz by * 4 before dividing by it, and still
+ * keep it in an u32. */
+ u32 effective_speed_kHz;
+
+ /*
+ * The time in 10s of nanoseconds for half a cycles.
+ * For convenience and performance; derived from the above.
+ */
+ u32 half_cycle_delay_ns;
+
+ /* This should be overridable by a module parameter. */
+ u32 max_speed_Hz;
+
+ /* Pre-computed timout for the max transfer chunk-size. */
+ u32 dma_timeout;
+
+ struct completion dma_done;
+
+ /*
+ * If we get a timeout from wait_for_completion_timeout on the
+ * above, first look at this before panicking.
+ */
+ u32 dma_actually_done;
+
+ /*
+ * Resources don't seem available at the remove call, so we
+ * have to save information we get through them.
+ */
+ struct crisv32_spi_sser_controller_data *gc;
+};
+
+/*
+ * The driver state hides behind the spi_bitbang state; we're
+ * responsible for allocating that, so we can get a little something
+ * for ourselves.
+ */
+struct crisv32_spi_sser_devdata {
+ struct spi_bitbang bitbang;
+ struct crisv32_spi_hw_info hw;
+};
+
+/* Our DMA descriptors that need alignment. */
+struct crisv32_spi_dma_descrs {
+ dma_descr_context in_ctxt __attribute__ ((__aligned__(32)));
+ dma_descr_context out_ctxt __attribute__ ((__aligned__(32)));
+
+ /*
+ * The code takes advantage of the fact that in_descr and
+ * out_descr are on the same cache-line when working around
+ * the cache-bug in TR 106.
+ */
+ dma_descr_data in_descr __attribute__ ((__aligned__(16)));
+ dma_descr_data out_descr __attribute__ ((__aligned__(16)));
+};
+
+/*
+ * Whatever needs DMA access is here, besides whatever DMA-able memory
+ * comes in transfers.
+ */
+struct crisv32_spi_dma_cs {
+ struct crisv32_spi_dma_descrs *descrp;
+
+ /* Scratch-buffers when the original was non-DMA. */
+ u8 rx_buf[DMA_CHUNKSIZ];
+ u8 tx_buf[DMA_CHUNKSIZ];
+};
+
+/*
+ * Max speed. If set, we won't go faster, promise. May be useful
+ * when dealing with weak hardware; misrouted signal paths or various
+ * debug-situations.
+ */
+static ulong crisv32_spi_speed_limit_Hz = 0;
+
+/* Helper function getting the driver state from a spi_device. */
+
+static inline struct crisv32_spi_hw_info *spidev_to_hw(struct spi_device *spi)
+{
+ struct crisv32_spi_sser_devdata *dd = spi_master_get_devdata(spi->master);
+ return &dd->hw;
+}
+
+/* SPI-bitbang word transmit-function for non-DMA. */
+
+static u32 crisv32_spi_sser_txrx_mode3(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ u32 regi_sser = hw->sser.regi;
+ reg_sser_rw_ack_intr ack_intr = { .trdy = 1, .rdav = 1 };
+ reg_sser_r_intr intr = {0};
+ reg_sser_rw_tr_data w_data = { .data = (u8) word };
+ reg_sser_r_rec_data r_data;
+ u32 i;
+
+ /*
+ * The timeout reflects one iteration per 10ns (impossible at
+ * 200MHz clock even without the ndelay) and a wait for a full
+ * byte.
+ */
+ u32 timeout = 1000000/10*8/hw->effective_speed_kHz;
+
+ BUG_ON(bits != 8);
+
+ intr = REG_RD_SSER(r_intr);
+
+ /*
+ * We should never get xruns when we control the transmitter
+ * and receiver in register mode. And if we don't have
+ * transmitter-ready and data-ready on entry, something's
+ * seriously fishy.
+ */
+ if (!intr.trdy || !intr.rdav || intr.orun || intr.urun)
+ panic("sser hardware or SPI driver broken (1) 0x%x\n",
+ REG_TYPE_CONV(u32, reg_sser_r_intr, intr));
+
+ REG_WR_SSER(rw_ack_intr, ack_intr);
+ REG_WR_SSER(rw_tr_data, w_data);
+
+ for (i = 0; i < timeout; i++) {
+ intr = REG_RD_SSER(r_intr);
+ /* Wait for received data. */
+ if (intr.rdav)
+ break;
+ ndelay(10);
+ }
+
+ if (!(intr.trdy && intr.rdav) || intr.orun || intr.urun)
+ panic("sser hardware or SPI driver broken (2) 0x%x\n",
+ REG_TYPE_CONV(u32, reg_sser_r_intr, intr));
+
+ r_data = REG_RD_SSER(r_rec_data);
+ return r_data.data & 0xff;
+}
+
+/*
+ * Wait for 1/2 bit-time if the transmitter or receiver is enabled.
+ * We need to do this as the data-available indications may arrive
+ * right at the edge, with half the last cycle remaining.
+ */
+static void inline crisv32_spi_sser_wait_halfabit(struct crisv32_spi_hw_info
+ *hw)
+{
+ if (hw->cfg.en)
+ ndelay(hw->half_cycle_delay_ns);
+}
+
+/*
+ * Assert or de-assert chip-select.
+ * We have two functions, with the active one assigned to the bitbang
+ * slot at setup, to avoid a performance penalty (1% on reads).
+ */
+static void crisv32_spi_sser_chip_select_active_high(struct spi_device *spi,
+ int value)
+{
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ u32 regi_sser = hw->sser.regi;
+
+ /*
+ * We may have received data at the "last producing clock
+ * edge". Thus we delay for another half a clock cycle.
+ */
+ crisv32_spi_sser_wait_halfabit(hw);
+
+ hw->frm_cfg.frame_pin_use
+ = value == BITBANG_CS_ACTIVE ? regk_sser_gio1 : regk_sser_gio0;
+ REG_WR_SSER(rw_frm_cfg, hw->frm_cfg);
+}
+
+static void crisv32_spi_sser_chip_select_active_low(struct spi_device *spi,
+ int value)
+{
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ u32 regi_sser = hw->sser.regi;
+
+ crisv32_spi_sser_wait_halfabit(hw);
+ hw->frm_cfg.frame_pin_use
+ = value == BITBANG_CS_ACTIVE ? regk_sser_gio0 : regk_sser_gio1;
+ REG_WR_SSER(rw_frm_cfg, hw->frm_cfg);
+}
+
+/* Set the transmission speed in Hz. */
+
+static int crisv32_spi_sser_set_speed_Hz(struct crisv32_spi_hw_info *hw,
+ u32 Hz)
+{
+ u32 kHz;
+ u32 ns_delay;
+ u32 regi_sser = hw->sser.regi;
+
+ if (Hz > hw->max_speed_Hz)
+ /*
+ * Should we complain? Return error? Current caller
+ * sequences want just the max speed.
+ */
+ Hz = hw->max_speed_Hz;
+
+ kHz = Hz/1000;
+
+ /*
+ * If absolutely needed, we *could* change the base frequency
+ * and go lower. Usually, a frequency set higher than wanted
+ * is a problem but lower isn't.
+ */
+ if (Hz < 100000000 / 65536 + 1) {
+ printk(KERN_ERR "attempt to set invalid sser speed: %u Hz\n",
+ Hz);
+ Hz = 100000000 / 65536 + 1;
+ }
+
+ pr_debug("setting sser speed to %u Hz\n", Hz);
+
+ /*
+ * Avoid going above the requested speed if there's a
+ * remainder for the 100 MHz clock-divider calculation, but
+ * don't unnecessarily go below if it's even.
+ */
+ hw->cfg.clk_div = 100000000/Hz - ((100000000 % Hz) == 0);
+
+ /* Make sure there's no ongoing transmission. */
+ crisv32_spi_sser_wait_halfabit(hw);
+
+ /*
+ * Wait for 3 times max of the old and the new clock before and after
+ * changing the frequency. Not because of documentation or empirical
+ * need, but because it seems sane to do so. The three-bit-times
+ * value is because that's the documented time it takes for a reset to
+ * take effect.
+ */
+ ns_delay = 1000000*3/(kHz > hw->effective_speed_kHz
+ ? kHz : hw->effective_speed_kHz);
+ ndelay(ns_delay);
+ REG_WR_SSER(rw_cfg, hw->cfg);
+ ndelay(ns_delay);
+
+ hw->effective_speed_kHz = kHz;
+
+ /*
+ * A timeout of twice the time for the largest chunk (not
+ * counting DMA overhead) plus one jiffy, should be more than
+ * enough for the transmission.
+ */
+ hw->dma_timeout = 1 + usecs_to_jiffies(1000*2*DMA_CHUNKSIZ*8/kHz);
+
+ hw->half_cycle_delay_ns
+ = 1000000/2/hw->effective_speed_kHz;
+
+ pr_debug(".clk_div %d, half %d, eff %d\n",
+ hw->cfg.clk_div, hw->half_cycle_delay_ns,
+ hw->effective_speed_kHz);
+ return 0;
+}
+
+/*
+ * Set up transmitter and receiver for non-DMA access.
+ * Unfortunately, it doesn't seem like hispeed works for this mode
+ * (mea culpa), so we're stuck with lospeed-mode. A little slower,
+ * but that's what you get for not allocating DMA.
+ */
+static int crisv32_setup_spi_sser_for_reg_access(struct crisv32_spi_hw_info *hw)
+{
+ u32 regi_sser = hw->sser.regi;
+
+ reg_sser_rw_cfg cfg = {0};
+ reg_sser_rw_frm_cfg frm_cfg = {0};
+ reg_sser_rw_tr_cfg tr_cfg = {0};
+ reg_sser_rw_rec_cfg rec_cfg = {0};
+ reg_sser_rw_intr_mask mask = {0};
+ reg_sser_rw_extra extra = {0};
+ reg_sser_rw_tr_data tr_data = {0};
+ reg_sser_r_intr intr;
+
+ cfg.en = 0;
+ tr_cfg.tr_en = 1;
+ rec_cfg.rec_en = 1;
+ REG_WR_SSER(rw_cfg, cfg);
+ REG_WR_SSER(rw_tr_cfg, tr_cfg);
+ REG_WR_SSER(rw_rec_cfg, rec_cfg);
+ REG_WR_SSER(rw_intr_mask, mask);
+
+ /*
+ * See 23.7.2 SPI in the hardware documentation.
+ * Except our configuration uses bulk mode; MMC/SD-SPI
+ * isn't isochronous in nature.
+ * Step 1.
+ */
+ cfg.gate_clk = regk_sser_yes;
+ cfg.clkgate_in = regk_sser_no;
+ cfg.clkgate_ctrl = regk_sser_tr;
+
+ /* Step 2. */
+ cfg.out_clk_pol = regk_sser_pos;
+ cfg.out_clk_src = regk_sser_intern_clk;
+
+ /* Step 3. */
+ tr_cfg.clk_src = regk_sser_intern;
+ rec_cfg.clk_src = regk_sser_intern;
+ frm_cfg.clk_src = regk_sser_intern;
+
+ /* Step 4. */
+ tr_cfg.clk_pol = regk_sser_neg;
+ rec_cfg.clk_pol = regk_sser_pos;
+ frm_cfg.clk_pol = regk_sser_neg;
+
+ /*
+ * Step 5: frame pin (PC03 or PD03) is frame; the status pin
+ * (PC02, PD02) is configured as input.
+ */
+ frm_cfg.frame_pin_dir = regk_sser_out;
+
+ /*
+ * Contrary to the doc example, we don't generate the frame
+ * signal "automatically". This setting of the frame pin as
+ * constant 1, reflects an inactive /CS setting, for just idle
+ * clocking. When we need to transmit or receive data, we
+ * change it.
+ */
+ frm_cfg.frame_pin_use = regk_sser_gio1;
+ frm_cfg.status_pin_dir = regk_sser_in;
+
+ /*
+ * Step 6. This is probably not necessary, as we don't
+ * generate the frame signal automatically. Nevertheless,
+ * modified for bulk transmission.
+ */
+ frm_cfg.out_on = regk_sser_tr;
+ frm_cfg.out_off = regk_sser_tr;
+
+ /* Step 7. Similarly, maybe not necessary. */
+ frm_cfg.type = regk_sser_level;
+ frm_cfg.level = regk_sser_neg_lo;
+
+ /* Step 8. These we have to set according to the bulk mode,
+ * which for tr_delay is the same as for iso; a value of 1
+ * means in sync with the frame signal. For rec_delay, we
+ * start it at the same time as the transmitter. See figure
+ * 23.7 in the hw documentation. */
+ frm_cfg.tr_delay = 1;
+ frm_cfg.rec_delay = 0;
+
+ /* Step 9. */
+ tr_cfg.sample_size = 7;
+ rec_cfg.sample_size = 7;
+
+ /* Step 10. */
+ frm_cfg.wordrate = 7;
+
+ /* Step 11 (but for bulk). */
+ tr_cfg.rate_ctrl = regk_sser_bulk;
+
+ /*
+ * Step 12. Similarly, maybe not necessary; still, modified
+ * for bulk.
+ */
+ tr_cfg.frm_src = regk_sser_intern;
+ rec_cfg.frm_src = regk_sser_tx_bulk;
+
+ /* Step 13. */
+ tr_cfg.mode = regk_sser_lospeed;
+ rec_cfg.mode = regk_sser_lospeed;
+
+ /* Step 14. */
+ tr_cfg.sh_dir = regk_sser_msbfirst;
+ rec_cfg.sh_dir = regk_sser_msbfirst;
+
+ /*
+ * Extra step for bulk-specific settings and other general
+ * settings not specified in the SPI config example.
+ * It's uncertain whether all of these are needed.
+ */
+ tr_cfg.bulk_wspace = 1;
+ tr_cfg.use_dma = 0;
+
+ tr_cfg.urun_stop = 1;
+ rec_cfg.orun_stop = 1;
+ rec_cfg.use_dma = 0;
+
+ rec_cfg.fifo_thr = regk_sser_inf;
+ frm_cfg.early_wend = regk_sser_yes;
+
+ cfg.clk_dir = regk_sser_out;
+ tr_cfg.data_pin_use = regk_sser_dout;
+ cfg.base_freq = regk_sser_f100;
+
+ /* Setup for the initial frequency given to us. */
+ hw->cfg = cfg;
+ crisv32_spi_sser_set_speed_Hz(hw, hw->max_speed_Hz);
+ cfg = hw->cfg;
+
+ /*
+ * Write it all, except cfg which is already written by
+ * crisv32_spi_sser_set_speed_Hz.
+ */
+ REG_WR_SSER(rw_frm_cfg, frm_cfg);
+ REG_WR_SSER(rw_tr_cfg, tr_cfg);
+ REG_WR_SSER(rw_rec_cfg, rec_cfg);
+ REG_WR_SSER(rw_extra, extra);
+
+ /*
+ * The transmit-register needs to be written before the
+ * transmitter is enabled, and to get a valid trdy signal
+ * waiting for us when we want to transmit a byte. Because
+ * the "frame event" is that the transmitter is written, this
+ * will cause a dummy 0xff-byte to be transmitted, but that's
+ * ok, because /CS is inactive.
+ */
+ tr_data.data = 0xffff;
+ REG_WR_SSER(rw_tr_data, tr_data);
+
+ /*
+ * We ack everything interrupt-wise; left-over indicators don't have
+ * to come from *this* code.
+ */
+ REG_WRINT_SSER(rw_ack_intr, -1);
+
+ /*
+ * Wait 3 cycles before enabling, after the transmit register
+ * has been written. (This'll be just a few microseconds for
+ * e.g. 400 KHz.)
+ */
+ ndelay(3 * 2 * hw->half_cycle_delay_ns);
+ cfg.en = 1;
+
+ REG_WR_SSER(rw_cfg, cfg);
+
+ /*
+ * Now wait for 8 + 3 cycles. The 0xff byte should now have
+ * been transmitted and dummy data received.
+ */
+ ndelay((8 + 3) * 2 * hw->half_cycle_delay_ns);
+
+ /*
+ * Sanity-check that we have data-available and the
+ * transmitter is ready to send new data.
+ */
+ intr = REG_RD_SSER(r_intr);
+ if (!intr.rdav || !intr.trdy)
+ panic("sser hw or SPI driver broken (3) 0x%x",
+ REG_TYPE_CONV(u32, reg_sser_r_intr, intr));
+
+ hw->frm_cfg = frm_cfg;
+ hw->tr_cfg = tr_cfg;
+ hw->rec_cfg = rec_cfg;
+ hw->extra = extra;
+ hw->cfg = cfg;
+ return 0;
+}
+
+/* Initialization, maybe fault recovery. */
+
+static void crisv32_reset_dma_hw(u32 regi)
+{
+ REG_WR_INT(dma, regi, rw_intr_mask, 0);
+
+ DMA_RESET(regi);
+ DMA_WAIT_UNTIL_RESET(regi);
+ DMA_ENABLE(regi);
+ REG_WR_INT(dma, regi, rw_ack_intr, -1);
+
+ DMA_WR_CMD(regi, regk_dma_set_w_size1);
+}
+
+/* Interrupt from SSER, for use with DMA when only the transmitter is used. */
+
+static irqreturn_t sser_interrupt(int irqno, void *arg)
+{
+ struct crisv32_spi_hw_info *hw = arg;
+ u32 regi_sser = hw->sser.regi;
+ reg_sser_r_intr intr = REG_RD_SSER(r_intr);
+
+ if (intr.tidle == 0 && intr.urun == 0) {
+ printk(KERN_ERR
+ "sser @0x%x: spurious sser intr, flags: 0x%x\n",
+ regi_sser, REG_TYPE_CONV(u32, reg_sser_r_intr, intr));
+ } else if (intr.urun == 0) {
+ hw->dma_actually_done = 1;
+ complete(&hw->dma_done);
+ } else {
+ /*
+ * Make any reception time out and notice the error,
+ * which it might not otherwise do data was *received*
+ * successfully.
+ */
+ u32 regi_dmain = hw->dmain.regi;
+
+ /*
+ * Recommended practice before acking urun is to turn
+ * off sser. That might not be enough to stop DMA-in
+ * from signalling success if the underrun was late in
+ * the transmission, so we disable the DMA-in
+ * interrupts too.
+ */
+ REG_WRINT_SSER(rw_cfg, 0);
+ REG_WRINT_DI(rw_intr_mask, 0);
+ REG_WRINT_DI(rw_ack_intr, -1);
+ }
+
+ REG_WRINT_SSER(rw_intr_mask, 0);
+
+ /*
+ * We must at least ack urun together with tidle, but keep it
+ * simple and ack them all.
+ */
+ REG_WRINT_SSER(rw_ack_intr, -1);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Interrupt from receiver DMA connected to SSER, for use when the
+ * receiver is used, with or without the transmitter.
+ */
+static irqreturn_t rec_dma_interrupt(int irqno, void *arg)
+{
+ struct crisv32_spi_hw_info *hw = arg;
+ u32 regi_dmain = hw->dmain.regi;
+ u32 regi_sser = hw->sser.regi;
+ reg_dma_r_intr intr = REG_RD_DI(r_intr);
+
+ if (intr.data == 0) {
+ printk(KERN_ERR
+ "sser @0x%x: spurious rec dma intr, flags: 0x%x\n",
+ regi_dmain, REG_TYPE_CONV(u32, reg_dma_r_intr, intr));
+ } else {
+ hw->dma_actually_done = 1;
+ complete(&hw->dma_done);
+ }
+
+ REG_WRINT_DI(rw_intr_mask, 0);
+
+ /* Avoid false underrun indications; stop all sser interrupts. */
+ REG_WRINT_SSER(rw_intr_mask, 0);
+ REG_WRINT_SSER(rw_ack_intr, -1);
+
+ REG_WRINT_DI(rw_ack_intr, -1);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Set up transmitter and receiver for DMA access. We use settings
+ * from the "Atmel fast flash" example.
+ */
+static int crisv32_setup_spi_sser_for_dma_access(struct crisv32_spi_hw_info
+ *hw)
+{
+ int ret;
+ u32 regi_sser = hw->sser.regi;
+
+ reg_sser_rw_cfg cfg = {0};
+ reg_sser_rw_frm_cfg frm_cfg = {0};
+ reg_sser_rw_tr_cfg tr_cfg = {0};
+ reg_sser_rw_rec_cfg rec_cfg = {0};
+ reg_sser_rw_intr_mask mask = {0};
+ reg_sser_rw_extra extra = {0};
+
+ cfg.en = 0;
+ tr_cfg.tr_en = 1;
+ rec_cfg.rec_en = 1;
+ REG_WR_SSER(rw_cfg, cfg);
+ REG_WR_SSER(rw_tr_cfg, tr_cfg);
+ REG_WR_SSER(rw_rec_cfg, rec_cfg);
+ REG_WR_SSER(rw_intr_mask, mask);
+
+ /*
+ * See 23.7.5.2 (Atmel fast flash) in the hardware documentation.
+ * Step 1.
+ */
+ cfg.gate_clk = regk_sser_no;
+
+ /* Step 2. */
+ cfg.out_clk_pol = regk_sser_pos;
+
+ /* Step 3. */
+ cfg.out_clk_src = regk_sser_intern_clk;
+
+ /* Step 4. */
+ tr_cfg.sample_size = 1;
+ rec_cfg.sample_size = 1;
+
+ /* Step 5. */
+ frm_cfg.wordrate = 7;
+
+ /* Step 6. */
+ tr_cfg.clk_src = regk_sser_intern;
+ rec_cfg.clk_src = regk_sser_intern;
+ frm_cfg.clk_src = regk_sser_intern;
+ tr_cfg.clk_pol = regk_sser_neg;
+ frm_cfg.clk_pol = regk_sser_neg;
+
+ /* Step 7. */
+ rec_cfg.clk_pol = regk_sser_pos;
+
+ /* Step 8. */
+ frm_cfg.tr_delay = 1;
+
+ /* Step 9. */
+ frm_cfg.rec_delay = 1;
+
+ /* Step 10. */
+ tr_cfg.sh_dir = regk_sser_msbfirst;
+ rec_cfg.sh_dir = regk_sser_msbfirst;
+
+ /* Step 11. */
+ tr_cfg.frm_src = regk_sser_intern;
+ rec_cfg.frm_src = regk_sser_intern;
+
+ /* Step 12. */
+ tr_cfg.rate_ctrl = regk_sser_iso;
+
+ /*
+ * Step 13. Note that 0 != tx_null, so we're good regarding
+ * the descriptor .md field.
+ */
+ tr_cfg.eop_stop = 1;
+
+ /* Step 14. */
+ frm_cfg.frame_pin_use = regk_sser_gio1;
+ frm_cfg.frame_pin_dir = regk_sser_out;
+
+ /* Step 15. */
+ extra.clkon_en = 1;
+ extra.clkoff_en = 1;
+
+ /* Step 16. We'll modify this value for each "burst". */
+ extra.clkoff_cycles = 7;
+
+ /* Step 17. */
+ cfg.prepare = 1;
+
+ /*
+ * Things left out from the documented startup procedure.
+ * It's uncertain whether all of these are needed.
+ */
+ frm_cfg.status_pin_dir = regk_sser_in;
+ tr_cfg.mode = regk_sser_hispeed;
+ rec_cfg.mode = regk_sser_hispeed;
+ frm_cfg.out_on = regk_sser_intern_tb;
+ frm_cfg.out_off = regk_sser_rec;
+ frm_cfg.type = regk_sser_level;
+ tr_cfg.use_dma = 1;
+ tr_cfg.urun_stop = 1;
+ rec_cfg.orun_stop = 1;
+ rec_cfg.use_dma = 1;
+ rec_cfg.fifo_thr = regk_sser_inf;
+ frm_cfg.early_wend = regk_sser_yes;
+ cfg.clk_dir = regk_sser_out;
+
+ tr_cfg.data_pin_use = regk_sser_dout;
+ cfg.base_freq = regk_sser_f100;
+
+ REG_WR_SSER(rw_frm_cfg, frm_cfg);
+ REG_WR_SSER(rw_tr_cfg, tr_cfg);
+ REG_WR_SSER(rw_rec_cfg, rec_cfg);
+ REG_WR_SSER(rw_extra, extra);
+ REG_WR_SSER(rw_cfg, cfg);
+ hw->frm_cfg = frm_cfg;
+ hw->tr_cfg = tr_cfg;
+ hw->rec_cfg = rec_cfg;
+ hw->extra = extra;
+ hw->cfg = cfg;
+
+ crisv32_spi_sser_set_speed_Hz(hw, hw->max_speed_Hz);
+
+ ret = request_irq(hw->sser.irq, sser_interrupt, 0, "sser", hw);
+ if (ret != 0)
+ goto noirq;
+
+ ret = request_irq(hw->dmain.irq, rec_dma_interrupt, 0, "sser rec", hw);
+ if (ret != 0)
+ goto free_outirq;
+
+ crisv32_reset_dma_hw(hw->dmain.regi);
+ crisv32_reset_dma_hw(hw->dmaout.regi);
+ return 0;
+
+ free_outirq:
+ free_irq(hw->sser.irq, hw);
+ noirq:
+ return ret;
+}
+
+/* SPI-master setup function for non-DMA. */
+
+static int crisv32_spi_sser_regs_master_setup(struct spi_device *spi)
+{
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master);
+ int ret = 0;
+
+ /* Just do a little initial constraining checks. */
+ if (spi->bits_per_word == 0)
+ spi->bits_per_word = 8;
+
+ if (spi->bits_per_word != 8)
+ return -EINVAL;
+
+ bitbang->chipselect = (spi->mode & SPI_CS_HIGH) != 0
+ ? crisv32_spi_sser_chip_select_active_high
+ : crisv32_spi_sser_chip_select_active_low;
+
+ if (hw->max_speed_Hz == 0) {
+ u32 max_speed_Hz;
+
+ /*
+ * At this time; at the first call to the SPI master
+ * setup function, spi->max_speed_hz reflects the
+ * board-init value. It will be changed later on by
+ * the protocol master, but at the master setup call
+ * is the only time we actually get to see the hw max
+ * and thus a reasonable time to init the hw field.
+ */
+
+ /* The module parameter overrides everything. */
+ if (crisv32_spi_speed_limit_Hz != 0)
+ max_speed_Hz = crisv32_spi_speed_limit_Hz;
+ /*
+ * I never could get hispeed mode to work for non-DMA.
+ * We adjust the max speed here (where we could
+ * presumably fix it), not in the board info file.
+ */
+ else if (spi->max_speed_hz > 16667000)
+ max_speed_Hz = 16667000;
+ else
+ max_speed_Hz = spi->max_speed_hz;
+
+ hw->max_speed_Hz = max_speed_Hz;
+ spi->max_speed_hz = max_speed_Hz;
+
+ /*
+ * We also do one-time initialization of the hardware at this
+ * point. We could defer to the return to the probe-function
+ * from spi_bitbang_start, but other hardware setup (like
+ * subsequent calls to this function before that) would have
+ * to be deferred until then too.
+ */
+ ret = crisv32_setup_spi_sser_for_reg_access(hw);
+ if (ret != 0)
+ return ret;
+
+ ret = spi_bitbang_setup(spi);
+ if (ret != 0)
+ return ret;
+
+ dev_info(&spi->dev,
+ "CRIS v32 SPI driver for sser%d\n",
+ spi->master->bus_num);
+ }
+
+ return 0;
+}
+
+/*
+ * SPI-master setup_transfer-function used for both DMA and non-DMA
+ * (single function for DMA, together with spi_bitbang_setup_transfer
+ * for non-DMA).
+ */
+
+static int crisv32_spi_sser_common_setup_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ u8 bits_per_word;
+ u32 hz;
+ int ret = 0;
+
+ if (t) {
+ bits_per_word = t->bits_per_word;
+ hz = t->speed_hz;
+ } else {
+ bits_per_word = 0;
+ hz = 0;
+ }
+
+ if (bits_per_word == 0)
+ bits_per_word = spi->bits_per_word;
+
+ if (bits_per_word != 8)
+ return -EINVAL;
+
+ if (hz == 0)
+ hz = spi->max_speed_hz;
+
+ if (hz != hw->effective_speed_kHz*1000 && hz != 0)
+ ret = crisv32_spi_sser_set_speed_Hz(hw, hz);
+
+ return ret;
+}
+
+/* Helper for a SPI-master setup_transfer function for non-DMA. */
+
+static int crisv32_spi_sser_regs_setup_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ int ret = crisv32_spi_sser_common_setup_transfer(spi, t);
+
+ if (ret != 0)
+ return ret;
+
+ /* Set up the loop-over-buffer parts. */
+ return spi_bitbang_setup_transfer (spi, t);
+}
+
+/* SPI-master setup function for DMA. */
+
+static int crisv32_spi_sser_dma_master_setup(struct spi_device *spi)
+{
+ /*
+ * As we don't dispatch to the spi_bitbang default function,
+ * we need to do whatever tests it does; keep it in sync. On
+ * the bright side, we can use the spi->controller_state slot;
+ * we use it for DMA:able memory for the descriptors and
+ * temporary buffers to copy non-DMA:able transfers.
+ */
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master);
+ struct crisv32_spi_dma_cs *cs;
+ u32 dmasize;
+ int ret = 0;
+
+ if (hw->max_speed_Hz == 0) {
+ struct crisv32_spi_dma_descrs *descrp;
+ u32 descrp_dma;
+ u32 max_speed_Hz;
+
+ /* The module parameter overrides everything. */
+ if (crisv32_spi_speed_limit_Hz != 0)
+ max_speed_Hz = crisv32_spi_speed_limit_Hz;
+ /*
+ * See comment at corresponding statement in
+ * crisv32_spi_sser_regs_master_setup.
+ */
+ else
+ max_speed_Hz = spi->max_speed_hz;
+
+ hw->max_speed_Hz = max_speed_Hz;
+ spi->max_speed_hz = max_speed_Hz;
+
+ ret = crisv32_setup_spi_sser_for_dma_access(hw);
+ if (ret != 0)
+ return ret;
+
+ /* Allocate some extra for necessary alignment. */
+ dmasize = sizeof *cs + 31
+ + sizeof(struct crisv32_spi_dma_descrs);
+
+ cs = kzalloc(dmasize, GFP_KERNEL | GFP_DMA);
+ if (cs == NULL)
+ return -ENOMEM;
+
+ /*
+ * Make descriptors aligned within the allocated area,
+ * some-place after cs.
+ */
+ descrp = (struct crisv32_spi_dma_descrs *)
+ (((u32) (cs + 1) + 31) & ~31);
+ descrp_dma = virt_to_phys(descrp);
+
+ /* Set up the "constant" parts of the descriptors. */
+ descrp->out_descr.eol = 1;
+ descrp->out_descr.intr = 1;
+ descrp->out_descr.out_eop = 1;
+ descrp->out_ctxt.saved_data = (dma_descr_data *)
+ (descrp_dma
+ + offsetof(struct crisv32_spi_dma_descrs, out_descr));
+ descrp->out_ctxt.next = 0;
+
+ descrp->in_descr.eol = 1;
+ descrp->in_descr.intr = 1;
+ descrp->in_ctxt.saved_data = (dma_descr_data *)
+ (descrp_dma
+ + offsetof(struct crisv32_spi_dma_descrs, in_descr));
+ descrp->in_ctxt.next = 0;
+
+ cs->descrp = descrp;
+ spi->controller_state = cs;
+
+ init_completion(&hw->dma_done);
+
+ dev_info(&spi->dev,
+ "CRIS v32 SPI driver for sser%d/DMA\n",
+ spi->master->bus_num);
+ }
+
+ /* Do our extra constraining checks. */
+ if (spi->bits_per_word == 0)
+ spi->bits_per_word = 8;
+
+ if (spi->bits_per_word != 8)
+ return -EINVAL;
+
+ /* SPI_LSB_FIRST deliberately left out, and we only support mode 3. */
+ if ((spi->mode & ~(SPI_TX_1|SPI_CS_HIGH)) != SPI_MODE_3)
+ return -EINVAL;
+
+ bitbang->chipselect = (spi->mode & SPI_CS_HIGH) != 0
+ ? crisv32_spi_sser_chip_select_active_high
+ : crisv32_spi_sser_chip_select_active_low;
+
+ ret = bitbang->setup_transfer(spi, NULL);
+ if (ret != 0)
+ return ret;
+
+ /* Remember to de-assert chip-select before the first transfer. */
+ spin_lock(&bitbang->lock);
+ if (!bitbang->busy) {
+ bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
+ ndelay(hw->half_cycle_delay_ns);
+ }
+ spin_unlock(&bitbang->lock);
+
+ return 0;
+}
+
+/* SPI-master cleanup function for DMA. */
+
+static void crisv32_spi_sser_dma_cleanup(struct spi_device *spi)
+{
+ kfree(spi->controller_state);
+ spi->controller_state = NULL;
+}
+
+/*
+ * Set up DMA transmitter descriptors for a chunk of data.
+ * The caller is responsible for working around TR 106.
+ */
+static void crisv32_spi_sser_setup_dma_descr_out(u32 regi,
+ struct crisv32_spi_dma_cs *cs,
+ u32 out_phys, u32 chunk_len)
+{
+ BUG_ON(chunk_len > DMA_CHUNKSIZ);
+ struct crisv32_spi_dma_descrs *descrp = cs->descrp;
+ u32 descrp_dma = virt_to_phys(descrp);
+
+ descrp->out_descr.buf = (u8 *) out_phys;
+ descrp->out_descr.after = (u8 *) out_phys + chunk_len;
+ descrp->out_ctxt.saved_data_buf = (u8 *) out_phys;
+
+ DMA_START_CONTEXT(regi,
+ descrp_dma
+ + offsetof(struct crisv32_spi_dma_descrs, out_ctxt));
+}
+
+/*
+ * Set up DMA receiver descriptors for a chunk of data.
+ * Also, work around TR 106.
+ */
+static void crisv32_spi_sser_setup_dma_descr_in(u32 regi_dmain,
+ struct crisv32_spi_dma_cs *cs,
+ u32 in_phys, u32 chunk_len)
+{
+ BUG_ON(chunk_len > DMA_CHUNKSIZ);
+ struct crisv32_spi_dma_descrs *descrp = cs->descrp;
+ u32 descrp_dma = virt_to_phys(descrp);
+
+ descrp->in_descr.buf = (u8 *) in_phys;
+ descrp->in_descr.after = (u8 *) in_phys + chunk_len;
+ descrp->in_ctxt.saved_data_buf = (u8 *) in_phys;
+
+ flush_dma_descr(&descrp->in_descr, 1);
+
+ DMA_START_CONTEXT(regi_dmain,
+ descrp_dma
+ + offsetof(struct crisv32_spi_dma_descrs, in_ctxt));
+}
+
+/*
+ * SPI-bitbang txrx_bufs function for DMA.
+ * FIXME: We have SG DMA descriptors; use them.
+ * (Requires abandoning the spi_bitbang framework if done reasonably.)
+ */
+static int crisv32_spi_sser_dma_txrx_bufs(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct crisv32_spi_dma_cs *cs = spi->controller_state;
+ struct crisv32_spi_hw_info *hw = spidev_to_hw(spi);
+ u32 len = t->len;
+ reg_sser_rw_cfg cfg = hw->cfg;
+ reg_sser_rw_tr_cfg tr_cfg = hw->tr_cfg;
+ reg_sser_rw_rec_cfg rec_cfg = hw->rec_cfg;
+ reg_sser_rw_extra extra = hw->extra;
+ u32 regi_sser = hw->sser.regi;
+ u32 dmain = 0;
+ u32 dmaout = 0;
+ u32 regi_dmain = hw->dmain.regi;
+ u8 *rx_buf = t->rx_buf;
+
+ /*
+ * Using IRQ+completion is measured to give an overhead of 14
+ * us, so let's instead busy-wait for the time that would be
+ * wasted anyway, and get back sooner. We're not counting in
+ * other overhead such as the DMA descriptor in the
+ * time-expression, which causes us to use busy-wait for
+ * data-lengths that actually take a bit longer than
+ * IRQ_USAGE_THRESHOLD_NS. Still, with IRQ_USAGE_THRESHOLD_NS
+ * = 14000, the threshold is for 20 MHz => 35 bytes, 25 => 44
+ * and 50 => 88 and the typical SPI transfer lengths for
+ * SDcard are { 1, 2, 7, 512 } bytes so a more complicated
+ * would likely give nothing but worse performance due to
+ * complexity.
+ */
+ int use_irq = len * hw->half_cycle_delay_ns
+ > IRQ_USAGE_THRESHOLD_NS / 8 / 2;
+
+ if (len > DMA_CHUNKSIZ) {
+ /*
+ * It should be quite easy to adjust the code if the need
+ * arises for something much larger than the preallocated
+ * buffers (which could themselves easily just be increased)
+ * but still what fits in extra.clkoff_cycles: kmalloc a
+ * temporary dmaable buffer in this function and free it at
+ * the end. No need to optimize rare requests. Until then,
+ * we'll keep the code as simple as performance allows.
+ * Alternatively or if we need to send even larger data,
+ * consider calling self with the required number of "faked"
+ * shorter transfers here.
+ */
+ dev_err(&spi->dev,
+ "Trying to transfer %d > max %d bytes:"
+ " need to adjust the SPI driver\n",
+ len, DMA_CHUNKSIZ);
+ return -EMSGSIZE;
+ }
+
+ /*
+ * Need to separately tell the hispeed machinery the number of
+ * bits in this transmission.
+ */
+ extra.clkoff_cycles = len * 8 - 1;
+
+ if (t->tx_buf != NULL) {
+ if (t->tx_dma == 0) {
+ memcpy(cs->tx_buf, t->tx_buf, len);
+ dmaout = virt_to_phys(cs->tx_buf);
+ } else
+ dmaout = t->tx_dma;
+
+ crisv32_spi_sser_setup_dma_descr_out(hw->dmaout.regi,
+ cs, dmaout,
+ len);
+
+ /* No need to do anything for TR 106; this DMA only reads. */
+ tr_cfg.tr_en = 1;
+ tr_cfg.data_pin_use = regk_sser_dout;
+ } else {
+ tr_cfg.data_pin_use = (spi->mode & SPI_TX_1)
+ ? regk_sser_gio1 : regk_sser_gio0;
+ tr_cfg.tr_en = 0;
+ }
+
+ if (rx_buf != 0) {
+ if (t->rx_dma == 0)
+ dmain = virt_to_phys(cs->rx_buf);
+ else
+ dmain = t->rx_dma;
+
+ crisv32_spi_sser_setup_dma_descr_in(regi_dmain, cs,
+ dmain, len);
+ rec_cfg.rec_en = 1;
+
+ REG_WRINT_SSER(rw_ack_intr, -1);
+ REG_WRINT_DI(rw_ack_intr, -1);
+
+ /*
+ * If we're receiving, use the rec data interrupt from DMA as
+ * a signal that the HW is done.
+ */
+ if (use_irq) {
+ reg_sser_rw_intr_mask mask = { .urun = 1 };
+ reg_dma_rw_intr_mask dmask = { .data = 1 };
+
+ REG_WR_DI(rw_intr_mask, dmask);
+
+ /*
+ * Catch transmitter underruns too. We don't
+ * have to conditionalize that on the
+ * transmitter being enabled; it's off when
+ * the transmitter is off. Any overruns will
+ * be indicated by a timeout, so we don't have
+ * to check for that specifically.
+ */
+ REG_WR_SSER(rw_intr_mask, mask);
+ }
+ } else {
+ rec_cfg.rec_en = 0;
+
+ /*
+ * Ack previous overrun, underrun and tidle interrupts. Or
+ * why not all. We'll get orun and urun "normally" due to the
+ * way hispeed is (documented to) work and need to clear them,
+ * and we'll have a tidle from a previous transmit if we used
+ * to both receive and transmit, but now only transmit.
+ */
+ REG_WRINT_SSER(rw_ack_intr, -1);
+
+ if (use_irq) {
+ reg_sser_rw_intr_mask mask = { .urun = 1, .tidle = 1 };
+ REG_WR_SSER(rw_intr_mask, mask);
+ }
+ }
+
+ REG_WR_SSER(rw_rec_cfg, rec_cfg);
+ REG_WR_SSER(rw_tr_cfg, tr_cfg);
+ REG_WR_SSER(rw_extra, extra);
+
+ /*
+ * Barriers are needed to make sure that the completion inits don't
+ * migrate past the register writes due to gcc scheduling.
+ */
+ mb();
+ hw->dma_actually_done = 0;
+ INIT_COMPLETION(hw->dma_done);
+ mb();
+
+ /*
+ * Wait until DMA tx FIFO has more than one byte (it reads one
+ * directly then one "very quickly") before starting sser tx.
+ */
+ if (tr_cfg.tr_en) {
+ u32 regi_dmaout = hw->dmaout.regi;
+ u32 minlen = len > 2 ? 2 : len;
+ while ((REG_RD_DO(rw_stat)).buf < minlen)
+ ;
+ }
+
+ /* Wait until DMA-in is finished reading the descriptors. */
+ if (rec_cfg.rec_en)
+ while (DMA_BUSY(regi_dmain))
+ ;
+ /*
+ * Wait 3 cycles before enabling (with .prepare = 1).
+ * FIXME: Can we cut this by some time already passed?
+ */
+ ndelay(3 * 2 * hw->half_cycle_delay_ns);
+ cfg.en = 1;
+ REG_WR_SSER(rw_cfg, cfg);
+
+ /*
+ * Wait 3 more cycles plus 30 ns before letting go.
+ * FIXME: Can we do something else before but after the
+ * previous cfg write and cut this by the time already passed?
+ */
+ cfg.prepare = 0;
+ hw->cfg = cfg;
+ ndelay(3 * 2 * hw->half_cycle_delay_ns + 30);
+
+ REG_WR_SSER(rw_cfg, cfg);
+
+ /*, We'll disable sser next the time we change the configuration. */
+ cfg.en = 0;
+ cfg.prepare = 1;
+ hw->cfg = cfg;
+
+ if (!use_irq) {
+ /*
+ * We use a timeout corresponding to one iteration per ns,
+ * which of course is at least five * insns / loop times as
+ * much as reality, but we'll avoid a need for reading hw
+ * timers directly.
+ */
+ u32 countdown = IRQ_USAGE_THRESHOLD_NS;
+
+ do
+ if (rec_cfg.rec_en == 0) {
+ /* Using the transmitter only. */
+ reg_sser_r_intr intr = REG_RD_SSER(r_intr);
+
+ if (intr.tidle != 0) {
+ /*
+ * Almost done... Just check if we
+ * had a transmitter underrun too.
+ */
+ if (!intr.urun)
+ goto transmission_done;
+
+ /*
+ * Fall over to the "time is up" case;
+ * no need to provide a special path
+ * for the error case.
+ */
+ countdown = 1;
+ }
+ } else {
+ /* Using at least the receiver. */
+ if ((REG_RD_DI(r_intr)).data != 0) {
+ if ((REG_RD_SSER(r_intr)).urun == 0)
+ goto transmission_done;
+ countdown = 1;
+ }
+ }
+ while (--countdown != 0);
+
+ /*
+ * The time is up. Something might be wrong, or perhaps we've
+ * started using data lengths where the threshold was about a
+ * magnitude wrong. Fall over to IRQ. Remember not to ack
+ * interrupts here (but always above, before starting), else
+ * we'll have a race condition with the interrupt.
+ */
+ if (!rec_cfg.rec_en) {
+ reg_sser_rw_intr_mask mask = { .urun = 1, .tidle = 1 };
+ REG_WR_SSER(rw_intr_mask, mask);
+ } else {
+ reg_dma_rw_intr_mask dmask = { .data = 1 };
+ reg_sser_rw_intr_mask mask = { .urun = 1 };
+
+ /*
+ * Never mind checking for tr being disabled; urun
+ * won't happen then.
+ */
+ REG_WR_SSER(rw_intr_mask, mask);
+ REG_WR_DI(rw_intr_mask, dmask);
+ }
+ }
+
+ if (!wait_for_completion_timeout(&hw->dma_done, hw->dma_timeout)
+ /*
+ * Have to keep track manually too, else we'll get a timeout
+ * indication for being scheduled out too long, while the
+ * completion will still have trigged.
+ */
+ && !hw->dma_actually_done) {
+ u32 regi_dmaout = hw->dmaout.regi;
+
+ /*
+ * Transfer timed out. Should not happen for a
+ * working controller, except perhaps if the system is
+ * badly conditioned, causing DMA memory bandwidth
+ * starvation. Not much to do afterwards, but perhaps
+ * reset DMA and sser and hope it works the next time.
+ */
+ REG_WRINT_SSER(rw_cfg, 0);
+ REG_WR_SSER(rw_cfg, cfg);
+ REG_WRINT_SSER(rw_intr_mask, 0);
+ REG_WRINT_DI(rw_intr_mask, 0);
+ REG_WRINT_SSER(rw_ack_intr, -1);
+ crisv32_reset_dma_hw(hw->dmain.regi);
+ crisv32_reset_dma_hw(hw->dmaout.regi);
+
+ dev_err(&spi->dev, "timeout %u bytes %u kHz\n",
+ len, hw->effective_speed_kHz);
+ dev_err(&spi->dev, "sser=(%x,%x,%x,%x,%x)\n",
+ REG_RDINT_SSER(rw_cfg), REG_RDINT_SSER(rw_tr_cfg),
+ REG_RDINT_SSER(rw_rec_cfg), REG_RDINT_SSER(rw_extra),
+ REG_RDINT_SSER(r_intr));
+ dev_err(&spi->dev, "tx=(%x,%x,%x,%x)\n",
+ dmaout, REG_RDINT_DO(rw_stat), REG_RDINT_DO(rw_data),
+ REG_RDINT_DO(r_intr));
+ dev_err(&spi->dev, "rx=(%x,%x,%x,%x)\n",
+ dmain, REG_RDINT_DI(rw_stat), REG_RDINT_DI(rw_data),
+ REG_RDINT_DI(r_intr));
+ return -EIO;
+ }
+
+ transmission_done:
+ /* Wait for the last half-cycle of the last cycle. */
+ crisv32_spi_sser_wait_halfabit(hw);
+
+ /* Reset for another call. */
+ REG_WR_SSER(rw_cfg, cfg);
+
+ /*
+ * If we had to use the temp DMAable rec buffer, copy it to the right
+ * position.
+ */
+ if (t->rx_buf != 0 && t->rx_dma == 0)
+ memcpy (t->rx_buf, cs->rx_buf, len);
+
+ /*
+ * All clear. The interrupt function disabled the interrupt, we don't
+ * have to do more.
+ */
+ return len;
+}
+
+/* Platform-device probe function. */
+
+static int __devinit crisv32_spi_sser_probe(struct platform_device *dev)
+{
+ struct spi_master *master;
+ struct crisv32_spi_sser_devdata *dd;
+ struct crisv32_spi_hw_info *hw;
+ struct resource *res;
+ struct crisv32_spi_sser_controller_data *gc;
+ int ret;
+
+ /*
+ * We need to get the controller data as a hardware resource,
+ * or else it wouldn't be available until *after* the
+ * spi_bitbang_start call!
+ */
+ res = platform_get_resource_byname(dev, 0, "controller_data_ptr");
+ if (res == NULL) {
+ dev_err(&dev->dev,
+ "can't get controller_data resource at probe\n");
+ return -EIO;
+ }
+
+ gc = (struct crisv32_spi_sser_controller_data *) res->start;
+
+ master = spi_alloc_master(&dev->dev, sizeof *dd);
+ if (master == NULL) {
+ dev_err(&dev->dev, "failed to allocate spi master\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ dd = spi_master_get_devdata(master);
+ platform_set_drvdata(dev, dd);
+
+ /*
+ * The device data asks for this driver, and holds the id
+ * number, which must be unique among the same-type devices.
+ * We use this as the number of this SPI bus.
+ */
+ master->bus_num = dev->id;
+
+ /* Setup SPI bitbang adapter hooks. */
+ dd->bitbang.master = spi_master_get(master);
+ dd->bitbang.chipselect = crisv32_spi_sser_chip_select_active_low;
+
+ hw = &dd->hw;
+ hw->gc = gc;
+
+ /* Pre-spi_bitbang_start setup. */
+ if (gc->using_dma) {
+ /* Setup DMA and interrupts. */
+ ret = gc->iface_allocate(&hw->sser, &hw->dmain, &hw->dmaout);
+ if (ret != 0)
+ goto err_no_regs;
+
+ dd->bitbang.master->setup = crisv32_spi_sser_dma_master_setup;
+ dd->bitbang.setup_transfer
+ = crisv32_spi_sser_common_setup_transfer;
+ dd->bitbang.txrx_bufs = crisv32_spi_sser_dma_txrx_bufs;
+ dd->bitbang.master->cleanup = crisv32_spi_sser_dma_cleanup;
+ } else {
+ /* Just registers, then. */
+ ret = gc->iface_allocate(&hw->sser, NULL, NULL);
+ if (ret != 0)
+ goto err_no_regs;
+
+ dd->bitbang.master->setup
+ = crisv32_spi_sser_regs_master_setup;
+ dd->bitbang.setup_transfer
+ = crisv32_spi_sser_regs_setup_transfer;
+ dd->bitbang.master->cleanup = spi_bitbang_cleanup;
+
+ /*
+ * We can do all modes pretty simply, but I have no
+ * simple enough way to test them, so I won't.
+ */
+ dd->bitbang.txrx_word[SPI_MODE_3]
+ = crisv32_spi_sser_txrx_mode3;
+ }
+
+ ret = spi_bitbang_start(&dd->bitbang);
+ if (ret)
+ goto err_no_bitbang;
+
+ /*
+ * We don't have a dev_info here, as initialization that may fail is
+ * postponed to the first master->setup call. It's called from
+ * spi_bitbang_start (above), where the call-chain doesn't look too
+ * close at error return values; we'll get here successfully anyway,
+ * so emitting a separate message here is at most confusing.
+ */
+ dev_dbg(&dev->dev,
+ "CRIS v32 SPI driver for sser%d%s present\n",
+ master->bus_num,
+ gc->using_dma ? "/DMA" : "");
+
+ return 0;
+
+ err_no_bitbang:
+ gc->iface_free();
+
+ err_no_regs:
+ platform_set_drvdata(dev, NULL);
+ spi_master_put(dd->bitbang.master);
+
+ err:
+ return ret;
+}
+
+/* Platform-device remove-function. */
+
+static int __devexit crisv32_spi_sser_remove(struct platform_device *dev)
+{
+ struct crisv32_spi_sser_devdata *dd = platform_get_drvdata(dev);
+ struct crisv32_spi_hw_info *hw = &dd->hw;
+ struct crisv32_spi_sser_controller_data *gc = hw->gc;
+ int ret;
+
+ /* We need to stop all bitbanging activity separately. */
+ ret = spi_bitbang_stop(&dd->bitbang);
+ if (ret != 0)
+ return ret;
+
+ spi_master_put(dd->bitbang.master);
+
+ /*
+ * If we get here, the queue is empty and there's no activity;
+ * it's safe to flip the switch on the interfaces.
+ */
+ if (gc->using_dma) {
+ u32 regi_dmain = hw->dmain.regi;
+ u32 regi_dmaout = hw->dmaout.regi;
+ u32 regi_sser = hw->sser.regi;
+
+ REG_WRINT_SSER(rw_intr_mask, 0);
+ REG_WRINT_DI(rw_intr_mask, 0);
+ REG_WRINT_DO(rw_intr_mask, 0);
+ hw->cfg.en = 0;
+ REG_WR_SSER(rw_cfg, hw->cfg);
+ DMA_RESET(regi_dmain);
+ DMA_RESET(regi_dmaout);
+ free_irq(hw->sser.irq, hw);
+ free_irq(hw->dmain.irq, hw);
+ }
+
+ gc->iface_free();
+
+ platform_set_drvdata(dev, NULL);
+ return 0;
+}
+
+/*
+ * For the time being, there's no suspend/resume support to care
+ * about, so those handlers default to NULL.
+ */
+static struct platform_driver crisv32_spi_sser_drv = {
+ .probe = crisv32_spi_sser_probe,
+ .remove = __devexit_p(crisv32_spi_sser_remove),
+ .driver = {
+ .name = "spi_crisv32_sser",
+ .owner = THIS_MODULE,
+ },
+};
+
+/* Module init function. */
+
+static int __devinit crisv32_spi_sser_init(void)
+{
+ return platform_driver_register(&crisv32_spi_sser_drv);
+}
+
+/* Module exit function. */
+
+static void __devexit crisv32_spi_sser_exit(void)
+{
+ platform_driver_unregister(&crisv32_spi_sser_drv);
+}
+
+/* Setter function for speed limit. */
+
+static int crisv32_spi_speed_limit_Hz_setter(const char *val,
+ struct kernel_param *kp)
+{
+ char *endp;
+ ulong num = simple_strtoul(val, &endp, 0);
+ if (endp == val
+ || *endp != 0
+ || num <= 0
+ /*
+ * We can't go above 100 MHz speed. Actually we can't go
+ * above 50 MHz using the sser support but it might make
+ * sense trying.
+ */
+ || num > 100000000)
+ return -EINVAL;
+ *(ulong *) kp->arg = num;
+ return 0;
+}
+
+module_param_call(crisv32_spi_max_speed_hz,
+ crisv32_spi_speed_limit_Hz_setter, param_get_ulong,
+ &crisv32_spi_speed_limit_Hz, 0644);
+
+module_init(crisv32_spi_sser_init);
+module_exit(crisv32_spi_sser_exit);
+
+MODULE_DESCRIPTION("CRIS v32 SPI-SSER Driver");
+MODULE_AUTHOR("Hans-Peter Nilsson, <hp@axis.com>");
+MODULE_LICENSE("GPL");
--- /dev/null
+
+/* macros for debug output */
+
+#define hcd_dbg(hcd, fmt, args...) \
+ dev_info(hcd->self.controller, fmt, ## args)
+#define hcd_err(hcd, fmt, args...) \
+ dev_err(hcd->self.controller, fmt, ## args)
+#define hcd_info(hcd, fmt, args...) \
+ dev_info(hcd->self.controller, fmt, ## args)
+#define hcd_warn(hcd, fmt, args...) \
+ dev_warn(hcd->self.controller, fmt, ## args)
+
+/*
+#define devdrv_dbg(fmt, args...) \
+ printk(KERN_INFO "usb_devdrv dbg: ");printk(fmt, ## args)
+*/
+#define devdrv_dbg(fmt, args...) {}
+
+#define devdrv_err(fmt, args...) \
+ printk(KERN_ERR "usb_devdrv error: ");printk(fmt, ## args)
+#define devdrv_info(fmt, args...) \
+ printk(KERN_INFO "usb_devdrv: ");printk(fmt, ## args)
+
+#define irq_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_irq dbg: ");printk(fmt, ## args)
+#define irq_err(fmt, args...) \
+ printk(KERN_ERR "crisv10_irq error: ");printk(fmt, ## args)
+#define irq_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_irq warn: ");printk(fmt, ## args)
+#define irq_info(fmt, args...) \
+ printk(KERN_INFO "crisv10_hcd: ");printk(fmt, ## args)
+
+/*
+#define rh_dbg(fmt, args...) \
+ printk(KERN_DEBUG "crisv10_rh dbg: ");printk(fmt, ## args)
+*/
+#define rh_dbg(fmt, args...) {}
+
+#define rh_err(fmt, args...) \
+ printk(KERN_ERR "crisv10_rh error: ");printk(fmt, ## args)
+#define rh_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_rh warning: ");printk(fmt, ## args)
+#define rh_info(fmt, args...) \
+ printk(KERN_INFO "crisv10_rh: ");printk(fmt, ## args)
+
+/*
+#define tc_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_tc dbg: ");printk(fmt, ## args)
+*/
+#define tc_dbg(fmt, args...) {while(0){}}
+
+#define tc_err(fmt, args...) \
+ printk(KERN_ERR "crisv10_tc error: ");printk(fmt, ## args)
+/*
+#define tc_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_tc warning: ");printk(fmt, ## args)
+*/
+#define tc_warn(fmt, args...) {while(0){}}
+
+#define tc_info(fmt, args...) \
+ printk(KERN_INFO "crisv10_tc: ");printk(fmt, ## args)
+
+
+/* Debug print-outs for various traffic types */
+
+#define intr_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_intr warning: ");printk(fmt, ## args)
+/*
+#define intr_dbg(fmt, args...) \
+ printk(KERN_DEBUG "crisv10_intr dbg: ");printk(fmt, ## args)
+*/
+#define intr_dbg(fmt, args...) {while(0){}}
+
+
+#define isoc_err(fmt, args...) \
+ printk(KERN_ERR "crisv10_isoc error: ");printk(fmt, ## args)
+/*
+#define isoc_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_isoc warning: ");printk(fmt, ## args)
+*/
+#define isoc_warn(fmt, args...) {while(0){}}
+
+/*
+#define isoc_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_isoc dbg: ");printk(fmt, ## args)
+*/
+#define isoc_dbg(fmt, args...) {while(0){}}
+
+/*
+#define timer_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_timer warning: ");printk(fmt, ## args)
+*/
+#define timer_warn(fmt, args...) {while(0){}}
+
+/*
+#define timer_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_timer dbg: ");printk(fmt, ## args)
+*/
+#define timer_dbg(fmt, args...) {while(0){}}
+
+
+/* Debug printouts for events related to late finishing of URBs */
+/*
+#define late_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_late dbg: ");printk(fmt, ## args)
+*/
+#define late_dbg(fmt, args...) {while(0){}}
+
+#define late_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_late warning: ");printk(fmt, ## args)
+/*
+#define errno_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_errno dbg: ");printk(fmt, ## args)
+*/
+#define errno_dbg(fmt, args...) {while(0){}}
+
+
+#define dma_dbg(fmt, args...) \
+ printk(KERN_INFO "crisv10_dma dbg: ");printk(fmt, ## args)
+#define dma_err(fmt, args...) \
+ printk(KERN_ERR "crisv10_dma error: ");printk(fmt, ## args)
+#define dma_warn(fmt, args...) \
+ printk(KERN_INFO "crisv10_dma warning: ");printk(fmt, ## args)
+#define dma_info(fmt, args...) \
+ printk(KERN_INFO "crisv10_dma: ");printk(fmt, ## args)
+
+
+
+#define str_dir(pipe) \
+ (usb_pipeout(pipe) ? "out" : "in")
+#define str_type(pipe) \
+ ({ \
+ char *s = "?"; \
+ switch (usb_pipetype(pipe)) { \
+ case PIPE_ISOCHRONOUS: s = "iso"; break; \
+ case PIPE_INTERRUPT: s = "intr"; break; \
+ case PIPE_CONTROL: s = "ctrl"; break; \
+ case PIPE_BULK: s = "bulk"; break; \
+ }; \
+ s; \
+ })
--- /dev/null
+#ifndef __MTD_MTDRAM_H__
+#define __MTD_MTDRAM_H__
+
+#ifdef __KERNEL__
+#include <linux/mtd/mtd.h>
+int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
+ unsigned long size, char *name);
+
+#endif /* __KERNEL__ */
+#endif /* __MTD_MTDRAM_H__ */
--- /dev/null
+config AXIS_FIMAGE
+ bool "Build fimage"
+ depends LINUX_2_6_ETRAX
+ default y
+
--- /dev/null
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+FOXBOARD:=custom MCM 416 816 832
+FOXBOARD_4MB:=MCM 416
+FOXBOARD_8MB:=custom 816 832
+
+define Image/BuildKernel
+ for f in $(FOXBOARD); do \
+ cp $(KDIR)/vmlinuz_$$$$f $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-zImage_$$$$f; \
+ done
+endef
+
+define Image/Prepare
+ for f in $(FOXBOARD); do \
+ cp $(LINUX_DIR)/arch/cris/boot/zImage_$$$$f $(KDIR)/vmlinuz_$$$$f; \
+ done
+ $(MAKE) -C ./e100boot/
+ $(MAKE) -C ./mkfimage/
+ $(INSTALL_BIN) ./boot_linux $(BIN_DIR)
+endef
+
+define Image/Build/generic
+ for f in $(2); do \
+ mkfimage $(KDIR)/vmlinuz_$$$$f $(KDIR)/vmlinuz_$$$$f.tmp ; \
+ cat $(KDIR)/vmlinuz_$$$$f.tmp $(KDIR)/root.$(1) > $(KDIR)/fimage.$(1)_$$$$f.tmp; \
+ dd if=$(KDIR)/fimage.$(1)_$$$$f.tmp of=$(KDIR)/fimage.$(1)_$$$$f bs=$(3) conv=sync; \
+ cp $(KDIR)/fimage.$(1)_$$$$f $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1)-fimage_$$$$f; \
+ done
+endef
+
+define Image/Build/jffs2-64k
+ $(call prepare_generic_jffs-64k,$(KDIR)/root.jff2-64k)
+ $(call Image/Build/generic,$(1),$(FOXBOARD_4MB),4194304)
+ $(call Image/Build/generic,$(1),$(FOXBOARD_8MB),8388608)
+endef
+
+define Image/Build/squashfs
+ $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
+ $(call Image/Build/generic,$(1),$(FOXBOARD_4MB),4194304)
+ $(call Image/Build/generic,$(1),$(FOXBOARD_8MB),8388608)
+endef
+
+define Image/Build
+ $(call Image/Build/$(1),$(1))
+endef
+
+$(eval $(call BuildImage))
--- /dev/null
+#!/usr/bin/perl -w
+
+#*****************************************************************************
+#!
+#! FILE NAME : boot_linux
+#!
+#! PARAMETERS : -b <bootimage> the name of the boot image to use
+#! -d <device> the interface to use, e.g., eth1
+#! (defaults is eth0)
+#! -f save it in flash memory at address 0x10000
+#! -F save it in flash memory at address 0
+#! -h show some help
+#! -i <image> name of the image to use (default is fimage)
+#! -o <offset> the offset in the flash where the flashing
+#! starts
+#! -O <offset> the offset in the image file where the
+#! flashing starts from
+#! -p print the resulting etrax100boot command
+#! instead of executing it
+#! -s <size> how much to flash (default is the size of
+#! the flash minus the offset specified using
+#! -o or -f)
+#! -S <size> the size of the flash
+#!
+#! All sizes and offsets above can be specified as decimal
+#! numbers, or as hexadecimal numbers by prefixing them with 0x.
+#! It is also possible to use the suffixes k and M to specify
+#! kilo (1024) or mega (1048576).
+#!
+#! DESCRIPTION: Extract the start of the image and any registers that should
+#! be set from the kimage or fimage file, and then boot it.
+#!
+#! FUNCTIONS : convert_size
+#! extract_hw_settings
+#! get_dword
+#! calculate_sdram_init
+#! sdram_command
+#! print_help
+#!
+#!----------------------------------------------------------------------------
+#! HISTORY
+#!
+#! $Log: boot_linux,v $
+#! Revision 1.16 2004/11/01 16:32:27 starvik
+#! Corrected help text to avoid confusion
+#!
+#! Revision 1.15 2003/01/29 11:48:57 pkj
+#! Calculate a flash size large enough for the given image if the
+#! -S option is not specified.
+#!
+#! Revision 1.14 2002/11/18 14:40:09 pkj
+#! Make use of the --loop option to etrax100boot when initialising
+#! SDRAM memories. This requires a lot fewer options to be passed
+#! to the boot loader.
+#!
+#! Revision 1.13 2002/08/15 16:29:02 pkj
+#! * The -S option now accepts the size in bytes (just like the -s option).
+#! For backwards compatibility it still assumes sizes of 16 and less to
+#! be specified in MB.
+#! * The suffixes k and M can now be used with all sizes and offsets to
+#! specify them in kilo or mega.
+#!
+#! Revision 1.12 2002/08/15 15:27:34 pkj
+#! Use $opts{'x'} instead of $opt_x.
+#!
+#! Revision 1.11 2002/07/04 17:06:39 pkj
+#! * No longer specifies a bootfile by default (not needed any longer).
+#! * Implemented option -b to specify a bootfile.
+#! * Removed references to option -l (it was never implemented).
+#!
+#! Revision 1.10 2002/06/04 11:50:23 starvik
+#! Check if mrs_data is specified in kernelconfig (necessary for MCM)
+#!
+#! Revision 1.9 2002/01/29 10:38:26 pkj
+#! Change illegal to invalid.
+#!
+#! Revision 1.8 2001/09/13 12:32:10 pkj
+#! * Added option -S to specify the size of the flash (in MB), as -s
+#! is used to specify how much to flash nowadays.
+#! * Made the default size of the flash depend on the size of the image
+#! file. If it is bigger than 0x200100 then the flash is assumed to
+#! be 4 MB, otherwise it is assumed to be 2 MB.
+#! * Added verification of various options.
+#!
+#! Revision 1.7 2001/09/13 10:25:11 pkj
+#! Minor clean-up.
+#!
+#! Revision 1.6 2001/06/29 10:05:16 pkj
+#! Corrected check for SDRAM.
+#!
+#! Revision 1.5 2001/06/29 09:11:55 pkj
+#! Synchronised boot_elinux and boot_linux.
+#!
+#!----------------------------------------------------------------------------
+#! (C) Copyright 2001, Axis Communications AB, LUND, SWEDEN
+#!****************************************************************************
+# $Id: boot_linux,v 1.16 2004/11/01 16:32:27 starvik Exp $
+
+#****************** INCLUDE FILES SECTION ************************************
+
+use strict;
+
+use Getopt::Std;
+use File::Basename;
+
+#****************** VARIABLE DECLARATION SECTION *****************************
+
+use vars qw($my_name %opts);
+use vars qw($text_start $cmd);
+use vars qw($image_name $image_size);
+use vars qw($offset $source_offset $flash_size $flashing_size);
+use vars qw($sdram_timing_address $sdram_config_address);
+use vars qw($sdram_precharge $sdram_nop $sdram_refresh $sdram_mrs);
+
+#****************** CONSTANT SECTION *****************************************
+
+# Register addresses
+$sdram_timing_address = "b0000008";
+$sdram_config_address = "b000000c";
+
+# SDRAM commands
+$sdram_precharge = 3;
+$sdram_nop = 0;
+$sdram_refresh = 2;
+$sdram_mrs = 1;
+
+#****************** MAIN PROGRAM SECTION *************************************
+
+# The name of this program.
+$my_name = basename($0);
+
+# Get options
+getopts('b:d:fFhi:o:O:ps:S:', \%opts);
+
+&print_help if ($opts{'h'});
+
+# Name and existance of the image
+$image_name = ($opts{'i'} ? $opts{'i'} : 'fimage');
+die "Could not find the image $image_name!\n" unless (-s $image_name);
+
+if ($opts{'f'} || $opts{'F'})
+{
+ $image_size = -s $image_name;
+
+ $offset = ($opts{'f'} ? 0x10000 : 0);
+
+ $offset = &convert_size($opts{'o'}) if (defined($opts{'o'}));
+
+ die("$my_name: Invalid destination offset\n") if ($offset !~ /^\d+$/);
+
+ my $base_name = basename($image_name);
+ if ($base_name eq 'timage' || $base_name eq 'flash1.img')
+ {
+ $source_offset = 0;
+ }
+ else
+ {
+ $source_offset = $offset;
+ }
+
+ $source_offset = &convert_size($opts{'O'}) if (defined($opts{'O'}));
+
+ die("$my_name: Invalid source offset\n") if ($source_offset !~ /^\d+$/);
+ die("$my_name: Source offset > image size\n") if ($source_offset > $image_size);
+
+ if (defined($opts{'S'}))
+ {
+ # Backwards compatibility to allow specifying the flash size in MB
+ # without using an M suffix
+ $opts{'S'} .= 'M' if ($opts{'S'} =~ /^\d+$/ && $opts{'S'} <= 16);
+
+ $flash_size = &convert_size($opts{'S'});
+ }
+ else
+ {
+ # Calculate a flash size large enough for the image without the checksum
+ # and HWID.
+ $flash_size = ($image_size - $source_offset + $offset) & 0xFFFF0000;
+ }
+
+ die("$my_name: Invalid flash size\n") if ($flash_size !~ /^\d+$/);
+ die("$my_name: Destination offset > flash size\n") if ($offset > $flash_size);
+ if (defined($opts{'s'}))
+ {
+ $flashing_size = &convert_size($opts{'s'});
+ }
+ else
+ {
+ $flashing_size = $flash_size - $offset;
+ }
+
+ die("$my_name: Invalid size to flash\n") if ($flashing_size !~ /^\d+$/);
+
+ if ($flashing_size > $flash_size - $offset)
+ {
+ $flashing_size = $flash_size - $offset;
+ printf("Warning: Flashing size limited to 0x%lx due to the offset (0x%lx) and flash size (0x%lx).\n", $flashing_size, $offset, $flash_size);
+ }
+
+ if ($flashing_size > $image_size - $source_offset)
+ {
+ $flashing_size = $image_size - $source_offset;
+ printf("Warning: Flashing size limited to 0x%lx due to the offset (0x%lx) and image size (0x%lx).\n", $flashing_size, $source_offset, $image_size);
+ }
+}
+
+# Create the command line to boot the image
+if (system('./etrax100boot --help > /dev/null') == 0)
+{
+ $cmd = './etrax100boot';
+}
+elsif (system('svinto_boot --help > /dev/null') == 0)
+{
+ $cmd = 'svinto_boot';
+}
+else
+{
+ die("Cannot find e100boot program in your PATH!\n");
+}
+
+$cmd .= " --device $opts{'d'}" if ($opts{'d'});
+
+$cmd .= &extract_hw_settings;
+
+$cmd .= " --bootfile $opts{'b'}" if ($opts{'b'});
+$cmd .= " --file $image_name $text_start";
+
+if ($opts{'f'} || $opts{'F'})
+{
+ $cmd .= sprintf(" --flash %lx %lx %lx --jump 0",
+ hex($text_start) + $source_offset, $offset, $flashing_size);
+}
+else
+{
+ $cmd .= " --jump $text_start";
+}
+
+if ($opts{'p'})
+{
+ print "Command:\n$cmd\n";
+}
+else
+{
+ system($cmd);
+}
+
+exit 0;
+
+#****************** FUNCTION DEFINITION SECTION ******************************
+
+#*****************************************************************************
+##
+## FUNCTION NAME: convert_size
+##
+##****************************************************************************
+
+sub convert_size
+{
+ my($arg) = @_;
+ my $size;
+
+ if ($arg =~ /^0x([\da-fA-F]+)([kM])?$/)
+ {
+ $size = hex($1);
+ }
+ elsif ($arg =~ /^(\d+)([kM])?$/)
+ {
+ $size = $1;
+ }
+ else
+ {
+ return -1;
+ }
+
+ if (!defined($2))
+ {
+ return $size;
+ }
+ elsif ($2 eq 'k')
+ {
+ return $size * 1024;
+ }
+ elsif ($2 eq 'M')
+ {
+ return $size * 1048576;
+ }
+}
+
+#*****************************************************************************
+##
+## FUNCTION NAME: extract_hw_settings
+##
+##****************************************************************************
+
+sub extract_hw_settings
+{
+ my $data;
+ my $dbg_port;
+ my $sdram_enabled;
+ my $return_value = "";
+ my $sdram_config;
+
+ # The hw information table has the following format
+ #
+ # "HW_PARAM_MAGIC"
+ # text_start (dword)
+ # serial debg port (dword)
+ # sdram enabled (dword)
+ # register address (dword)
+ # register value (dword)
+ # ...
+ # 0
+
+ open(FILE, "$image_name") || die("Could not open '$image_name'");
+
+ while (<FILE>)
+ {
+ if (m/HW_PARAM_MAGIC/g)
+ {
+ # Seek to first byte after magic
+ seek(FILE, -length($_) + pos($_), 1);
+ last;
+ }
+ }
+
+ $text_start = &get_dword;
+ $dbg_port = &get_dword;
+ $sdram_enabled = int(&get_dword);
+
+ while (1)
+ {
+ my $register = &get_dword;
+ my $value = &get_dword;
+
+ last if ($register eq "00000000");
+
+ if ($sdram_enabled)
+ {
+ if ($register eq $sdram_config_address)
+ {
+ $sdram_config = $value;
+ }
+ elsif ($register eq $sdram_timing_address)
+ {
+ $return_value .= &calculate_sdram_init($value, $sdram_config);
+ next;
+ }
+ }
+
+ $return_value .= " --setreg $register $value";
+ }
+
+ close(FILE);
+
+ return $return_value;
+}
+
+#*****************************************************************************
+##
+## FUNCTION NAME: get_dword
+##
+##****************************************************************************
+
+sub get_dword
+{
+ my $data;
+
+ read(FILE, $data, 4);
+ return unpack("H8", pack("V", unpack("N", $data)));
+}
+
+#*****************************************************************************
+##
+## FUNCTION NAME: calculate_sdram_init
+##
+##****************************************************************************
+
+sub calculate_sdram_init
+{
+ # Refer to ETRAX 100LX Designers Reference for a description of SDRAM
+ # initialization
+ my $sdram_init_val = hex($_[0]);
+ my $sdram_config_val = hex($_[1]);
+ my $bus_width = $sdram_config_val & 0x00800000;
+ my $speed;
+ my $cas_latency;
+ my $mrs_data;
+ my $temp;
+ my $return_value;
+ my $value;
+
+ $mrs_data = ($sdram_init_val & 0x00ff0000) >> 16;
+ $sdram_init_val &= 0x8000ffff; # Make sure mrs data is 0
+ $sdram_init_val |= 0x80000000; # Make sure sdram is enabled
+ $speed = $sdram_init_val & 0x1000;
+ $cas_latency = $sdram_init_val & 0x3;
+ if ($speed) # 100 MHz
+ {
+ $cas_latency += 2;
+ }
+ else # 50 MHz
+ {
+ $cas_latency += 1;
+ }
+
+ # Calculate value of mrs_data
+ # CAS latency = 2 && bus_width = 32 => 0x40
+ # CAS latency = 3 && bus_width = 32 => 0x60
+ # CAS latency = 2 && bus_width = 16 => 0x20
+ # CAS latency = 3 && bus_width = 16 => 0x30
+ if ($mrs_data == 0)
+ {
+ if ($bus_width == 0) # 16 bits
+ {
+ $mrs_data = $cas_latency == 2 ? 0x20 : 0x30;
+ }
+ else # 32 bits
+ {
+ $mrs_data = $cas_latency == 2 ? 0x40 : 0x60;
+ }
+ }
+
+ $temp = $sdram_init_val | 0x0000c000; # Disable refresh
+ $return_value .= &sdram_command($temp);
+ $return_value .= " --pause 20000";
+
+ $return_value .= &sdram_command($temp, $sdram_precharge);
+ $return_value .= &sdram_command($temp, $sdram_nop);
+
+ $return_value .= " --setreg +0 7";
+ $return_value .= " --label label1";
+ $return_value .= &sdram_command($temp, $sdram_refresh);
+ $return_value .= &sdram_command($temp, $sdram_nop);
+ $return_value .= " --loop +0 label1";
+
+ $return_value .= &sdram_command($temp, $sdram_mrs, $mrs_data);
+ $return_value .= &sdram_command($temp, $sdram_nop);
+
+ $return_value .= &sdram_command($sdram_init_val);
+
+ return $return_value;
+}
+
+#*****************************************************************************
+##
+## FUNCTION NAME: sdram_command
+##
+##****************************************************************************
+
+sub sdram_command
+{
+ my($temp, $value, $mrs_data) = @_;
+
+ $value ||= 0;
+ if ($value == $sdram_mrs)
+ {
+ $value = sprintf("%lx", $temp | ($value << 9) | ($mrs_data << 16));
+ }
+ else
+ {
+ $value = sprintf("%lx", $temp | ($value << 9));
+ }
+
+ return " --setreg $sdram_timing_address $value";
+}
+
+#*****************************************************************************
+##
+## FUNCTION NAME: print_help
+##
+##****************************************************************************
+
+sub print_help
+{
+ print "\nAXIS $my_name, ", '$Revision: 1.16 $ $Date: 2004/11/01 16:32:27 $ ', "\n";
+ die <<EOT;
+Copyright (C) 2001-2002 Axis Communications AB
+
+DESCRIPTION:
+ This program is used to boot (and flash) a linux image to a box.
+ It tries to extract the required ETRAX 100 settings from the image file.
+
+SYNTAX:
+ $my_name [options]
+
+OPTIONS:
+ -b <bootfile> : The boot image to use.
+ -d <device> : The network interface to use, default is eth0.
+ -f : Save the image in the flash memory starting at
+ address 0x10000.
+ -F : Save the image in the flash memory starting at
+ address 0.
+ -h : Print this help text.
+ -i <image> : The path and name of the image to use, default
+ is fimage.
+ -o <offset> : The offset in the flash where the flashing starts.
+ -O <offset> : The offset in the image file where the flashing
+ starts from.
+ -p : Print the resulting etrax100boot command instead
+ of executing it.
+ -s <size> : How much to flash (default is the size of the
+ flash minus the offset specified using -o or -f).
+ -S <size> : The size of the flash.
+
+ All sizes and offsets above can be specified as decimal numbers, or as
+ hexadecimal numbers by prefixing them with 0x. It is also possible to use
+ the suffixes k and M to specify kilo (1024) or mega (1048576).
+
+EOT
+}
+
+#****************** END OF FILE boot_linux ***********************************
--- /dev/null
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=e100boot
+PKG_VERSION:=0.1
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
+
+CRLF_WORKAROUND=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Build/Compile
+ mkdir -p $(PKG_BUILD_DIR)
+ cp -r ./src/* $(PKG_BUILD_DIR)
+ make -C $(PKG_BUILD_DIR)
+endef
+
+define Build/InstallDev
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/sbl/e100boot $(BIN_DIR)/etrax100boot
+endef
+
+$(eval $(call Build/DefaultTargets))
--- /dev/null
+Copyright (c) 2004, 2005 Axis Communications AB. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of Axis Communications AB nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY AXIS COMMUNCATIONS AB ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
--- /dev/null
+#
+# Top Makefile for e100boot
+# $Id: Makefile,v 1.20 2003/06/04 12:22:23 pkj Exp $
+#
+
+# Change these paths if necessary. Can also be specified on cmdline as
+# 'make INSTALL_PATH=/foo/bar/'.
+
+INSTALL_NAME = e100boot
+INSTALL_PATH = /usr/local
+INSTALL_PATH_BIN = $(INSTALL_PATH)/bin
+INSTALL_PATH_DOC = $(INSTALL_PATH)/man/man1
+
+DIRS = libpcap-0.4 sbl doc
+
+-include $(AXIS_TOP_DIR)/tools/build/Rules.axis
+ifdef prefix
+INSTALL_PATH = $(prefix)
+endif
+
+INSTALL ?= install
+
+all: conf $(DIRS)
+ @for d in $(DIRS); do \
+ echo -e "\n### Making $$d"; \
+ $(MAKE) -C $$d || exit; \
+ done
+
+conf: $(DIRS)
+ @for d in $(DIRS); do \
+ if [ -x $$d/configure ] && [ ! -e $$d/Makefile ]; then \
+ echo -e "\n### Configuring $$d"; \
+ cd $$d; ./configure ||Â exit; cd ..; \
+ fi; \
+ done
+
+tar: clean
+ @echo -e "\n### Making tarball."
+ tar -C ../ -zcf e100boot.tgz --exclude e100boot.tgz --exclude RCS --exclude CVS e100boot
+
+
+install: all
+ $(INSTALL) -d $(INSTALL_PATH_BIN) $(INSTALL_PATH_DOC)
+ $(INSTALL) sbl/e100boot.stripped $(INSTALL_PATH_BIN)/$(INSTALL_NAME)
+ $(INSTALL) -m 0644 doc/e100boot.1 $(INSTALL_PATH_DOC)/$(INSTALL_NAME).1
+
+install.setuid:
+ @echo -e "\n### Make install.setuid"; \
+ if ! [ -e $(INSTALL_PATH_BIN)/$(INSTALL_NAME) ]; then \
+ echo -e "\n### Binary $(INSTALL_PATH_BIN)/$(INSTALL_NAME) does not exist! Make install first."; \
+ elif [ `id -u` = 0 ]; then \
+ chown root.root $(INSTALL_PATH_BIN)/$(INSTALL_NAME); \
+ chmod +s $(INSTALL_PATH_BIN)/$(INSTALL_NAME); \
+ else \
+ echo "### You must do this as root!"; \
+ fi
+
+clean:
+ @for d in $(DIRS); do \
+ if [ -e $$d/Makefile ]; then \
+ echo -e "\n### Cleaning $$d"; \
+ $(MAKE) -C $$d clean || exit; \
+ fi; \
+ done
+
+configsubs: conf configsubs-dirs
+
+configsubs-dirs:
+ $(MAKE) -C libpcap-0.4 configsubs
+ $(MAKE) -C sbl configsubs
--- /dev/null
+#
+# Makefile to generate .ima files for e100boot
+#
+# Hacked by ronny, rehacked by ronny
+#
+# $Id: Makefile,v 1.26 2003/03/13 14:18:31 cii Exp $
+#
+
+DIRS := net net_noleds ser ser_noleds
+
+all: $(DIRS)
+ @for d in $(DIRS); do \
+ echo -e "\n### Making $$d"; \
+ make -C $$d || exit; \
+ done
+ @echo "***************************************************************"
+ @./free_size
+ @echo "***************************************************************"
+
+clean:
+ rm -f *.ima
+ @for d in $(DIRS); do \
+ echo -e "\n### Cleaning $$d"; \
+ make -C $$d clean || exit; \
+ done;
--- /dev/null
+#!/bin/sh
+#
+# Calculates the size left in ETRAX cache when bootloader is loaded.
+#
+
+BOOT_FILE=`dirname $0`/net/net.out
+HEADER_FILE=`dirname $0`/src/e100boot.h
+
+for FILE in $BOOT_FILE $HEADER_FILE; do
+ if [ ! -f $FILE ]; then
+ echo "Could not find the file \"$FILE\"!"
+ exit 1
+ fi
+done
+
+# The cache size is given in hex
+CACHE_SIZE=2000
+
+BSS_SIZE=`nm-cris $BOOT_FILE | grep Ebss | cut -d ' ' -f 1 | tr a-f A-F`
+
+TEXT_SIZE=`nm-cris $BOOT_FILE | grep Stext | cut -d ' ' -f 1 | tr a-f A-F`
+
+IO_BUF_END=`grep IO_BUF_END $HEADER_FILE | awk '{ print $3 }' | \
+ cut -d x -f 2 | tr a-f A-F`
+
+IO_BUF_START=`grep IO_BUF_START $HEADER_FILE | awk '{ print $3 }' | \
+ cut -d x -f 2 | tr a-f A-F`
+
+FREE_SIZE=`echo "ibase=16 ; \
+ $CACHE_SIZE - \
+ ($BSS_SIZE - $TEXT_SIZE + $IO_BUF_END - $IO_BUF_START)" | \
+ bc`
+
+echo "Free cache size when cbl is loaded will be:"
+echo -e "\t$FREE_SIZE bytes - size of stack"
+
+if [ $FREE_SIZE -lt 0 ]; then
+ echo "Bootloader is too large! You will have to do some optimizing..."
+ exit 1
+fi
+
+exit 0
--- /dev/null
+#
+# $Id: Makefile,v 1.1 2002/07/01 14:36:40 pkj Exp $
+#
+
+IMAGE := net.ima
+include ../rules.cbl
--- /dev/null
+common.o: ../src/common.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+common_init.o: ../src/common_init.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+crt0.o: ../src/crt0.S
--- /dev/null
+char e100boot_version[] = "This bootloader was built by root on Wed May 16 21:31:41 CEST 2007.\r\n";
--- /dev/null
+e100boot_version.o: e100boot_version.c
--- /dev/null
+flash.o: ../src/flash.c ../src/e100boot.h ../src/compiler.h
--- /dev/null
+hwregs.o: ../src/hwregs.c ../src/compiler.h ../src/hwregs.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h
--- /dev/null
+net_init.o: ../src/net_init.c ../src/sv_addr_ag.h ../src/sv_addr.agh \
+ ../src/e100boot.h ../src/compiler.h
--- /dev/null
+#
+# $Id: Makefile,v 1.1 2002/07/01 14:36:51 pkj Exp $
+#
+
+IMAGE := net_noleds.ima
+include ../rules.cbl
--- /dev/null
+common.o: ../src/common.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+common_init.o: ../src/common_init.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+crt0.o: ../src/crt0.S
--- /dev/null
+char e100boot_version[] = "This bootloader was built by root on Wed May 16 21:31:43 CEST 2007.\r\n";
--- /dev/null
+e100boot_version.o: e100boot_version.c
--- /dev/null
+flash.o: ../src/flash.c ../src/e100boot.h ../src/compiler.h
--- /dev/null
+hwregs.o: ../src/hwregs.c ../src/compiler.h ../src/hwregs.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h
--- /dev/null
+net_init.o: ../src/net_init.c ../src/sv_addr_ag.h ../src/sv_addr.agh \
+ ../src/e100boot.h ../src/compiler.h
--- /dev/null
+#
+# $Id: rules.cbl,v 1.4 2005/04/20 11:18:54 starvik Exp $
+#
+
+VPATH := .:../src
+
+ifeq ($(findstring _noleds,$(IMAGE)),_noleds)
+USE_LEDS := 0
+else
+USE_LEDS := 1
+endif
+
+MAKEFLAGS := r
+INCS := -I.
+DEFS := -DUSE_LEDS=$(USE_LEDS)
+CFLAGS := -Os -Wall -Wmissing-prototypes -W -Wa,-N -nostdinc $(INCS) $(DEFS) -MMD
+ASFLAGS := $(CFLAGS)
+LNFLAGS := -Wl,--section-start,.startup=0x380000f0 -nostdlib -Os -Wl,-T../src/ldscript
+CC := cris-axis-elf-gcc
+
+OUT := $(patsubst %.ima,%.out,$(IMAGE))
+
+OBJS = crt0.o common_init.o
+ifeq ($(findstring net,$(IMAGE)),net)
+OBJS += net_init.o
+else
+OBJS += ser_init.o
+endif
+OBJS += common.o flash.o hwregs.o e100boot_version.o
+
+all: ../$(IMAGE)
+
+$(OUT): $(OBJS) ldscript
+ $(CC) -o $@ $(LNFLAGS) $(OBJS)
+
+../%.ima: %.out
+ bin-cris -o $@ $<
+ @find $@ -printf '# Size of image $@ is %s bytes.\n\n'
+
+$(OBJS): ../rules.cbl Makefile
+
+# We don't want this to be a dummy and be recreated every time we build,
+# only after a make clean
+e100boot_version.c:
+ @echo "Generating version file....."
+ @echo 'char e100boot_version[] = "This bootloader was built by '`id -u -n`' on '`date`'.\r\n";' > $@
+
+dummy:
+
+clean:
+ rm -rf *.o *.d *.out *.ima deps e100boot_version.c
+
+ifneq ($(MAKECMDGOALS),clean)
+-include *.d
+endif
--- /dev/null
+#
+# $Id: Makefile,v 1.1 2002/07/01 14:37:01 pkj Exp $
+#
+
+IMAGE := ser.ima
+include ../rules.cbl
--- /dev/null
+common.o: ../src/common.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+common_init.o: ../src/common_init.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+crt0.o: ../src/crt0.S
--- /dev/null
+char e100boot_version[] = "This bootloader was built by root on Wed May 16 21:31:44 CEST 2007.\r\n";
--- /dev/null
+e100boot_version.o: e100boot_version.c
--- /dev/null
+flash.o: ../src/flash.c ../src/e100boot.h ../src/compiler.h
--- /dev/null
+hwregs.o: ../src/hwregs.c ../src/compiler.h ../src/hwregs.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h
--- /dev/null
+ser_init.o: ../src/ser_init.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/sv_addr_ag.h ../src/sv_addr.agh ../src/e100boot.h
--- /dev/null
+#
+# $Id: Makefile,v 1.1 2002/07/01 14:37:10 pkj Exp $
+#
+
+IMAGE := ser_noleds.ima
+include ../rules.cbl
--- /dev/null
+common.o: ../src/common.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+common_init.o: ../src/common_init.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/e100boot.h
--- /dev/null
+crt0.o: ../src/crt0.S
--- /dev/null
+char e100boot_version[] = "This bootloader was built by root on Wed May 16 21:31:46 CEST 2007.\r\n";
--- /dev/null
+e100boot_version.o: e100boot_version.c
--- /dev/null
+flash.o: ../src/flash.c ../src/e100boot.h ../src/compiler.h
--- /dev/null
+hwregs.o: ../src/hwregs.c ../src/compiler.h ../src/hwregs.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h
--- /dev/null
+ser_init.o: ../src/ser_init.c ../src/hwregs.h ../src/compiler.h \
+ ../src/debug.h ../src/project.h ../src/hwregs_def.h ../src/hwregs_int.h \
+ ../src/sv_addr_ag.h ../src/sv_addr.agh ../src/e100boot.h
--- /dev/null
+#include "hwregs.h"
+#include "e100boot.h"
+
+static void toggle_led(void);
+
+static void read_load_info(void);
+static void decode_load_info(void);
+
+static void read_file(byte* addr, udword size);
+
+#if USE_PRINT_DESCR
+static void print_descr(dma_descr_T *d);
+#endif
+
+static int memory_test(udword addr, udword size, udword *failed_address);
+static void memory_dump(udword *from, udword *to);
+
+extern byte _Stext[];
+extern byte _Edata[];
+
+#ifdef USE_BAUDRATE_CHANGING
+byte change_baudrate;
+udword new_baudrate;
+#endif
+
+void
+level2_boot(void)
+{
+#if USE_LEDS
+ REG_SET(R_PORT_PA_DATA, data_out, 0xaa);
+#endif
+
+#if 0
+ io_buf_next = (byte*)IO_BUF_START;
+ io_buf_cur = (byte*)IO_BUF_START;
+#endif
+
+#if 1
+ send_string("\r\n\r\nDevice ID = ");
+ send_hex(ntohl(tx_header.id), NL);
+ send_string(e100boot_version);
+#endif
+
+#if 1
+ {
+ udword sum = 0;
+ byte *b;
+
+ for (b = (byte*)_Stext; b != (byte*)_Edata; b++) {
+ sum += *b;
+ }
+ send_string("Checksum of bootloader is ");
+ send_hex(sum, NL);
+ }
+#endif
+
+ read_load_info();
+
+ __asm__ volatile ("jump _start");
+}
+
+void
+toggle_led(void)
+{
+#if USE_LEDS
+ REG_SET(R_PORT_PA_DATA, data_out, 0x55);
+
+ while (1) {
+ REG_SET(R_PORT_PA_DATA, data_out, ~REG_GET(R_PORT_PA_READ, data_in));
+ {
+ volatile udword i;
+
+ for (i = 0; i != 2000000; i++)
+ ;
+ }
+ }
+#else
+ while (1) {
+ }
+#endif
+}
+
+void
+read_load_info(void)
+{
+#ifdef USE_BAUDRATE_CHANGING
+ change_baudrate = 0;
+#endif
+
+ send_string("Waiting for load info.\r\n");
+
+ send_ack();
+
+ read_file((byte*)IO_BUF_START, IO_BUF_END - IO_BUF_START - CRC_LEN);
+ send_string("Got load info.\r\n");
+ decode_load_info();
+
+#ifdef USE_BAUDRATE_CHANGING
+ if (change_baudrate) {
+ REG_WR(R_SERIAL0_BAUD, new_baudrate);
+ {
+ udword i = 0;
+
+ while (i++ < 1000000)
+ ;
+ }
+ send_ack();
+ }
+#endif
+
+ toggle_led();
+}
+
+void
+decode_load_info(void)
+{
+ udword *type_p = (udword*)IO_BUF_START;
+ udword failed_address;
+ udword i;
+ command_T *cmd;
+
+ while (type_p != (udword*)(IO_BUF_END - CRC_LEN)) { /* !!! */
+// send_hex(type_p, NL);
+ *type_p = ntohl(*type_p);
+// send_hex(*type_p, NL);
+ type_p++;
+ }
+
+// memory_dump(IO_BUF_START, IO_BUF_END);
+
+ cmd = (command_T*)IO_BUF_START;
+ while (cmd->type) {
+ switch (cmd->type) {
+ case PACKET_INFO:
+ send_string("PACKET_INFO\r\n");
+ send_hex(cmd->args.packet_info.addr, NL);
+ send_hex(cmd->args.packet_info.size, NL);
+
+ seq--;
+ send_ack();
+ seq++;
+
+ read_file((byte*)cmd->args.packet_info.addr, cmd->args.packet_info.size);
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.packet_info;
+ break;
+
+ case SET_REGISTER:
+ send_string("SET_REGISTER\r\n");
+ send_hex(cmd->args.set_register.addr, NL);
+ send_hex(cmd->args.set_register.val, NL);
+
+ *(udword*)cmd->args.set_register.addr = cmd->args.set_register.val;
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.set_register;
+ break;
+
+ case GET_REGISTER:
+ send_string("GET_REGISTER\r\n");
+ send_hex(cmd->args.get_register.addr, NL);
+ send_hex(*(udword*)cmd->args.get_register.addr, NL);
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.get_register;
+ break;
+
+ case PAUSE_LOOP:
+ send_string("PAUSE_LOOP\r\n");
+ send_hex(cmd->args.pause_loop.pause, NL);
+
+ for (i = cmd->args.pause_loop.pause; i; i--)
+ ;
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.pause_loop;
+ break;
+
+ case MEM_VERIFY:
+ send_string("MEM_VERIFY\r\n");
+ send_hex(cmd->args.mem_verify.addr, NL);
+ send_hex(cmd->args.mem_verify.val, NL);
+
+ if (*(udword*)cmd->args.mem_verify.addr != cmd->args.mem_verify.val) {
+ send_string("verify failed\r\n");
+ goto decode_failed;
+ }
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.mem_verify;
+ break;
+
+ case MEM_TEST:
+ send_string("MEM_TEST\r\n");
+ send_hex(cmd->args.mem_test.from, NL);
+ send_hex(cmd->args.mem_test.to, NL);
+
+ if (!memory_test(cmd->args.mem_test.from,
+ cmd->args.mem_test.to,
+ &failed_address)) {
+ send_string("### Memory test failed at ");
+ send_hex(failed_address, NL);
+ memory_dump((udword*)DWORD_ALIGN(failed_address - 64),
+ (udword*)DWORD_ALIGN(failed_address + 64));
+ goto decode_failed;
+ }
+ send_string("Passed memory test.\r\n");
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.mem_test;
+ break;
+
+ case MEM_DUMP:
+ send_string("MEM_DUMP\r\n");
+ send_hex(cmd->args.mem_dump.from_addr, NL);
+ send_hex(cmd->args.mem_dump.to_addr, NL);
+
+ memory_dump((udword*)cmd->args.mem_dump.from_addr,
+ (udword*)cmd->args.mem_dump.to_addr);
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.mem_dump;
+ break;
+
+ case MEM_CLEAR:
+ send_string("MEM_CLEAR\r\n");
+ send_hex(cmd->args.mem_clear.from_addr, NL);
+ send_hex(cmd->args.mem_clear.to_addr, NL);
+
+ for (i = cmd->args.mem_clear.from_addr;
+ i <= cmd->args.mem_clear.to_addr;
+ i++) {
+ *(byte*)i = 0x00;
+ }
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.mem_clear;
+ break;
+
+ case FLASH:
+ send_string("FLASH\r\n");
+ send_hex((udword)cmd->args.flash.source, NL);
+ send_hex(cmd->args.flash.offset, NL);
+ send_hex(cmd->args.flash.size, NL);
+
+ if ((i = flash_write(cmd->args.flash.source,
+ cmd->args.flash.offset,
+ cmd->args.flash.size)) != ERR_FLASH_OK) {
+ if (i == ERR_FLASH_VERIFY) {
+ udword size =
+ (cmd->args.flash.size < 65536 ? cmd->args.flash.size : 65536);
+
+ /* Try to erase the first block(s) we tried to flash to prevent a
+ unit which failed to flash correctly from booting */
+ flash_write(NULL, cmd->args.flash.offset, size);
+ }
+
+ goto decode_failed;
+ }
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.flash;
+ break;
+
+ case JUMP:
+#if 1
+ /* for the printf function in our libc */
+ REG_WR(R_DMA_CH8_FIRST, *(udword*)&tx_header.dest[0]);
+ REG_WR(R_DMA_CH9_FIRST, *(uword*)&tx_header.dest[4]);
+// REG_WR(R_NETWORK_SA_1, &tx_header.dest[4]);
+// REG_WR(R_NETWORK_SA_2, tx_header.id);
+#endif
+ send_string("JUMP\r\n");
+ send_hex(cmd->args.jump.addr, NL);
+ send_string("END\r\n");
+
+ __asm__ volatile ("jump %0" :: "r" (cmd->args.jump.addr));
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.jump;
+ break;
+
+ case LOOP:
+ send_string("LOOP\r\n");
+ send_hex(cmd->args.bne.addr, NL);
+ send_hex(cmd->args.bne.target, NL);
+
+ if (*(udword*)cmd->args.bne.addr) {
+ (*(udword*)cmd->args.bne.addr)--;
+ (byte*)cmd = cmd->args.bne.target;
+ }
+ else {
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.bne;
+ }
+ break;
+
+#ifdef USE_BAUDRATE_CHANGING
+ case BAUDRATE:
+ send_string("BAUDRATE\r\n");
+ send_hex(cmd->args.br.baudrate, NL);
+
+ new_baudrate = cmd->args.br.baudrate;
+
+ (byte*)cmd += sizeof cmd->type + sizeof cmd->args.br;
+ break;
+#endif
+
+ default:
+ send_string("### Unknown type: ");
+ send_hex(cmd->type, NL);
+
+ goto decode_failed;
+ break;
+ }
+ }
+
+decode_failed:
+ send_string("END\r\n");
+}
+
+void
+read_file(byte* addr, udword size)
+{
+ udword nbr_read_last;
+ udword sum;
+ byte *b;
+ byte *from;
+
+/* send_string(">read_file\r\n"); */
+
+ nbr_read = 0;
+ nbr_read_last = 0;
+ target_address = (udword)addr;
+
+ if (interface == NETWORK) {
+ rx_descr2.buf = (udword)addr;
+ bytes_to_read = size;
+ rx_descr2.sw_len = size + CRC_LEN > 1500 ? 1500 : size + CRC_LEN;
+/* rx_descr2.sw_len = 1500; */
+
+ REG_SET(R_DMA_CH1_FIRST, first, (udword)&rx_descr);
+
+ /* Restart receiver so descriptor is re-read. */
+ REG_SET(R_DMA_CH1_CMD, cmd, reset);
+ while (REG_EQL(R_DMA_CH1_CMD, cmd, reset)) {
+ }
+
+ REG_SET(R_DMA_CH1_CMD, cmd, start);
+
+ while (1) {
+/* send_hex(rx_descr2.hw_len, NL); */
+ from = (byte*)rx_descr2.buf;
+ if (read_data()) {
+ if (nbr_read < size) {
+ REG_SET(R_DMA_CH1_CMD, cmd, start);
+ }
+
+#if USE_PRINT_DESCR
+ print_descr(&rx_descr);
+ print_descr(&rx_descr2);
+#endif
+
+#if 0
+ send_string("Read ");
+ send_hex(rx_descr2.hw_len - CRC_LEN, NO_NL);
+ send_string(" bytes. ");
+ send_hex((udword)from, NO_NL);
+ send_string(" - ");
+ send_hex(rx_descr2.buf-1, NO_NL);
+ send_string(" (");
+ send_hex(nbr_read, NO_NL);
+ send_string("/");
+ send_hex(size, NO_NL);
+ send_string(")\r\n");
+#endif
+
+ nbr_read_last = nbr_read;
+/* from = (byte*)rx_descr2.buf; */
+
+ if (nbr_read >= size) {
+ break;
+ }
+ }
+ }
+ }
+ else { /* interface != NETWORK */
+ while (nbr_read < size) {
+ read_data();
+ }
+ }
+
+ sum = 0;
+ for (b = addr; b != (byte*)(addr+size); b++) {
+ sum += *b;
+ }
+ send_string("Checksum of file is ");
+ send_hex(sum, NL);
+
+/* memory_dump((udword*)addr, (udword*)addr+size); */
+/* send_string("<read_file\r\n"); */
+}
+
+#if USE_PRINT_DESCR
+void
+print_descr(dma_descr_T *d)
+{
+ send_string("Descriptor at ");
+ send_hex((udword)d, NL);
+
+ send_string("ctrl : ");
+ send_hex(d->ctrl, NL);
+
+ send_string("sw_len : ");
+ send_hex(d->sw_len, NL);
+
+ send_string("next : ");
+ send_hex(d->next, NL);
+
+ send_string("buf : ");
+ send_hex(d->buf, NL);
+
+ send_string("status : ");
+ send_hex(d->status, NL);
+
+ send_string("hw_len : ");
+ send_hex(d->hw_len, NL);
+}
+#endif
+
+int
+memory_test(udword from, udword to, udword *failed_address)
+{
+ udword i;
+ udword j;
+ byte b;
+
+ /* At each dword (but bytewise) write the inverse of the adress,
+ check that it worked, then write the inverse of the last byte
+ written. Exit on fail. The memory after a successfull test will
+ be:
+
+ 0xC0000000 : 0xC0000000 0xC0000004 0xC0000008 0xC000000C
+ 0xC0000010 : 0xC0000010 0xC0000014 0xC0000018 0xC000001C
+ */
+
+ for (i = from; i < to; i += 4) {
+ for (j = 0; (j != sizeof(udword)) && (i+j < to); j++) {
+ b = ((~i) >> (j*8)) & 0xff;
+ *(volatile byte*)(i+j) = b;
+ if (*(volatile byte*)(i+j) == b) {
+ *(volatile byte*)(i+j) = ~b;
+ }
+ else {
+ *failed_address = i+j;
+ send_string("### Memory test 1 failed at ");
+ send_hex(*failed_address, NL);
+ return FALSE;
+ }
+ }
+ }
+
+ /* Run through entire region, check bytewise that the dwords contain
+ the address to the dword. Exit on fail. */
+
+ for (i = from; i < to; i += 4) {
+ for (j = 0; (j != sizeof(udword)) && (i+j < to); j++) {
+ b = (i >> (j*8)) & 0xff;
+ if (*(volatile byte*)(i+j) != b) {
+ *failed_address = i+j;
+ send_string("### Memory test 2 failed at ");
+ send_hex(*failed_address, NL);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+void
+memory_dump(udword *from, udword *to)
+{
+ udword *i = from;
+ int j;
+
+ for (; i <= to; i += 4) {
+ send_hex((udword)i, NO_NL);
+ send_string(" :");
+ for(j = 0; j != 4 && (i+j <= to); j++) {
+ send_string(" ");
+ send_hex(*(udword*)(i+j), NO_NL);
+ }
+ send_string("\r\n");
+ }
+}
--- /dev/null
+/*****************************************************************************
+*!
+*! FILE NAME : common_init.c
+*!
+*! DESCRIPTION: This piece of code is loaded at bootstrap and is put in the
+*! cache at 0x380000F0. Depending of how R_BUS_STATUS<2:1> is
+*! set different kinds of bootstrap is performed.
+*!
+*! 00 - Normal boot. No bootstrap is performed and this code
+*! is never loaded.
+*! 01 - Serial boot. 784 bytes is loaded and execution starts
+*! at 0x380000F0.
+*! 11 - Parallel boot. 784 bytes is loaded and execution starts
+*! at 0x380000F0.
+*! 10 - Network boot. 1484 bytes is loaded and execution start
+*! at 0x380000F4.
+*!
+*! ---------------------------------------------------------------------------
+*! HISTORY
+*!
+*! DATE NAME CHANGES
+*! ---- ---- -------
+*! 980326 Ronny Ranerup Initial version
+*! Sep 20 1999 Jonas Dellenvall Added port3 debug support
+*! 20020206 ronny Yeah, and I removed it again...
+*!
+*! ---------------------------------------------------------------------------
+*! (C) Copyright 1998-2002, Axis Communications AB, LUND, SWEDEN
+*!***************************************************************************/
+
+/*
+
+ Misc notes:
+
+ It is very important to keep this file short. This and the boot
+ interface specific parts must fit into the first boot packet.
+
+*/
+
+/****************** INCLUDE FILES SECTION ***********************************/
+
+#include "hwregs.h"
+#include "e100boot.h"
+
+/****************** CONSTANT AND MACRO SECTION ******************************/
+
+/****************** TYPE DEFINITION SECTION *********************************/
+
+/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
+
+static int timeout(void);
+
+/****************** GLOBAL VARIABLE DECLARATION SECTION *********************/
+
+udword nbr_read; /* How many bytes has been read from current file */
+byte interface; /* Which I/O interface is the current one */
+byte set_dest; /* Have we set the destination address in tx_header */
+udword last_timeout;
+
+struct packet_header_T tx_header;
+dma_descr_T tx_descr; /* For packet header */
+dma_descr_T tx_descr2; /* packet data */
+
+struct packet_header_T rx_header;
+dma_descr_T rx_descr; /* For packet header */
+dma_descr_T rx_descr2; /* packet data */
+
+udword seq; /* Sequence number of next wanted packet */
+byte serial_up;
+
+/****************** LOCAL VARIABLE DECLARATION SECTION **********************/
+
+/****************** FUNCTION DEFINITION SECTION *****************************/
+
+void
+crt1(void)
+{
+ /* Do this only once so we don't reset the timers and destroy the 32
+ bit timer-register used as random number generator */
+
+ REG_SET__R_TIMER_CTRL(
+ timerdiv1, 0,
+ timerdiv0, 0,
+ presc_timer1, normal,
+ i1, clr,
+ tm1, run,
+ clksel1, cascade0,
+ presc_ext, prescale,
+ i0, clr,
+ tm0, run,
+ clksel0, c9600Hz);
+
+ REG_SET__R_TIMER_CTRL(
+ timerdiv1, 0,
+ timerdiv0, 0,
+ presc_timer1, normal,
+ i1, nop,
+ tm1, run,
+ clksel1, cascade0,
+ presc_ext, prescale,
+ i0, nop,
+ tm0, run,
+ clksel0, c9600Hz);
+
+ start();
+}
+
+void
+start(void)
+{
+#if USE_LEDS
+ REG_SET__R_PORT_PA_DIR(
+ dir7, output,
+ dir6, output,
+ dir5, output,
+ dir4, output,
+ dir3, output,
+ dir2, output,
+ dir1, output,
+ dir0, input); /* not for prodtest */
+
+ REG_SET__R_PORT_PA_DATA(data_out, 0);
+
+ REG_SET__R_PORT_PB_DIR(
+ dir7, output,
+ dir6, output,
+ dir5, output,
+ dir4, output,
+ dir3, output,
+ dir2, output,
+ dir1, output,
+ dir0, output);
+
+ REG_SET__R_PORT_PB_DATA(data_out, 0xff);
+#endif
+
+ /* We must initialize all (global) variables here, since the .data
+ and .bss area are used before they are loaded. */
+
+ //serial_up = FALSE;
+ nbr_read = 0;
+
+ /* Get a random value to use as id. */
+ tx_header.id = htonl(REG_RD(R_TIMER_DATA));
+
+ /* timer01 is used as timer. */
+ last_timeout = REG_GET(R_TIMER01_DATA, count);
+
+ interface = REG_GET(R_BUS_STATUS, boot) - 1; /* 0,1,2 */
+ rx_descr2.status = 0;
+
+ /* Initialize the boot interface */
+ init_interface();
+ send_ack(); /* Ack the first bootpacket, i.e. this code. seq 0. */
+
+ while (1) {
+ if (read_data()) {
+ if (nbr_read >= (udword)bytes_to_read) {
+ break;
+ }
+ else if (interface == NETWORK) {
+ REG_SET(R_DMA_CH1_CMD, cmd, start);
+ }
+ }
+ }
+
+#if USE_LEDS
+ REG_SET(R_PORT_PA_DATA, data_out, 0x55);
+#endif
+
+ level2_boot();
+}
+
+int
+read_data(void)
+{
+ if (handle_read()) {
+ return TRUE;
+ }
+
+ if (timeout()) {
+ send_ack();
+ }
+
+ return FALSE;
+}
+
+int
+timeout(void)
+{
+ volatile int now = REG_GET(R_TIMER01_DATA, count);
+ int elapsed;
+ int wait_time = 9600;
+
+ elapsed = last_timeout - now;
+
+ if (elapsed < 0) {
+ elapsed = -elapsed;
+ }
+
+ if (elapsed > wait_time) {
+ last_timeout = now;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/****************** END OF FILE common_init.c *******************************/
--- /dev/null
+#ifndef _COMPILER_H
+#define _COMPILER_H
+
+typedef int dword;
+typedef unsigned int udword;
+typedef signed short word;
+typedef unsigned short uword;
+typedef unsigned char byte;
+
+#endif
--- /dev/null
+ .global crt0 ; Needed because of a bug in binutils
+ .global _target_address
+ .global _bytes_to_read
+
+ .section .startup, "ax"
+
+ nop
+ nop
+
+
+crt0:
+ move.d 0x38001f00, sp
+ jump _crt1
+
+_bytes_to_read: .dword 0x12345678
+_target_address: .dword 0x87654321
+
--- /dev/null
+/* $Id: e100boot.h,v 1.9 2003/12/16 09:04:07 magnusmn Exp $ */
+
+#include "compiler.h"
+
+#define DMA_DESCR__out_priority__BITNR 5
+#define DMA_DESCR__out_priority__WIDTH 1
+#define DMA_DESCR__out_priority__normal 0
+#define DMA_DESCR__out_priority__high 1
+
+#define DMA_DESCR__ecp_cmd__BITNR 4
+#define DMA_DESCR__ecp_cmd__WIDTH 1
+#define DMA_DESCR__ecp_cmd__normal 0
+#define DMA_DESCR__ecp_cmd__high 1
+
+#define DMA_DESCR__tx_err__BITNR 4
+#define DMA_DESCR__tx_err__WIDTH 1
+#define DMA_DESCR__tx_err__enable 1
+#define DMA_DESCR__tx_err__disable 0
+
+#define DMA_DESCR__intr__BITNR 3
+#define DMA_DESCR__intr__WIDTH 1
+#define DMA_DESCR__intr__enable 1
+#define DMA_DESCR__intr__disable 0
+
+#define DMA_DESCR__wait__BITNR 2
+#define DMA_DESCR__wait__WIDTH 1
+#define DMA_DESCR__wait__enable 1
+#define DMA_DESCR__wait__disable 0
+
+#define DMA_DESCR__eop__BITNR 1
+#define DMA_DESCR__eop__WIDTH 1
+#define DMA_DESCR__eop__enable 1
+#define DMA_DESCR__eop__disable 0
+
+#define DMA_DESCR__eol__BITNR 0
+#define DMA_DESCR__eol__WIDTH 1
+#define DMA_DESCR__eol__enable 1
+#define DMA_DESCR__eol__disable 0
+
+#define DMA_DESCR__sw_len__BITNR 0
+#define DMA_DESCR__sw_len__WIDTH 16
+
+#define DMA_DESCR__next__BITNR 0
+#define DMA_DESCR__next__WIDTH 32
+
+#define DMA_DESCR__buf__BITNR 0
+#define DMA_DESCR__buf__WIDTH 32
+
+#define DMA_DESCR__fifo_len__BITNR 8
+#define DMA_DESCR__fifo_len__WIDTH 7
+
+#define DMA_DESCR__crc_err__BITNR 7
+#define DMA_DESCR__crc_err__WIDTH 1
+#define DMA_DESCR__crc_err__enable 1
+#define DMA_DESCR__crc_err__disable 0
+
+#define DMA_DESCR__align_err__BITNR 6
+#define DMA_DESCR__align_err__WIDTH 1
+#define DMA_DESCR__align_err__enable 1
+#define DMA_DESCR__align_err__disable 0
+
+#define DMA_DESCR__in_priority__BITNR 5
+#define DMA_DESCR__in_priority__WIDTH 1
+#define DMA_DESCR__in_priority__high 1
+#define DMA_DESCR__in_priority__normal 0
+
+#define DMA_DESCR__stop__BITNR 4
+#define DMA_DESCR__stop__WIDTH 1
+
+#define DMA_DESCR__rd_eop__BITNR 1
+#define DMA_DESCR__rd_eop__WIDTH 1
+
+#define DMA_DESCR__hw_len__BITNR 0
+#define DMA_DESCR__hw_len__WIDTH 16
+
+#define SET_ETHER_ADDR(a0_0,a0_1,a0_2,a0_3,a0_4,a0_5,a1_0,a1_1,a1_2,a1_3,a1_4,a1_5) \
+ *R_NETWORK_SA_0 = a0_0 | (a0_1 << 8) | (a0_2 << 16) | (a0_3 << 24); \
+ *R_NETWORK_SA_1 = a0_4 | (a0_5 << 8) | (a1_0 << 16) | (a1_1 << 24); \
+ *R_NETWORK_SA_2 = a1_2 | (a1_3 << 8) | (a1_4 << 16) | (a1_5 << 24);
+
+#define DWORD_ALIGN(x) ((x) & 0xfffffffc)
+
+#define CRC_LEN 4
+
+#define TRUE 1
+#define FALSE 0
+
+#define NL 1
+#define NO_NL 0
+
+#define SERIAL 0
+#define NETWORK 1
+#define PARALLEL 2
+
+#define STRING 0
+#define INT 1
+#define ACK 2
+#define BOOT_PACKET 3
+#define BOOT_CMDS 4
+#define NET_INT 5
+#define NET_INT_NL 6
+
+#define JUMP 1
+#define MEM_TEST 2
+#define PACKET_INFO 3
+#define SET_REGISTER 4
+#define GET_REGISTER 5
+#define MEM_DUMP 6
+#define MEM_CLEAR 7
+#define MEM_VERIFY 8
+#define FLASH 9
+#define PAUSE_LOOP 10
+#define LOOP 11
+#define BAUDRATE 12
+
+#define ERR_FLASH_OK 0
+#define ERR_FLASH_NONE 1
+#define ERR_FLASH_TOO_SMALL 2
+#define ERR_FLASH_VERIFY 3
+#define ERR_FLASH_ERASE 4
+
+#define TIMEOUT_LIMIT ( ((6250 * 1000) / 0xffff) / 2)
+
+#define TX_CTRL_EOP \
+(IO_STATE(DMA_DESCR, intr, disable) |\
+ IO_STATE(DMA_DESCR, wait, enable) |\
+ IO_STATE(DMA_DESCR, eop, enable) |\
+ IO_STATE(DMA_DESCR, eol, enable))
+
+#define TX_CTRL \
+ (IO_STATE(DMA_DESCR, intr, disable) |\
+ IO_STATE(DMA_DESCR, wait, disable) |\
+ IO_STATE(DMA_DESCR, eop, disable) |\
+ IO_STATE(DMA_DESCR, eol, disable))
+
+#define LOAD_ADDRESS 0x38001000
+#define SIZEOF_BOOT_LEVEL_1 2048
+
+/* This is where the commands are transfered to. */
+#define IO_BUF_START 0x38001f00
+#define IO_BUF_END 0x380020f0 /* bootcode start + cache size */
+
+/* This should only be used in the cbl, but if we compile the sbl for
+ * elinux then __CRIS__ will be defined, and these are already defined
+ * in uC-libc. Check that __linux__ is not defined as well!
+ */
+
+#if defined(__CRIS__) && !defined(__linux__)
+#define NULL ((void*)0)
+
+static inline udword
+htonl(udword x)
+{
+ __asm__ ("swapwb %0" : "=r" (x) : "0" (x));
+
+ return(x);
+}
+#ifndef ntohl
+#define ntohl(x) htonl(x)
+#endif
+
+static inline uword
+htons(uword x)
+{
+ __asm__ ("swapb %0" : "=r" (x) : "0" (x));
+
+ return(x);
+}
+#ifndef ntohs
+#define ntohs(x) htons(x)
+#endif
+#endif
+
+/*#define ntohs(x) \*/
+/*((unsigned short)((((unsigned short)(x) & 0x00ffU) << 8) | \*/
+/* (((unsigned short)(x) & 0xff00U) >> 8)))*/
+/* */
+
+/*#define ntohl(x) \*/
+/*((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \*/
+/* (((unsigned long int)(x) & 0x0000ff00U) << 8) | \*/
+/* (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \*/
+/* (((unsigned long int)(x) & 0xff000000U) >> 24)))*/
+
+struct packet_header_T /* Size = 38 */
+{
+ byte dest[6];
+ byte src[6];
+ uword length;
+ udword snap1;
+ udword snap2;
+ udword tag;
+ udword seq;
+ udword type;
+ udword id;
+} __attribute__ ((packed));
+
+typedef struct dma_descr_T {
+ uword sw_len; /* 0-1 */
+ uword ctrl; /* 2-3 */
+ udword next; /* 4-7 */
+ udword buf; /* 8-11 */
+ uword hw_len; /* 12-13 */
+ uword status; /* 14-15 */
+} dma_descr_T;
+
+typedef struct packet_info_T {
+ udword addr;
+ udword size;
+} packet_info_T;
+
+typedef struct set_register_T {
+ udword addr;
+ udword val;
+} set_register_T;
+
+typedef struct get_register_T {
+ udword addr;
+} get_register_T;
+
+typedef struct pause_loop_T {
+ udword pause;
+} pause_loop_T;
+
+typedef struct mem_verify_T {
+ udword addr;
+ udword val;
+} mem_verify_T;
+
+typedef struct mem_test_T {
+ udword from;
+ udword to;
+} mem_test_T;
+
+typedef struct mem_dump_T {
+ udword from_addr;
+ udword to_addr;
+} mem_dump_T;
+
+typedef struct mem_clear_T {
+ udword from_addr;
+ udword to_addr;
+} mem_clear_T;
+
+typedef struct flash_T {
+ unsigned char *source;
+ udword offset;
+ udword size;
+} flash_T;
+
+typedef struct jump_T {
+ udword addr;
+} jump_T;
+
+typedef struct bne_T {
+ udword addr;
+ udword target;
+} bne_T;
+
+typedef struct br_T {
+ udword baudrate;
+} br_T;
+
+typedef struct command_T {
+ udword type;
+ union {
+ packet_info_T packet_info;
+ set_register_T set_register;
+ get_register_T get_register;
+ pause_loop_T pause_loop;
+ mem_verify_T mem_verify;
+ mem_test_T mem_test;
+ mem_dump_T mem_dump;
+ mem_clear_T mem_clear;
+ flash_T flash;
+ jump_T jump;
+ bne_T bne;
+ br_T br;
+ } args;
+} command_T;
+
+#define NETWORK_HEADER_LENGTH sizeof(struct packet_header_T)
+
+void crt1(void);
+void start(void);
+void level2_boot(void);
+int read_data(void);
+int handle_network_read(void);
+int flash_write(const unsigned char *source, unsigned int offset, unsigned int size);
+
+void init_interface(void);
+int handle_read(void);
+void send_ack(void);
+void send_string(char *str);
+void send_hex(udword v, byte nl);
+
+extern char e100boot_version[];
+
+extern volatile udword bytes_to_read;
+extern volatile udword target_address;
+
+extern udword nbr_read;
+extern byte interface;
+extern byte set_dest;
+extern udword last_timeout;
+extern byte *io_buf_next;
+extern byte *io_buf_cur;
+
+extern struct packet_header_T tx_header;
+extern dma_descr_T tx_descr;
+extern dma_descr_T tx_descr2;
+
+extern struct packet_header_T rx_header;
+extern dma_descr_T rx_descr;
+extern dma_descr_T rx_descr2;
+
+extern uword timeout_limit;
+extern udword seq;
+extern byte serial_up;
+
+enum { /* Available in: */
+ d_eol = (1 << 0), /* flags */
+ d_eop = (1 << 1), /* flags & status */
+ d_wait = (1 << 2), /* flags */
+ d_int = (1 << 3), /* flags */
+ d_txerr = (1 << 4), /* flags */
+ d_stop = (1 << 4), /* status */
+ d_ecp = (1 << 4), /* flags & status */
+ d_pri = (1 << 5), /* flags & status */
+ d_alignerr = (1 << 6), /* status */
+ d_crcerr = (1 << 7) /* status */
+};
--- /dev/null
+/* $Id: flash.c,v 1.39 2004/04/20 07:57:57 jonashg Exp $
+ *
+ * Stolen from the eLinux kernel and stripped down.
+ *
+ * HISTORY:
+ *
+ * $Log: flash.c,v $
+ * Revision 1.39 2004/04/20 07:57:57 jonashg
+ * Clear flash_status fields to make it possible to flash several images
+ * sequentially.
+ *
+ * Revision 1.38 2003/12/16 09:04:07 magnusmn
+ * Removed FLASHFILL command
+ *
+ * Revision 1.37 2003/12/16 08:49:01 magnusmn
+ * Merging change_branch--fast_flash
+ *
+ * Revision 1.36.2.6 2003/12/15 17:21:27 magnusmn
+ * Reset counter when continuing with operations the next sector.
+ *
+ * Revision 1.36.2.5 2003/12/15 11:35:57 magnusmn
+ * Bail out if we try to erase the same sector more that 10 times
+ *
+ * Revision 1.36.2.4 2003/12/12 12:07:10 magnusmn
+ * FIX for ST M29W320DT
+ * Some chip need a reset to bring them back to read mode again.
+ *
+ * Revision 1.36.2.3 2003/11/10 16:38:04 orjanf
+ * Unified Erasing/Writing messages
+ *
+ * Revision 1.36.2.2 2003/11/10 15:52:34 magnusmn
+ * More info on a sector basis
+ *
+ * Revision 1.36.2.1 2003/11/07 16:23:20 magnusmn
+ * o Only erase a flash sector if we need to, that is if the source content isn't already is in place.
+ * o Don't erase a flash sector that already contain ones.
+ * o Don't write ones to a (d)word that already contain ones.
+ * o If there are two flashes, switch flash after an erase operation is started on one of them.
+ * o Flash fill doesn't work yet.
+ * o No timeout implemented, we will continue to erase/program until we succeed.
+ * o Interleave not tested.
+ *
+ * Revision 1.36 2003/10/16 17:08:51 jonashg
+ * Bugfix: reversed CFI-tables wasn't handled correctly since regions support was
+ * merged.
+ *
+ * Revision 1.35 2003/10/14 13:43:41 pkj
+ * Fixed compiler warnings.
+ *
+ * Revision 1.34 2003/10/14 10:48:13 magnusmn
+ * No need to write ones to a (d)word where there already are ones. This will save time during flash programming.
+ *
+ * Revision 1.33 2003/10/10 11:46:25 jonashg
+ * Merged change_branch--regions_support.
+ *
+ * Revision 1.32.2.3 2003/10/10 09:38:13 jonashg
+ * Corrected calculation of current region and sector before erase.
+ *
+ * Revision 1.32.2.2 2003/10/09 16:31:26 jonashg
+ * Regions support in JEDEC probe.
+ *
+ * Revision 1.32.2.1 2003/09/19 15:28:22 jonashg
+ * Support for unusual region layouts. It only works for CFI compliant chips (yet).
+ *
+ * Revision 1.32 2002/12/13 15:55:54 jonashg
+ * Fix for ST M29W160ET. It seems to need a reset before erase (even though the
+ * probe functions did reset it).
+ *
+ * Revision 1.31 2002/07/01 14:37:25 pkj
+ * Merged with the ASIC version of e100boot. Main difference is that
+ * information about the executed commands are sent back to e100boot
+ * instead of being sent to the debug port. This means there is no
+ * longer any need to use different boot loaders for different
+ * debug ports.
+ *
+ * Revision 1.30 2002/06/26 13:28:29 pkj
+ * flash_write() can now be used to erase an area (by specifying
+ * source as NULL), and to fill an area with the first udword of
+ * source by setting do_fill to TRUE).
+ *
+ * Revision 1.29 2002/06/26 13:19:37 pkj
+ * * flash_write() now returns a status code.
+ * * timeout is now decremented correctly in flash_write_part() to
+ * actually be able to trigger the timeout message.
+ * * Fixed all compiler warnings.
+ *
+ * Revision 1.28 2002/06/20 12:58:18 pkj
+ * Changed svinto_boot.h to e100boot.h
+ *
+ * Revision 1.27 2002/06/19 14:00:29 pkj
+ * * Broke out the probing of the flash chips from flash_write()
+ * into flash_probe_chips().
+ * * flash_probe_chips() is not limited to two chips or that the
+ * first chip exists.
+ *
+ * Revision 1.26 2002/02/21 14:37:52 jonashg
+ * Optimized away my sanity. It's back now I think.
+ *
+ * Revision 1.25 2002/02/21 14:28:24 jonashg
+ * Added support for Atmel AT49?V16?T (had to optimize a bit to make room).
+ *
+ * Revision 1.24 2002/01/31 14:36:14 jonashg
+ * * Added support for Atmel AT49[BL]V16[01] (the chip used in the ETRAX MCM).
+ * * Replaced concurrent sector erase with sequential (we have found three
+ * different chips that cannot erase multiple sectors at the same time,
+ * one of the is the chip in the MCM). I haven't noticed any performance
+ * loss on chips (CFI and non-CFI) that can erase all sectors at the same
+ * time either (maybe they don't really erase them at the same time in
+ * hardware).
+ * * Added check for manufacturer id as well as device id (should have been
+ * done a long time ago).
+ *
+ * Revision 1.23 2001/11/21 15:52:44 jonashg
+ * Almost readable.
+ *
+ * Revision 1.22 2001/11/21 15:24:38 jonashg
+ * Increased readability and decreased size some 40bytes.
+ *
+ * Revision 1.21 2001/11/20 13:40:12 starvik
+ * Corrected handling for CFI capable bottom boot flashes
+ * Shorted some strings to make more space available
+ *
+ * Revision 1.20 2001/08/08 17:51:28 pkj
+ * Made it possible to flash at a start offset other than zero when
+ * there are more than one physical flash chip available. Previously
+ * it always started flashing from the start of the first flash if
+ * there were more than one, even though the start offset was set to
+ * something else...
+ *
+ * Revision 1.19 2001/06/19 14:51:17 jonashg
+ * Added support for non-CFI flash Toshiba TC58FVT800.
+ *
+ * Revision 1.18 2001/04/05 06:32:39 starvik
+ * Works with flashes with multiple banks
+ *
+ * Revision 1.17 2001/03/06 15:21:16 jonashg
+ * More output to user.
+ *
+ * Revision 1.16 2001/03/06 14:11:16 jonashg
+ * * Switch to second device correctly when flashing images that extend past the
+ * first device.
+ * * Only enter autoselect mode once saves a few bytes (not needed before reading
+ * device id, since it was done before reading manufacturer id).
+ * * A few unnecessary resets removed to save another few bytes.
+ *
+ * Revision 1.15 2001/02/28 14:52:43 jonashg
+ * * Reverted to old sector erase sequence (that was correct).
+ * * A bit of executable size optimization (a few hundred bytes).
+ * * Cleanup.
+ *
+ * Revision 1.14 2001/02/27 14:18:59 jonashg
+ * * Write full erase command sequence to all sectors that should be erased.
+ * * Write 16bit erase command to non-interleaved chips.
+ *
+ * Revision 1.13 2001/02/23 11:03:41 jonashg
+ * Added support for 2 x 16Mb flashes (32-bits buswidth).
+ * The CFI probe does not detect two parallel flash devices, but the normal
+ * probe does (it should be easy to add that in the CFI-probe, but I didn't
+ * have any hardware to try it on and the size of the executable is getting
+ * pretty close to the size of the ETRAX cache).
+ *
+ * Revision 1.12 2001/02/12 13:59:00 jonashg
+ * Bugfix: pointer arithmetics made bootsector calculation go wrong.
+ *
+ * Revision 1.11 2000/11/10 08:02:23 starvik
+ * Added CFI support
+ *
+ * Revision 1.10 2000/10/26 13:47:32 johana
+ * Added support for Fujitsu flash 16MBit (2MByte) MBM29LV160BE and MBM29LV160TE.
+ * NOT VERIFIED YET!
+ *
+ * Revision 1.9 2000/06/28 13:02:50 bjornw
+ * * Added support for SST39LF800 and SST39LF160 flashes
+ * * Fixed some indentation issues
+ *
+ * Revision 1.8 2000/06/13 11:51:11 starvik
+ * Support for two flashes. Second flash is erased and programmed if program
+ * is larger than first flash.
+ *
+ * Revision 1.7 2000/04/13 16:06:15 macce
+ * See if flash is empty before erasing it. Might save some production time.
+ *
+ * Revision 1.6 2000/01/27 17:52:07 bjornw
+ * * Added Toshiba flashes
+ * * Added proper bootblock erase for the different flashes
+ * (this caused the verify errors when trying to do ./flashitall before)
+ *
+ * Revision 1.5 2000/01/20 11:41:28 finn
+ * Improved the verify error printouts in flash_write.
+ *
+ * Revision 1.4 1999/12/21 19:32:53 bjornw
+ * Dont choke on full chip erases even though we dont implement it efficiently.
+ *
+ * Revision 1.3 1999/11/12 01:30:04 bjornw
+ * Added wait for busy to be ready. Removed some warnings.
+ *
+ * Revision 1.2 1999/10/27 07:42:42 johana
+ * Added support for ST M29W800T flash used in 5600
+ *
+ * Revision 1.1 1999/10/27 01:37:12 bjornw
+ * Wrote routines to erase and flash data into a flash ROM.
+ *
+ */
+
+#include "e100boot.h"
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define FDEBUG(x) x
+#else
+#define FDEBUG(x)
+#endif
+
+/* Try turning of some of these if you run into space problems. */
+#define CFI_PROBE
+#define JEDEC_PROBE
+#define INTERLEAVE
+
+#define TYPE_X16 (16 / 8)
+
+#define nop() __asm__("nop")
+
+#define safe_printk send_string
+
+static char *message_bottom_boot_8 = "8Mb BB";
+static char *message_top_boot_8 = "8Mb TB";
+static char *message_bottom_boot_16 = "16Mb BB";
+static char *message_top_boot_16 = "16Mb TB";
+static char *message_top_boot_32 = "32Mb TB";
+
+enum {
+ /* Addresses */
+ ADDR_UNLOCK_1 = 0x0555,
+ ADDR_UNLOCK_2 = 0x02AA,
+ ADDR_MANUFACTURER = 0x0000,
+ ADDR_DEVICE_ID = 0x0001,
+ ADDR_CFI_QUERY = 0x0055,
+
+ /* Commands */
+ CMD_UNLOCK_DATA_1 = 0x00AA,
+ CMD_UNLOCK_DATA_2 = 0x0055,
+ CMD_MANUFACTURER_UNLOCK_DATA = 0x0090,
+ CMD_PROGRAM_UNLOCK_DATA = 0x00A0,
+ CMD_RESET_DATA = 0x00F0,
+ CMD_SECTOR_ERASE_UNLOCK_DATA_1 = 0x0080,
+ CMD_SECTOR_ERASE_UNLOCK_DATA_2 = 0x0030,
+ CMD_CFI_QUERY_DATA = 0x0098,
+
+ /* Offsets */
+ OFFSET_CFI_ID = 0x10,
+ OFFSET_CFI_SIZE = 0x27,
+ OFFSET_CFI_BLOCK_COUNT = 0x2C,
+ OFFSET_CFI_BLOCK = 0x2D,
+
+ /* Manufacturers */
+ MANUFACTURER_AMD = 0x01,
+ MANUFACTURER_ATMEL = 0x1F,
+ MANUFACTURER_FUJITSU = 0x04,
+ MANUFACTURER_SST = 0xBF,
+ MANUFACTURER_ST = 0x20,
+ MANUFACTURER_TOSHIBA = 0x98,
+
+
+ /* To save precious space we store mfr and dev id together */
+
+ /* AMD devices */
+ AM29F800BB = 0x00012258,
+ AM29F800BT = 0x000122D6,
+ AM29LV800BB = 0x0001225B,
+ AM29LV800BT = 0x000122DA,
+ AM29LV160BT = 0x000122C4,
+
+ /* Atmel devices */
+ AT49xV16x = 0x001F00C0,
+ AT49xV16xT = 0x001F00C2,
+ AT49BV32xAT = 0x001F00C9,
+
+ /* Fujitsu devices */
+ MBM29LV160TE = 0x000422C4,
+ MBM29LV160BE = 0x00042249,
+
+ /* SST devices */
+ SST39LF800 = 0x00BF2781,
+ SST39LF160 = 0x00BF2782,
+
+ /* ST devices */
+ M29W800T = 0x002000D7, /* Used in 5600, similar
+ * to AM29LV800, but no
+ * unlock bypass
+ */
+ /* Toshiba devices */
+ TC58FVT160 = 0x009800C2,
+ TC58FVB160 = 0x00980043,
+ TC58FVT800 = 0x0098004F,
+
+ /* Toggle bit mask */
+ D6_MASK = 0x40
+};
+
+struct region {
+ unsigned long offset;
+ unsigned int sector_size;
+ unsigned int numsectors;
+};
+
+#define MAXREGIONS 8
+
+struct chip {
+ volatile unsigned char *base;
+#ifdef INTERLEAVE
+ byte interleave;
+ byte buswidth;
+#endif
+ unsigned int size;
+ unsigned short numregions;
+ struct region regions[MAXREGIONS];
+};
+
+/* Allocate flash structures and initialize base. */
+static struct chip chips[2] = {
+ { (unsigned char *)0x80000000,
+#ifdef INTERLEAVE
+ 0, 0,
+#endif
+ 0, 0, { } },
+ { (unsigned char *)0x84000000,
+#ifdef INTERLEAVE
+ 0, 0,
+#endif
+ 0, 0, { } }
+};
+
+
+
+static unsigned int
+wide_read(struct chip *flash, unsigned long offset)
+{
+#ifdef INTERLEAVE
+ switch (flash->buswidth) {
+ case 2:
+#endif
+ return *((uword *)(flash->base + offset));
+
+#ifdef INTERLEAVE
+ case 4:
+ return *((udword *)(flash->base + offset));
+ }
+
+ return 0;
+#endif
+}
+
+static int
+wide_write_chunk(struct chip *flash, unsigned long offset, const void *chunk)
+{
+#ifdef INTERLEAVE
+ switch (flash->buswidth) {
+ case 2:
+#endif
+ *((uword *)(flash->base + offset)) = *((uword *)chunk);
+ return 2;
+
+#ifdef INTERLEAVE
+ case 4:
+ *((udword *)(flash->base + offset)) = *((udword *)chunk);
+ return 4;
+ }
+
+ return 0;
+#endif
+}
+
+static void
+wide_cmd(struct chip *flash, udword cmd, unsigned long offset)
+{
+#ifdef INTERLEAVE
+ if (flash->interleave == 1) {
+#endif
+ offset <<= 1;
+#ifdef INTERLEAVE
+ } else if (flash->interleave == 2) {
+ cmd |= (cmd << 16);
+ offset <<= 2;
+ } else {
+ safe_printk("Unsupported interleave!\n");
+ return;
+ }
+#endif
+
+ wide_write_chunk(flash, offset, &cmd);
+}
+
+static void
+flash_unlock(struct chip *flash)
+{
+ wide_cmd(flash, CMD_UNLOCK_DATA_1, ADDR_UNLOCK_1);
+ wide_cmd(flash, CMD_UNLOCK_DATA_2, ADDR_UNLOCK_2);
+}
+
+static int
+flash_is_busy(struct chip *flash, unsigned long offset)
+{
+#ifdef INTERLEAVE
+ if (flash->interleave == 2) {
+ udword read1, read2;
+
+ read1 = wide_read(flash, offset);
+ read2 = wide_read(flash, offset);
+ return (((read1 >> 16) & D6_MASK) !=
+ ((read2 >> 16) & D6_MASK)) ||
+ (((read1 & 0xffff) & D6_MASK) !=
+ ((read2 & 0xffff) & D6_MASK));
+ }
+#endif
+
+ return ((wide_read(flash, offset) & D6_MASK) !=
+ (wide_read(flash, offset) & D6_MASK));
+}
+
+
+
+#ifdef CFI_PROBE
+static int
+try_cfi(struct chip *flash)
+{
+ int offset_shift = 1;
+
+#ifdef INTERLEAVE
+ if (flash->interleave == 2) {
+ offset_shift = 2;
+ }
+#endif
+
+ /* Enter CFI mode */
+ wide_cmd(flash, CMD_CFI_QUERY_DATA, ADDR_CFI_QUERY);
+
+ /* Check if flash responds correctly */
+ if ((byte)wide_read(flash, (OFFSET_CFI_ID+0) << offset_shift) == 'Q' &&
+ (byte)wide_read(flash, (OFFSET_CFI_ID+1) << offset_shift) == 'R' &&
+ (byte)wide_read(flash, (OFFSET_CFI_ID+2) << offset_shift) == 'Y') {
+ int block; /* Current block */
+ int block_count; /* Number of blocks */
+ unsigned int offset = 0; /* Offset into flash */
+ int reverse = 0; /* Reverse block table */
+ int primary; /* Offset to vendor specific table */
+
+ safe_printk("Found 1 x CFI at ");
+ send_hex((udword)flash->base, NL);
+
+ flash->size =
+ 1 << wide_read(flash, OFFSET_CFI_SIZE << offset_shift);
+
+ /* CFI stores flash organization in blocks. Each block contains
+ * a number of sectors with the same size
+ */
+ block_count = wide_read(flash, OFFSET_CFI_BLOCK_COUNT <<
+ offset_shift);
+
+ /* Check if table is reversed */
+ primary = wide_read(flash, (OFFSET_CFI_ID+5) << offset_shift);
+ /* For CFI version 1.0 we don't know. Assume that id & 0x80 */
+ /* indicates top boot */
+ if ((byte)wide_read(flash, (primary+4) << offset_shift) == 0x30)
+ {
+ /* read device id */
+ wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
+ flash_unlock(flash);
+ wide_cmd(flash, CMD_MANUFACTURER_UNLOCK_DATA,
+ ADDR_UNLOCK_1);
+ reverse = wide_read(flash, ADDR_DEVICE_ID * TYPE_X16
+#ifdef INTERLEAVE
+ * flash->interleave
+#endif
+ ) & 0x80;
+ wide_cmd(flash, CMD_CFI_QUERY_DATA, ADDR_CFI_QUERY);
+ } else {
+ reverse = ((byte)wide_read(flash,
+ (primary+15) << offset_shift) == 3);
+ }
+
+ flash->numregions = block_count;
+ if (block_count > MAXREGIONS) {
+ safe_printk("Too many regions on chip!\n");
+ return 0;
+ }
+
+ /* Blocks are stored backwards compared to flash organization */
+ for (block = reverse ? block_count - 1 : 0;
+ reverse ? block >= 0 : block < block_count;
+ reverse ? block-- : block++) {
+ int region;
+
+ /* Size of each sector in block. Size is stored as
+ * sector_size / 256.
+ */
+ int sector_size =
+ (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+2) <<
+ offset_shift)
+ |
+ (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+3) <<
+ offset_shift) << 8)
+ ) << 8;
+
+ /* Number of sectors */
+ int sector_count =
+ (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+0) <<
+ offset_shift)
+ |
+ (wide_read(flash, (OFFSET_CFI_BLOCK+block * 4+1) <<
+ offset_shift) << 8)
+ ) + 1;
+
+ region = reverse? block_count - 1 - block : block;
+ flash->regions[region].offset = offset;
+ flash->regions[region].sector_size = sector_size;
+ flash->regions[region].numsectors = sector_count;
+
+ /* Can't use multiplication (we have no lib). */
+ {
+ int temp;
+ for (temp = 0 ; temp < sector_count ; temp++) {
+ offset += sector_size;
+ }
+ }
+
+FDEBUG(
+ if (reverse) {
+ safe_printk("NOTE! reversed table:\n");
+ }
+ safe_printk("region: ");
+ send_hex((udword)region, NL);
+ safe_printk(" offset: ");
+ send_hex((udword)flash->regions[region].offset, NL);
+ safe_printk(" sector_size: ");
+ send_hex((udword)flash->regions[region].sector_size, NL);
+ safe_printk(" numsectors: ");
+ send_hex((udword)flash->regions[region].numsectors, NL);
+)
+
+ /* Some flashes (SST) store information about alternate
+ * block sizes. Ignore those by breaking when the sum
+ * of the sector sizes == flash size.
+ */
+ if (offset == flash->size) {
+ break;
+ }
+ }
+
+ /* reset */
+ wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
+
+ return 1;
+ }
+
+ /* reset */
+ wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
+
+ return 0;
+}
+#endif
+
+
+
+static int
+flash_probe(struct chip *flash)
+{
+ char *message;
+ udword dev_id;
+ udword mfr_id;
+ udword id;
+
+ if (flash->size
+#ifdef CFI_PROBE
+ || try_cfi(flash)
+#endif
+ ) {
+ return 1;
+ }
+
+#ifdef JEDEC_PROBE
+ /* Read manufacturer ID. */
+ flash_unlock(flash);
+ wide_cmd(flash, CMD_MANUFACTURER_UNLOCK_DATA, ADDR_UNLOCK_1);
+ mfr_id = wide_read(flash, ADDR_MANUFACTURER * TYPE_X16
+#ifdef INTERLEAVE
+ * flash->interleave
+#endif
+ );
+ /* Read device ID. */
+ dev_id = wide_read(flash, ADDR_DEVICE_ID * TYPE_X16
+#ifdef INTERLEAVE
+ * flash->interleave
+#endif
+ );
+FDEBUG(
+ safe_printk("mfr_id: ");
+ send_hex(mfr_id, NL);
+ safe_printk("dev_id: ");
+ send_hex(dev_id, NL);
+)
+
+#ifdef INTERLEAVE
+ if ((flash->interleave == 2) &&
+ ((mfr_id >> 16) == (mfr_id & 0xffff)) &&
+ ((dev_id >> 16) == (dev_id & 0xffff))) {
+ mfr_id &= 0xffff;
+ dev_id &= 0xffff;
+ }
+#endif
+
+ id = (mfr_id << 16) | dev_id;
+
+ /* reset */
+ wide_cmd(flash, CMD_RESET_DATA, ADDR_UNLOCK_1);
+
+ /* Check device type and fill in correct sizes. */
+ switch (id) {
+ case AM29LV160BT:
+ case TC58FVT160:
+ // case MBM29LV160TE: /* This is same id as AM29LV160BT */
+ message = message_top_boot_16;
+
+ flash->size = 0x00200000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x10000;
+ flash->regions[0].numsectors = 31;
+
+ flash->regions[1].offset = 0x001F0000;
+ flash->regions[1].sector_size = 0x08000;
+ flash->regions[1].numsectors = 1;
+
+ flash->regions[2].offset = 0x001F8000;
+ flash->regions[2].sector_size = 0x02000;
+ flash->regions[2].numsectors = 2;
+
+ flash->regions[3].offset = 0x001FC000;
+ flash->regions[3].sector_size = 0x04000;
+ flash->regions[3].numsectors = 1;
+ break;
+
+ // case AM29LV160BB:
+ case TC58FVB160:
+ case MBM29LV160BE:
+ message = message_bottom_boot_16;
+
+ flash->size = 0x00200000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x04000;
+ flash->regions[0].numsectors = 1;
+
+ flash->regions[1].offset = 0x00004000;
+ flash->regions[1].sector_size = 0x02000;
+ flash->regions[1].numsectors = 2;
+
+ flash->regions[2].offset = 0x00008000;
+ flash->regions[2].sector_size = 0x08000;
+ flash->regions[2].numsectors = 1;
+
+ flash->regions[3].offset = 0x00010000;
+ flash->regions[3].sector_size = 0x10000;
+ flash->regions[3].numsectors = 31;
+ break;
+
+ case AM29LV800BB:
+ case AM29F800BB:
+ message = message_bottom_boot_8;
+
+ flash->size = 0x00100000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x04000;
+ flash->regions[0].numsectors = 1;
+
+ flash->regions[1].offset = 0x00004000;
+ flash->regions[1].sector_size = 0x02000;
+ flash->regions[1].numsectors = 2;
+
+ flash->regions[2].offset = 0x00008000;
+ flash->regions[2].sector_size = 0x08000;
+ flash->regions[2].numsectors = 1;
+
+ flash->regions[3].offset = 0x00010000;
+ flash->regions[3].sector_size = 0x10000;
+ flash->regions[3].numsectors = 15;
+ break;
+
+ case M29W800T:
+ case AM29LV800BT:
+ case AM29F800BT:
+ case TC58FVT800:
+ message = message_top_boot_8;
+
+ flash->size = 0x00100000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x10000;
+ flash->regions[0].numsectors = 15;
+
+ flash->regions[1].offset = 0x000F0000;
+ flash->regions[1].sector_size = 0x08000;
+ flash->regions[1].numsectors = 1;
+
+ flash->regions[2].offset = 0x000F8000;
+ flash->regions[2].sector_size = 0x02000;
+ flash->regions[2].numsectors = 2;
+
+ flash->regions[3].offset = 0x000FC000;
+ flash->regions[3].sector_size = 0x04000;
+ flash->regions[3].numsectors = 1;
+
+ break;
+
+ case AT49xV16x:
+ message = message_bottom_boot_16;
+
+ flash->size = 0x00200000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x02000;
+ flash->regions[0].numsectors = 8;
+
+ flash->regions[1].offset = 0x00010000;
+ flash->regions[1].sector_size = 0x10000;
+ flash->regions[1].numsectors = 31;
+
+ break;
+
+ case AT49xV16xT:
+ message = message_top_boot_16;
+
+ flash->size = 0x00200000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x10000;
+ flash->regions[0].numsectors = 31;
+
+ flash->regions[1].offset = 0x001F0000;
+ flash->regions[1].sector_size = 0x02000;
+ flash->regions[1].numsectors = 8;
+
+ break;
+
+ case AT49BV32xAT:
+ message = message_top_boot_32;
+
+ flash->size = 0x00400000;
+
+ flash->regions[0].offset = 0x00000000;
+ flash->regions[0].sector_size = 0x10000;
+ flash->regions[0].numsectors = 63;
+
+ flash->regions[1].offset = 0x001F0000;
+ flash->regions[1].sector_size = 0x02000;
+ flash->regions[1].numsectors = 8;
+
+ break;
+
+ default:
+#endif
+#ifdef INTERLEAVE
+ if (flash->interleave == 1) {
+#endif
+ safe_printk("No single x16 at ");
+#ifdef INTERLEAVE
+ } else {
+ safe_printk("No interleaved x16 at ");
+ }
+#endif
+ send_hex((udword)flash->base, NL);
+
+ return 0;
+#ifdef JEDEC_PROBE
+ }
+
+ safe_printk("Found ");
+#ifdef INTERLEAVE
+ if (flash->interleave == 1) {
+#endif
+ safe_printk("1");
+#ifdef INTERLEAVE
+ }
+ if (flash->interleave == 2) {
+ int count = 0;
+
+ flash->size <<= 1;
+ while (count < MAXREGIONS) {
+ flash->regions[count].offset <<= 1;
+ flash->regions[count].sector_size <<= 1;
+ count++;
+ }
+ safe_printk("2");
+ }
+#endif
+ safe_printk(" x ");
+ safe_printk(message);
+ safe_printk(" at ");
+ send_hex((udword)flash->base, NL);
+
+ return 1;
+#endif
+}
+
+/* Start erase of a sector but do no wait for completion */
+static void
+start_sector_erase(struct chip *flash, unsigned long offset)
+{
+ flash_unlock(flash);
+ wide_cmd(flash, CMD_SECTOR_ERASE_UNLOCK_DATA_1, ADDR_UNLOCK_1);
+ flash_unlock(flash);
+
+#ifdef INTERLEAVE
+ if (flash->interleave == 2) {
+ *(udword *)(flash->base+offset) = (CMD_SECTOR_ERASE_UNLOCK_DATA_2 << 16) |
+ CMD_SECTOR_ERASE_UNLOCK_DATA_2;
+ } else {
+#endif
+ *(uword *)(flash->base+offset) = CMD_SECTOR_ERASE_UNLOCK_DATA_2;
+#ifdef INTERLEAVE
+ }
+#endif
+}
+
+/* Return the size of the sector at the given offset */
+static int
+find_sector_size(struct chip *flash, unsigned long offset)
+{
+ unsigned int i, j;
+ int region_size;
+ /* Sanity check */
+ if (offset >= flash->size)
+ return 0;
+
+ for(i=0; i < MAXREGIONS; i++)
+ if (offset >= flash->regions[i].offset) {
+ region_size=0;
+ for (j=0; j < flash->regions[i].numsectors; j++)
+ region_size += flash->regions[i].sector_size;
+ if (offset < flash->regions[i].offset + region_size)
+ return flash->regions[i].sector_size;
+ }
+
+ /* Should not happen */
+ return 0;
+}
+
+/* Check and see if we need to erase the sector */
+/* The return values mean */
+/* 0: The source and destination are the same. */
+/* 1: The source and destination are not the same, but flash sector already contains only ones. */
+/* 2: The source and destination are not the same and the flash sector is tainted by some zeroes. */
+static char
+need_to_erase(struct chip *flash, unsigned long offset, const unsigned char *source, int size)
+{
+ int i;
+ unsigned long j;
+
+ for (i = 0; i < size; i+=2)
+ if (*(uword*)(flash->base + i + offset) != *(uword*)(source + i)) {
+ /* Check if the sector only contain zeroes */
+ for (j = offset; j < (size + offset); j+=2) {
+ if (*(uword*)(flash->base + j) != 0xffff)
+ return 2;
+ }
+ return 1;
+ }
+
+ /* The source is equal to the destination */
+ return 0;
+}
+
+static unsigned int
+flash_probe_chips(void)
+{
+ unsigned int tot_size = 0;
+ unsigned int i = 0;
+
+ for (; i < sizeof chips/sizeof *chips; i++) {
+#ifdef INTERLEAVE
+ byte interleave;
+
+ for (interleave = 1; interleave < 4; interleave *= 2) {
+ chips[i].interleave = interleave;
+ if (interleave == 1) {
+ chips[i].buswidth = sizeof(uword);
+ } else {
+ chips[i].buswidth = sizeof(udword);
+ }
+
+ if (flash_probe(&chips[i])) {
+ break;
+ }
+ }
+#else
+ flash_probe(&chips[i]);
+#endif
+
+ tot_size += chips[i].size;
+ }
+
+ return tot_size;
+}
+
+/* Program a sector (given by size) at the given offset. Do not write only ones. */
+static void
+program_sector(struct chip *flash, unsigned long offset, const unsigned char *source, int size)
+{
+ int chunk_size = 0;
+ int bytes_written = 0;
+
+
+ while (bytes_written < size) {
+ if (
+#ifdef INTERLEAVE
+ (flash->buswidth == 2) &&
+#endif
+ *(uword*)(source + bytes_written) == 0xffff) {
+ chunk_size=2;
+ }
+#ifdef INTERLEAVE
+ else if ((flash->buswidth == 4) && *(udword*)(source + bytes_written) == 0xffffffff) {
+ chunk_size=4;
+ }
+#endif
+ else {
+ flash_unlock(flash);
+ wide_cmd(flash, CMD_PROGRAM_UNLOCK_DATA, ADDR_UNLOCK_1);
+ chunk_size = wide_write_chunk(flash, offset + bytes_written, source + bytes_written);
+ while(flash_is_busy(flash, offset + bytes_written))
+ /* Nothing */
+ ;
+ }
+
+ bytes_written += chunk_size;
+ }
+}
+
+int
+flash_write(const unsigned char *source, unsigned int offset, unsigned int size)
+{
+ struct flash_status {
+ unsigned char busy; /* Indicates if the flash is busy */
+ const unsigned char *src; /* From where to get the source info */
+ unsigned long offset; /* Start operations in flash at this offset */
+ unsigned int size; /* Size to erase/program (if needed) */
+ unsigned int bytes_done; /* Bytes written (if needed) */
+ unsigned int erase_attempts; /* Keep track how many times we try to erase the same sector */
+ };
+
+ unsigned int tot_size = flash_probe_chips();
+ unsigned int i, j;
+ unsigned int current_sector_size;
+ unsigned long current_offset;
+ const unsigned char *current_src;
+ char need_erase;
+ struct flash_status *current_flash = NULL;
+
+ static struct flash_status flash_status[2] = {
+ { 0, NULL, 0, 0, 0, 0 },
+ { 0, NULL, 0, 0, 0, 0 }
+ };
+
+ if (!tot_size) {
+ /* No chips found, bail out. */
+ return ERR_FLASH_NONE;
+ }
+
+ if (offset + size > tot_size) {
+ safe_printk("Fatal: flash is too small.\n");
+ return ERR_FLASH_TOO_SMALL;
+ }
+
+ /* Initiate the flash_status structs so that we can keep track of what needs to be done
+ on the different flash chips */
+
+ /* Operations only on flash chip 1 */
+ if (offset >= (&chips[0])->size) {
+ flash_status[0].size = 0;
+ flash_status[1].src = source;
+ flash_status[1].offset = offset - (&chips[0])->size;
+ flash_status[1].size = size;
+ }
+ /* Operations on both flash chips */
+ else if ((offset < (&chips[0])->size) && ((offset+size) > (&chips[0])->size)) {
+ flash_status[0].src = source;
+ flash_status[0].offset = offset;
+ flash_status[0].size = (&chips[0])->size - offset;
+ flash_status[1].src = source + flash_status[0].size;
+ flash_status[1].offset = 0;
+ flash_status[1].size = size - flash_status[0].size;
+ }
+ /* Operations only on flash chip 0 */
+ else {
+ flash_status[0].src = source;
+ flash_status[0].offset = offset;
+ flash_status[0].size = size;
+ flash_status[1].size = 0;
+ }
+ flash_status[0].busy = 0;
+ flash_status[0].bytes_done = 0;
+ flash_status[0].erase_attempts = 0;
+ flash_status[1].busy = 0;
+ flash_status[1].bytes_done = 0;
+ flash_status[1].erase_attempts = 0;
+#if 0
+ for (i = 0; i < 2; i++) {
+ safe_printk("\nFlash ");
+ send_hex(i, NL);
+ safe_printk("src:\t");
+ send_hex((int)flash_status[i].src, NL);
+ safe_printk("offset:\t");
+ send_hex(flash_status[i].offset, NL);
+ safe_printk("size:\t");
+ send_hex(flash_status[i].size, NL);
+ safe_printk("\n");
+ }
+#endif
+
+ /* Erase and write */
+
+ i = 0; /* Start operations on flash 0 */
+
+#define CHANGE_FLASH
+
+ while (((&flash_status[0])->bytes_done + (&flash_status[1])->bytes_done) < size) {
+
+ struct flash_status *previous_flash = &flash_status[i ? 0 : 1];
+ current_flash = &flash_status[i];
+
+#ifdef CHANGE_FLASH
+ /* Change flash only if:
+ - There is a flash to change to and operations should be made on that flash *AND*
+ - There is more to write to the previous flash *AND*
+ - Operations should be made on the current flash *OR*
+ - The current flash is busy *OR*
+ - All has been written to the current flash */
+
+ if (previous_flash->size && (previous_flash->bytes_done < previous_flash->size) &&
+ (!current_flash->size || current_flash->busy ||
+ current_flash->bytes_done == current_flash->size))
+ i = i ? 0 : 1; /* Change flash chip */
+#else
+ /* Finish one flash chip before continuing on the next one */
+
+ if ((&flash_status[i])->bytes_done == (&flash_status[i])->size)
+ i = i ? 0 : 1; /* Change flash chip */
+#endif
+ /* Bail out if we have tried to erase the same sector more that 10 times. */
+ if(current_flash->erase_attempts > 10) {
+ safe_printk("Sector erase error\n");
+ return ERR_FLASH_ERASE;
+ }
+
+ /* Get the current status from the chip we are about to access */
+ current_flash = &flash_status[i];
+ current_offset = current_flash->offset + current_flash->bytes_done;
+ current_src = current_flash->src + current_flash->bytes_done;
+ current_sector_size = find_sector_size(&chips[i], current_offset);
+
+ /* Make sure that the chip we are about to access has finished erasing */
+ if (current_flash->busy) {
+ while (flash_is_busy(&chips[i], current_offset))
+ /* nothing */
+ ;
+ current_flash->busy = 0;
+ }
+
+ /* Some flash chip need a reset to bring them back to read mode again. */
+ wide_cmd(&chips[i], CMD_RESET_DATA, ADDR_UNLOCK_1);
+
+ /* Find out if we need to erase the sector or not */
+ need_erase = need_to_erase(&chips[i], current_offset, current_src, current_sector_size);
+
+ if (need_erase == 0) {
+ current_flash->bytes_done += current_sector_size;
+ current_flash->erase_attempts = 0;
+ send_hex((int)(&chips[i])->base + current_offset, 0);
+ safe_printk(": No need to write\n");
+ continue;
+ } else if (need_erase == 1) {
+ /* Erased, not worth printing. */
+ }
+ else if (need_erase == 2) {
+ send_hex((int)(&chips[i])->base + current_offset, 0);
+ safe_printk(": Erasing ");
+ send_hex(current_sector_size, 0);
+ safe_printk(" bytes\n");
+ start_sector_erase(&chips[i], current_offset);
+ current_flash->busy=1;
+ current_flash->erase_attempts++;
+ continue;
+ }
+
+ /* The sector is ready to be programmed */
+ send_hex((int)(&chips[i])->base + current_offset, 0);
+ safe_printk(": Writing ");
+ send_hex(current_sector_size, 0);
+ safe_printk(" bytes\n");
+ program_sector(&chips[i], current_offset, current_src, current_sector_size);
+ current_flash->bytes_done += current_sector_size;
+ current_flash->erase_attempts = 0;
+ }
+
+ /* Verify that the flash chip(s) have the correct content */
+ for (i = 0; i < 2; i++) {
+ current_flash = &flash_status[i];
+ if (!current_flash->size)
+ continue;
+ send_hex((int)(&chips[i])->base, 0);
+ safe_printk(": Verifying...");
+ for (j = 0; j < current_flash->size; j+=2) {
+ if (*(uword*)(current_flash->offset + j + (&chips[i])->base) !=
+ *(uword*)(current_flash->src + j)) {
+ safe_printk("Error at ");
+ send_hex(j, NL);
+ return ERR_FLASH_VERIFY;
+ }
+ }
+ safe_printk("OK\n");
+ }
+
+ return ERR_FLASH_OK;
+}
--- /dev/null
+/*!**********************************************************************
+*!
+*! FILE NAME: hwregs.c
+*!
+*! DESCRIPTION: Shadow register and initiated flag variables,
+*! and a function for initialization of these variables.
+*!
+*!
+*! FUNCTIONS: void init_shadow__hwregs( void )
+*!
+*! NOTE: This file is automatically generated, do _not_ edit.
+*! Created: Thu Oct 3 01:21:27 2002
+*! By: Id: shadow_gen,v 1.14 2002/10/02 20:31:22 hp Exp
+*! From: /n/asic/projects/etrax_ng/doc/work/etrax_ng_regs.rd 1.168
+*! /n/asic/projects/etrax_ng/include//hwregs.ctrl 1.3
+*!
+*! NOTE: init_shadow__hwregs() initiate all write only registers
+*! described in /n/asic/projects/etrax_ng/doc/work/etrax_ng_regs.rd.
+*! Since one physical register may have several logical names you
+*! must choose which of the logical registers to initiate.
+*! This is done by the 'USE_GROUP__group-name' macro in the
+*! hwregs_def.h file.
+*!
+*! As an example, in Etrax100 the following logical registers are
+*! all the same physical register at address 0xb0000044:
+*!
+*! R_ATA_CONFIG
+*! R_PAR0_CONFIG
+*! R_SCSI0_CTRL
+*! R_SHARED_RAM_ADDR
+*!
+*!----------------------------------------------------------------------
+*! HISTORY
+*!
+*! DATE NAME CHANGES
+*! ---- ---- -------
+*! Apr 01 1998 Jan Bengtsson Initial version
+*!----------------------------------------------------------------------
+*!
+*! (C) Copyright 1998, Axis Communications AB, LUND, SWEDEN
+*!
+*!**********************************************************************/
+/* %Z% %M% %I% %G% */
+
+/********************** INCLUDE FILES SECTION **************************/
+
+#include "compiler.h"
+#include "hwregs.h"
+
+#if REG_DEBUG
+#include <string.h>
+#endif
+
+/********************** CONSTANT AND MACRO SECTION *********************/
+
+/********************** TYPE DEFINITION SECTION ************************/
+
+/********************** LOCAL FUNCTION DECLARATION SECTION *************/
+
+/********************** GLOBAL VARIABLE DECLARATION SECTION ************/
+
+#ifndef REG_NO_SHADOW
+/* Shadows for write only registers. */
+reg_shadow_type__hwregs reg_shadow__hwregs;
+#else
+/* Use constant zero as shadow when there isn't a shadow register. */
+reg_shadow_type__hwregs reg_shadow__hwregs = 0;
+#endif
+
+#if REG_DEBUG
+#ifndef REG_NO_SHADOW
+/* Initiated flags for shadow registers. */
+reg_initiated_type__hwregs reg_initiated__hwregs;
+#else
+/* No need for initiated flags when there isn't a shadow register. */
+reg_initiated_type__hwregs reg_initiated__hwregs = 0;
+#endif
+#endif
+
+/********************** FUNCTION DEFINITION SECTION ********************/
+
+/*#**********************************************************************
+*#
+*# FUNCTION NAME: init_shadow__hwregs
+*#
+*# PARAMETERS : none
+*#
+*# RETURNS : nothing
+*#
+*# SIDE EFFECTS : Writes initial values to all write only registers
+*# and their associated shadow registers. If REG_DEBUG
+*# is non zero the reg_initiated struct is also initiated.
+*#
+*# DESCRIPTION : Initiate write only registers, their shadows, and in
+*# debug mode the initiated flags. Default values for
+*# the initialization are defined in hwregs_def.h.
+*#
+*# Note that one physical register may have several
+*# logical names, and that you have to modify this
+*# function to only initiate the physical register once!
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*#
+*#**********************************************************************/
+
+void init_shadow__hwregs( void )
+{
+#if REG_DEBUG && !defined(REG_NO_SHADOW)
+ /* Initiate reg_initiated__hwregs struct to 0xff. */
+ memset( ®_initiated__hwregs, 0xff, sizeof(reg_initiated_type__hwregs) );
+#endif
+
+#ifndef REG_NO_INIT_SHADOW
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_ALT_SER_BAUDRATE(
+ ser3_tr, R_ALT_SER_BAUDRATE__ser3_tr__DEFAULT,
+ ser3_rec, R_ALT_SER_BAUDRATE__ser3_rec__DEFAULT,
+ ser2_tr, R_ALT_SER_BAUDRATE__ser2_tr__DEFAULT,
+ ser2_rec, R_ALT_SER_BAUDRATE__ser2_rec__DEFAULT,
+ ser1_tr, R_ALT_SER_BAUDRATE__ser1_tr__DEFAULT,
+ ser1_rec, R_ALT_SER_BAUDRATE__ser1_rec__DEFAULT,
+ ser0_tr, R_ALT_SER_BAUDRATE__ser0_tr__DEFAULT,
+ ser0_rec, R_ALT_SER_BAUDRATE__ser0_rec__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__ATA_interface_registers
+ REG_SET__R_ATA_CONFIG(
+ enable, R_ATA_CONFIG__enable__DEFAULT,
+ dma_strobe, R_ATA_CONFIG__dma_strobe__DEFAULT,
+ dma_hold, R_ATA_CONFIG__dma_hold__DEFAULT,
+ pio_setup, R_ATA_CONFIG__pio_setup__DEFAULT,
+ pio_strobe, R_ATA_CONFIG__pio_strobe__DEFAULT,
+ pio_hold, R_ATA_CONFIG__pio_hold__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__ATA_interface_registers
+ REG_SET__R_ATA_CTRL_DATA(
+ sel, R_ATA_CTRL_DATA__sel__DEFAULT,
+ cs1, R_ATA_CTRL_DATA__cs1__DEFAULT,
+ cs0, R_ATA_CTRL_DATA__cs0__DEFAULT,
+ addr, R_ATA_CTRL_DATA__addr__DEFAULT,
+ rw, R_ATA_CTRL_DATA__rw__DEFAULT,
+ src_dst, R_ATA_CTRL_DATA__src_dst__DEFAULT,
+ handsh, R_ATA_CTRL_DATA__handsh__DEFAULT,
+ multi, R_ATA_CTRL_DATA__multi__DEFAULT,
+ dma_size, R_ATA_CTRL_DATA__dma_size__DEFAULT,
+ data, R_ATA_CTRL_DATA__data__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Bus_interface_configuration_registers
+ REG_SET__R_BUS_CONFIG(
+ sram_type, R_BUS_CONFIG__sram_type__DEFAULT,
+ dma_burst, R_BUS_CONFIG__dma_burst__DEFAULT,
+ pcs4_7_wr, R_BUS_CONFIG__pcs4_7_wr__DEFAULT,
+ pcs0_3_wr, R_BUS_CONFIG__pcs0_3_wr__DEFAULT,
+ sram_wr, R_BUS_CONFIG__sram_wr__DEFAULT,
+ flash_wr, R_BUS_CONFIG__flash_wr__DEFAULT,
+ pcs4_7_bw, R_BUS_CONFIG__pcs4_7_bw__DEFAULT,
+ pcs0_3_bw, R_BUS_CONFIG__pcs0_3_bw__DEFAULT,
+ sram_bw, R_BUS_CONFIG__sram_bw__DEFAULT,
+ flash_bw, R_BUS_CONFIG__flash_bw__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Timer_registers
+ REG_SET__R_CLOCK_PRESCALE(
+ ser_presc, R_CLOCK_PRESCALE__ser_presc__DEFAULT,
+ tim_presc, R_CLOCK_PRESCALE__tim_presc__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH0_CLR_INTR(
+ clr_eop, R_DMA_CH0_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH0_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH1_CLR_INTR(
+ clr_eop, R_DMA_CH1_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH1_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH2_CLR_INTR(
+ clr_eop, R_DMA_CH2_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH2_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH3_CLR_INTR(
+ clr_eop, R_DMA_CH3_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH3_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH4_CLR_INTR(
+ clr_eop, R_DMA_CH4_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH4_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH5_CLR_INTR(
+ clr_eop, R_DMA_CH5_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH5_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH6_CLR_INTR(
+ clr_eop, R_DMA_CH6_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH6_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH7_CLR_INTR(
+ clr_eop, R_DMA_CH7_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH7_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH8_CLR_INTR(
+ clr_eop, R_DMA_CH8_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH8_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH8_SUB0_CLR_INTR(
+ clr_descr, R_DMA_CH8_SUB0_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH8_SUB1_CLR_INTR(
+ clr_descr, R_DMA_CH8_SUB1_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH8_SUB2_CLR_INTR(
+ clr_descr, R_DMA_CH8_SUB2_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH8_SUB3_CLR_INTR(
+ clr_descr, R_DMA_CH8_SUB3_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_DMA_CH9_CLR_INTR(
+ clr_eop, R_DMA_CH9_CLR_INTR__clr_eop__DEFAULT,
+ clr_descr, R_DMA_CH9_CLR_INTR__clr_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Bus_interface_configuration_registers
+ REG_SET__R_DRAM_CONFIG(
+ wmm1, R_DRAM_CONFIG__wmm1__DEFAULT,
+ wmm0, R_DRAM_CONFIG__wmm0__DEFAULT,
+ sh1, R_DRAM_CONFIG__sh1__DEFAULT,
+ sh0, R_DRAM_CONFIG__sh0__DEFAULT,
+ w, R_DRAM_CONFIG__w__DEFAULT,
+ c, R_DRAM_CONFIG__c__DEFAULT,
+ e, R_DRAM_CONFIG__e__DEFAULT,
+ group_sel, R_DRAM_CONFIG__group_sel__DEFAULT,
+ ca1, R_DRAM_CONFIG__ca1__DEFAULT,
+ bank23sel, R_DRAM_CONFIG__bank23sel__DEFAULT,
+ ca0, R_DRAM_CONFIG__ca0__DEFAULT,
+ bank01sel, R_DRAM_CONFIG__bank01sel__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Bus_interface_configuration_registers
+ REG_SET__R_DRAM_TIMING(
+ sdram, R_DRAM_TIMING__sdram__DEFAULT,
+ ref, R_DRAM_TIMING__ref__DEFAULT,
+ rp, R_DRAM_TIMING__rp__DEFAULT,
+ rs, R_DRAM_TIMING__rs__DEFAULT,
+ rh, R_DRAM_TIMING__rh__DEFAULT,
+ w, R_DRAM_TIMING__w__DEFAULT,
+ c, R_DRAM_TIMING__c__DEFAULT,
+ cz, R_DRAM_TIMING__cz__DEFAULT,
+ cp, R_DRAM_TIMING__cp__DEFAULT,
+ cw, R_DRAM_TIMING__cw__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__External_DMA_registers
+ REG_SET__R_EXT_DMA_0_ADDR(
+ ext0_addr, R_EXT_DMA_0_ADDR__ext0_addr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__External_DMA_registers
+ REG_SET__R_EXT_DMA_0_CMD(
+ cnt, R_EXT_DMA_0_CMD__cnt__DEFAULT,
+ rqpol, R_EXT_DMA_0_CMD__rqpol__DEFAULT,
+ apol, R_EXT_DMA_0_CMD__apol__DEFAULT,
+ rq_ack, R_EXT_DMA_0_CMD__rq_ack__DEFAULT,
+ wid, R_EXT_DMA_0_CMD__wid__DEFAULT,
+ dir, R_EXT_DMA_0_CMD__dir__DEFAULT,
+ run, R_EXT_DMA_0_CMD__run__DEFAULT,
+ trf_count, R_EXT_DMA_0_CMD__trf_count__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__External_DMA_registers
+ REG_SET__R_EXT_DMA_1_ADDR(
+ ext0_addr, R_EXT_DMA_1_ADDR__ext0_addr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__External_DMA_registers
+ REG_SET__R_EXT_DMA_1_CMD(
+ cnt, R_EXT_DMA_1_CMD__cnt__DEFAULT,
+ rqpol, R_EXT_DMA_1_CMD__rqpol__DEFAULT,
+ apol, R_EXT_DMA_1_CMD__apol__DEFAULT,
+ rq_ack, R_EXT_DMA_1_CMD__rq_ack__DEFAULT,
+ wid, R_EXT_DMA_1_CMD__wid__DEFAULT,
+ dir, R_EXT_DMA_1_CMD__dir__DEFAULT,
+ run, R_EXT_DMA_1_CMD__run__DEFAULT,
+ trf_count, R_EXT_DMA_1_CMD__trf_count__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_config_registers
+ REG_SET__R_GEN_CONFIG(
+ par_w, R_GEN_CONFIG__par_w__DEFAULT,
+ usb2, R_GEN_CONFIG__usb2__DEFAULT,
+ usb1, R_GEN_CONFIG__usb1__DEFAULT,
+ g24dir, R_GEN_CONFIG__g24dir__DEFAULT,
+ g16_23dir, R_GEN_CONFIG__g16_23dir__DEFAULT,
+ g8_15dir, R_GEN_CONFIG__g8_15dir__DEFAULT,
+ g0dir, R_GEN_CONFIG__g0dir__DEFAULT,
+ dma9, R_GEN_CONFIG__dma9__DEFAULT,
+ dma8, R_GEN_CONFIG__dma8__DEFAULT,
+ dma7, R_GEN_CONFIG__dma7__DEFAULT,
+ dma6, R_GEN_CONFIG__dma6__DEFAULT,
+ dma5, R_GEN_CONFIG__dma5__DEFAULT,
+ dma4, R_GEN_CONFIG__dma4__DEFAULT,
+ dma3, R_GEN_CONFIG__dma3__DEFAULT,
+ dma2, R_GEN_CONFIG__dma2__DEFAULT,
+ mio_w, R_GEN_CONFIG__mio_w__DEFAULT,
+ ser3, R_GEN_CONFIG__ser3__DEFAULT,
+ par1, R_GEN_CONFIG__par1__DEFAULT,
+ scsi0w, R_GEN_CONFIG__scsi0w__DEFAULT,
+ scsi1, R_GEN_CONFIG__scsi1__DEFAULT,
+ mio, R_GEN_CONFIG__mio__DEFAULT,
+ ser2, R_GEN_CONFIG__ser2__DEFAULT,
+ par0, R_GEN_CONFIG__par0__DEFAULT,
+ ata, R_GEN_CONFIG__ata__DEFAULT,
+ scsi0, R_GEN_CONFIG__scsi0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_config_registers
+ REG_SET__R_GEN_CONFIG_II(
+ sermode3, R_GEN_CONFIG_II__sermode3__DEFAULT,
+ sermode1, R_GEN_CONFIG_II__sermode1__DEFAULT,
+ ext_clk, R_GEN_CONFIG_II__ext_clk__DEFAULT,
+ ser3, R_GEN_CONFIG_II__ser3__DEFAULT,
+ ser2, R_GEN_CONFIG_II__ser2__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_IRQ_MASK0_CLR(
+ nmi_pin, R_IRQ_MASK0_CLR__nmi_pin__DEFAULT,
+ watchdog_nmi, R_IRQ_MASK0_CLR__watchdog_nmi__DEFAULT,
+ sqe_test_error, R_IRQ_MASK0_CLR__sqe_test_error__DEFAULT,
+ carrier_loss, R_IRQ_MASK0_CLR__carrier_loss__DEFAULT,
+ deferred, R_IRQ_MASK0_CLR__deferred__DEFAULT,
+ late_col, R_IRQ_MASK0_CLR__late_col__DEFAULT,
+ multiple_col, R_IRQ_MASK0_CLR__multiple_col__DEFAULT,
+ single_col, R_IRQ_MASK0_CLR__single_col__DEFAULT,
+ congestion, R_IRQ_MASK0_CLR__congestion__DEFAULT,
+ oversize, R_IRQ_MASK0_CLR__oversize__DEFAULT,
+ alignment_error, R_IRQ_MASK0_CLR__alignment_error__DEFAULT,
+ crc_error, R_IRQ_MASK0_CLR__crc_error__DEFAULT,
+ overrun, R_IRQ_MASK0_CLR__overrun__DEFAULT,
+ underrun, R_IRQ_MASK0_CLR__underrun__DEFAULT,
+ excessive_col, R_IRQ_MASK0_CLR__excessive_col__DEFAULT,
+ mdio, R_IRQ_MASK0_CLR__mdio__DEFAULT,
+ ata_drq3, R_IRQ_MASK0_CLR__ata_drq3__DEFAULT,
+ ata_drq2, R_IRQ_MASK0_CLR__ata_drq2__DEFAULT,
+ ata_drq1, R_IRQ_MASK0_CLR__ata_drq1__DEFAULT,
+ ata_drq0, R_IRQ_MASK0_CLR__ata_drq0__DEFAULT,
+ par0_ecp_cmd, R_IRQ_MASK0_CLR__par0_ecp_cmd__DEFAULT,
+ par0_peri, R_IRQ_MASK0_CLR__par0_peri__DEFAULT,
+ par0_data, R_IRQ_MASK0_CLR__par0_data__DEFAULT,
+ par0_ready, R_IRQ_MASK0_CLR__par0_ready__DEFAULT,
+ ata_dmaend, R_IRQ_MASK0_CLR__ata_dmaend__DEFAULT,
+ irq_ext_vector_nr, R_IRQ_MASK0_CLR__irq_ext_vector_nr__DEFAULT,
+ irq_int_vector_nr, R_IRQ_MASK0_CLR__irq_int_vector_nr__DEFAULT,
+ ext_dma1, R_IRQ_MASK0_CLR__ext_dma1__DEFAULT,
+ ext_dma0, R_IRQ_MASK0_CLR__ext_dma0__DEFAULT,
+ timer1, R_IRQ_MASK0_CLR__timer1__DEFAULT,
+ timer0, R_IRQ_MASK0_CLR__timer0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_IRQ_MASK0_SET(
+ nmi_pin, R_IRQ_MASK0_SET__nmi_pin__DEFAULT,
+ watchdog_nmi, R_IRQ_MASK0_SET__watchdog_nmi__DEFAULT,
+ sqe_test_error, R_IRQ_MASK0_SET__sqe_test_error__DEFAULT,
+ carrier_loss, R_IRQ_MASK0_SET__carrier_loss__DEFAULT,
+ deferred, R_IRQ_MASK0_SET__deferred__DEFAULT,
+ late_col, R_IRQ_MASK0_SET__late_col__DEFAULT,
+ multiple_col, R_IRQ_MASK0_SET__multiple_col__DEFAULT,
+ single_col, R_IRQ_MASK0_SET__single_col__DEFAULT,
+ congestion, R_IRQ_MASK0_SET__congestion__DEFAULT,
+ oversize, R_IRQ_MASK0_SET__oversize__DEFAULT,
+ alignment_error, R_IRQ_MASK0_SET__alignment_error__DEFAULT,
+ crc_error, R_IRQ_MASK0_SET__crc_error__DEFAULT,
+ overrun, R_IRQ_MASK0_SET__overrun__DEFAULT,
+ underrun, R_IRQ_MASK0_SET__underrun__DEFAULT,
+ excessive_col, R_IRQ_MASK0_SET__excessive_col__DEFAULT,
+ mdio, R_IRQ_MASK0_SET__mdio__DEFAULT,
+ ata_drq3, R_IRQ_MASK0_SET__ata_drq3__DEFAULT,
+ ata_drq2, R_IRQ_MASK0_SET__ata_drq2__DEFAULT,
+ ata_drq1, R_IRQ_MASK0_SET__ata_drq1__DEFAULT,
+ ata_drq0, R_IRQ_MASK0_SET__ata_drq0__DEFAULT,
+ par0_ecp_cmd, R_IRQ_MASK0_SET__par0_ecp_cmd__DEFAULT,
+ par0_peri, R_IRQ_MASK0_SET__par0_peri__DEFAULT,
+ par0_data, R_IRQ_MASK0_SET__par0_data__DEFAULT,
+ par0_ready, R_IRQ_MASK0_SET__par0_ready__DEFAULT,
+ ata_dmaend, R_IRQ_MASK0_SET__ata_dmaend__DEFAULT,
+ irq_ext_vector_nr, R_IRQ_MASK0_SET__irq_ext_vector_nr__DEFAULT,
+ irq_int_vector_nr, R_IRQ_MASK0_SET__irq_int_vector_nr__DEFAULT,
+ ext_dma1, R_IRQ_MASK0_SET__ext_dma1__DEFAULT,
+ ext_dma0, R_IRQ_MASK0_SET__ext_dma0__DEFAULT,
+ timer1, R_IRQ_MASK0_SET__timer1__DEFAULT,
+ timer0, R_IRQ_MASK0_SET__timer0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_IRQ_MASK1_CLR(
+ sw_int7, R_IRQ_MASK1_CLR__sw_int7__DEFAULT,
+ sw_int6, R_IRQ_MASK1_CLR__sw_int6__DEFAULT,
+ sw_int5, R_IRQ_MASK1_CLR__sw_int5__DEFAULT,
+ sw_int4, R_IRQ_MASK1_CLR__sw_int4__DEFAULT,
+ sw_int3, R_IRQ_MASK1_CLR__sw_int3__DEFAULT,
+ sw_int2, R_IRQ_MASK1_CLR__sw_int2__DEFAULT,
+ sw_int1, R_IRQ_MASK1_CLR__sw_int1__DEFAULT,
+ sw_int0, R_IRQ_MASK1_CLR__sw_int0__DEFAULT,
+ par1_ecp_cmd, R_IRQ_MASK1_CLR__par1_ecp_cmd__DEFAULT,
+ par1_peri, R_IRQ_MASK1_CLR__par1_peri__DEFAULT,
+ par1_data, R_IRQ_MASK1_CLR__par1_data__DEFAULT,
+ par1_ready, R_IRQ_MASK1_CLR__par1_ready__DEFAULT,
+ ser3_ready, R_IRQ_MASK1_CLR__ser3_ready__DEFAULT,
+ ser3_data, R_IRQ_MASK1_CLR__ser3_data__DEFAULT,
+ ser2_ready, R_IRQ_MASK1_CLR__ser2_ready__DEFAULT,
+ ser2_data, R_IRQ_MASK1_CLR__ser2_data__DEFAULT,
+ ser1_ready, R_IRQ_MASK1_CLR__ser1_ready__DEFAULT,
+ ser1_data, R_IRQ_MASK1_CLR__ser1_data__DEFAULT,
+ ser0_ready, R_IRQ_MASK1_CLR__ser0_ready__DEFAULT,
+ ser0_data, R_IRQ_MASK1_CLR__ser0_data__DEFAULT,
+ pa7, R_IRQ_MASK1_CLR__pa7__DEFAULT,
+ pa6, R_IRQ_MASK1_CLR__pa6__DEFAULT,
+ pa5, R_IRQ_MASK1_CLR__pa5__DEFAULT,
+ pa4, R_IRQ_MASK1_CLR__pa4__DEFAULT,
+ pa3, R_IRQ_MASK1_CLR__pa3__DEFAULT,
+ pa2, R_IRQ_MASK1_CLR__pa2__DEFAULT,
+ pa1, R_IRQ_MASK1_CLR__pa1__DEFAULT,
+ pa0, R_IRQ_MASK1_CLR__pa0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_IRQ_MASK1_SET(
+ sw_int7, R_IRQ_MASK1_SET__sw_int7__DEFAULT,
+ sw_int6, R_IRQ_MASK1_SET__sw_int6__DEFAULT,
+ sw_int5, R_IRQ_MASK1_SET__sw_int5__DEFAULT,
+ sw_int4, R_IRQ_MASK1_SET__sw_int4__DEFAULT,
+ sw_int3, R_IRQ_MASK1_SET__sw_int3__DEFAULT,
+ sw_int2, R_IRQ_MASK1_SET__sw_int2__DEFAULT,
+ sw_int1, R_IRQ_MASK1_SET__sw_int1__DEFAULT,
+ sw_int0, R_IRQ_MASK1_SET__sw_int0__DEFAULT,
+ par1_ecp_cmd, R_IRQ_MASK1_SET__par1_ecp_cmd__DEFAULT,
+ par1_peri, R_IRQ_MASK1_SET__par1_peri__DEFAULT,
+ par1_data, R_IRQ_MASK1_SET__par1_data__DEFAULT,
+ par1_ready, R_IRQ_MASK1_SET__par1_ready__DEFAULT,
+ ser3_ready, R_IRQ_MASK1_SET__ser3_ready__DEFAULT,
+ ser3_data, R_IRQ_MASK1_SET__ser3_data__DEFAULT,
+ ser2_ready, R_IRQ_MASK1_SET__ser2_ready__DEFAULT,
+ ser2_data, R_IRQ_MASK1_SET__ser2_data__DEFAULT,
+ ser1_ready, R_IRQ_MASK1_SET__ser1_ready__DEFAULT,
+ ser1_data, R_IRQ_MASK1_SET__ser1_data__DEFAULT,
+ ser0_ready, R_IRQ_MASK1_SET__ser0_ready__DEFAULT,
+ ser0_data, R_IRQ_MASK1_SET__ser0_data__DEFAULT,
+ pa7, R_IRQ_MASK1_SET__pa7__DEFAULT,
+ pa6, R_IRQ_MASK1_SET__pa6__DEFAULT,
+ pa5, R_IRQ_MASK1_SET__pa5__DEFAULT,
+ pa4, R_IRQ_MASK1_SET__pa4__DEFAULT,
+ pa3, R_IRQ_MASK1_SET__pa3__DEFAULT,
+ pa2, R_IRQ_MASK1_SET__pa2__DEFAULT,
+ pa1, R_IRQ_MASK1_SET__pa1__DEFAULT,
+ pa0, R_IRQ_MASK1_SET__pa0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_IRQ_MASK2_CLR(
+ dma8_sub3_descr, R_IRQ_MASK2_CLR__dma8_sub3_descr__DEFAULT,
+ dma8_sub2_descr, R_IRQ_MASK2_CLR__dma8_sub2_descr__DEFAULT,
+ dma8_sub1_descr, R_IRQ_MASK2_CLR__dma8_sub1_descr__DEFAULT,
+ dma8_sub0_descr, R_IRQ_MASK2_CLR__dma8_sub0_descr__DEFAULT,
+ dma9_eop, R_IRQ_MASK2_CLR__dma9_eop__DEFAULT,
+ dma9_descr, R_IRQ_MASK2_CLR__dma9_descr__DEFAULT,
+ dma8_eop, R_IRQ_MASK2_CLR__dma8_eop__DEFAULT,
+ dma8_descr, R_IRQ_MASK2_CLR__dma8_descr__DEFAULT,
+ dma7_eop, R_IRQ_MASK2_CLR__dma7_eop__DEFAULT,
+ dma7_descr, R_IRQ_MASK2_CLR__dma7_descr__DEFAULT,
+ dma6_eop, R_IRQ_MASK2_CLR__dma6_eop__DEFAULT,
+ dma6_descr, R_IRQ_MASK2_CLR__dma6_descr__DEFAULT,
+ dma5_eop, R_IRQ_MASK2_CLR__dma5_eop__DEFAULT,
+ dma5_descr, R_IRQ_MASK2_CLR__dma5_descr__DEFAULT,
+ dma4_eop, R_IRQ_MASK2_CLR__dma4_eop__DEFAULT,
+ dma4_descr, R_IRQ_MASK2_CLR__dma4_descr__DEFAULT,
+ dma3_eop, R_IRQ_MASK2_CLR__dma3_eop__DEFAULT,
+ dma3_descr, R_IRQ_MASK2_CLR__dma3_descr__DEFAULT,
+ dma2_eop, R_IRQ_MASK2_CLR__dma2_eop__DEFAULT,
+ dma2_descr, R_IRQ_MASK2_CLR__dma2_descr__DEFAULT,
+ dma1_eop, R_IRQ_MASK2_CLR__dma1_eop__DEFAULT,
+ dma1_descr, R_IRQ_MASK2_CLR__dma1_descr__DEFAULT,
+ dma0_eop, R_IRQ_MASK2_CLR__dma0_eop__DEFAULT,
+ dma0_descr, R_IRQ_MASK2_CLR__dma0_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_IRQ_MASK2_SET(
+ dma8_sub3_descr, R_IRQ_MASK2_SET__dma8_sub3_descr__DEFAULT,
+ dma8_sub2_descr, R_IRQ_MASK2_SET__dma8_sub2_descr__DEFAULT,
+ dma8_sub1_descr, R_IRQ_MASK2_SET__dma8_sub1_descr__DEFAULT,
+ dma8_sub0_descr, R_IRQ_MASK2_SET__dma8_sub0_descr__DEFAULT,
+ dma9_eop, R_IRQ_MASK2_SET__dma9_eop__DEFAULT,
+ dma9_descr, R_IRQ_MASK2_SET__dma9_descr__DEFAULT,
+ dma8_eop, R_IRQ_MASK2_SET__dma8_eop__DEFAULT,
+ dma8_descr, R_IRQ_MASK2_SET__dma8_descr__DEFAULT,
+ dma7_eop, R_IRQ_MASK2_SET__dma7_eop__DEFAULT,
+ dma7_descr, R_IRQ_MASK2_SET__dma7_descr__DEFAULT,
+ dma6_eop, R_IRQ_MASK2_SET__dma6_eop__DEFAULT,
+ dma6_descr, R_IRQ_MASK2_SET__dma6_descr__DEFAULT,
+ dma5_eop, R_IRQ_MASK2_SET__dma5_eop__DEFAULT,
+ dma5_descr, R_IRQ_MASK2_SET__dma5_descr__DEFAULT,
+ dma4_eop, R_IRQ_MASK2_SET__dma4_eop__DEFAULT,
+ dma4_descr, R_IRQ_MASK2_SET__dma4_descr__DEFAULT,
+ dma3_eop, R_IRQ_MASK2_SET__dma3_eop__DEFAULT,
+ dma3_descr, R_IRQ_MASK2_SET__dma3_descr__DEFAULT,
+ dma2_eop, R_IRQ_MASK2_SET__dma2_eop__DEFAULT,
+ dma2_descr, R_IRQ_MASK2_SET__dma2_descr__DEFAULT,
+ dma1_eop, R_IRQ_MASK2_SET__dma1_eop__DEFAULT,
+ dma1_descr, R_IRQ_MASK2_SET__dma1_descr__DEFAULT,
+ dma0_eop, R_IRQ_MASK2_SET__dma0_eop__DEFAULT,
+ dma0_descr, R_IRQ_MASK2_SET__dma0_descr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__MMU_registers
+ REG_SET__R_MMU_CONFIG(
+ mmu_enable, R_MMU_CONFIG__mmu_enable__DEFAULT,
+ inv_excp, R_MMU_CONFIG__inv_excp__DEFAULT,
+ acc_excp, R_MMU_CONFIG__acc_excp__DEFAULT,
+ we_excp, R_MMU_CONFIG__we_excp__DEFAULT,
+ seg_f, R_MMU_CONFIG__seg_f__DEFAULT,
+ seg_e, R_MMU_CONFIG__seg_e__DEFAULT,
+ seg_d, R_MMU_CONFIG__seg_d__DEFAULT,
+ seg_c, R_MMU_CONFIG__seg_c__DEFAULT,
+ seg_b, R_MMU_CONFIG__seg_b__DEFAULT,
+ seg_a, R_MMU_CONFIG__seg_a__DEFAULT,
+ seg_9, R_MMU_CONFIG__seg_9__DEFAULT,
+ seg_8, R_MMU_CONFIG__seg_8__DEFAULT,
+ seg_7, R_MMU_CONFIG__seg_7__DEFAULT,
+ seg_6, R_MMU_CONFIG__seg_6__DEFAULT,
+ seg_5, R_MMU_CONFIG__seg_5__DEFAULT,
+ seg_4, R_MMU_CONFIG__seg_4__DEFAULT,
+ seg_3, R_MMU_CONFIG__seg_3__DEFAULT,
+ seg_2, R_MMU_CONFIG__seg_2__DEFAULT,
+ seg_1, R_MMU_CONFIG__seg_1__DEFAULT,
+ seg_0, R_MMU_CONFIG__seg_0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__MMU_registers
+ REG_SET__R_MMU_CTRL(
+ inv_excp, R_MMU_CTRL__inv_excp__DEFAULT,
+ acc_excp, R_MMU_CTRL__acc_excp__DEFAULT,
+ we_excp, R_MMU_CTRL__we_excp__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__MMU_registers
+ REG_SET__R_MMU_ENABLE(
+ mmu_enable, R_MMU_ENABLE__mmu_enable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__MMU_registers
+ REG_SET__R_MMU_KBASE_HI(
+ base_f, R_MMU_KBASE_HI__base_f__DEFAULT,
+ base_e, R_MMU_KBASE_HI__base_e__DEFAULT,
+ base_d, R_MMU_KBASE_HI__base_d__DEFAULT,
+ base_c, R_MMU_KBASE_HI__base_c__DEFAULT,
+ base_b, R_MMU_KBASE_HI__base_b__DEFAULT,
+ base_a, R_MMU_KBASE_HI__base_a__DEFAULT,
+ base_9, R_MMU_KBASE_HI__base_9__DEFAULT,
+ base_8, R_MMU_KBASE_HI__base_8__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__MMU_registers
+ REG_SET__R_MMU_KBASE_LO(
+ base_7, R_MMU_KBASE_LO__base_7__DEFAULT,
+ base_6, R_MMU_KBASE_LO__base_6__DEFAULT,
+ base_5, R_MMU_KBASE_LO__base_5__DEFAULT,
+ base_4, R_MMU_KBASE_LO__base_4__DEFAULT,
+ base_3, R_MMU_KBASE_LO__base_3__DEFAULT,
+ base_2, R_MMU_KBASE_LO__base_2__DEFAULT,
+ base_1, R_MMU_KBASE_LO__base_1__DEFAULT,
+ base_0, R_MMU_KBASE_LO__base_0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__MMU_registers
+ REG_SET__R_MMU_KSEG(
+ seg_f, R_MMU_KSEG__seg_f__DEFAULT,
+ seg_e, R_MMU_KSEG__seg_e__DEFAULT,
+ seg_d, R_MMU_KSEG__seg_d__DEFAULT,
+ seg_c, R_MMU_KSEG__seg_c__DEFAULT,
+ seg_b, R_MMU_KSEG__seg_b__DEFAULT,
+ seg_a, R_MMU_KSEG__seg_a__DEFAULT,
+ seg_9, R_MMU_KSEG__seg_9__DEFAULT,
+ seg_8, R_MMU_KSEG__seg_8__DEFAULT,
+ seg_7, R_MMU_KSEG__seg_7__DEFAULT,
+ seg_6, R_MMU_KSEG__seg_6__DEFAULT,
+ seg_5, R_MMU_KSEG__seg_5__DEFAULT,
+ seg_4, R_MMU_KSEG__seg_4__DEFAULT,
+ seg_3, R_MMU_KSEG__seg_3__DEFAULT,
+ seg_2, R_MMU_KSEG__seg_2__DEFAULT,
+ seg_1, R_MMU_KSEG__seg_1__DEFAULT,
+ seg_0, R_MMU_KSEG__seg_0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_GA_0(
+ ga_low, R_NETWORK_GA_0__ga_low__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_GA_1(
+ ga_high, R_NETWORK_GA_1__ga_high__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_GEN_CONFIG(
+ loopback, R_NETWORK_GEN_CONFIG__loopback__DEFAULT,
+ frame, R_NETWORK_GEN_CONFIG__frame__DEFAULT,
+ vg, R_NETWORK_GEN_CONFIG__vg__DEFAULT,
+ phy, R_NETWORK_GEN_CONFIG__phy__DEFAULT,
+ enable, R_NETWORK_GEN_CONFIG__enable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_MGM_CTRL(
+ txd_pins, R_NETWORK_MGM_CTRL__txd_pins__DEFAULT,
+ txer_pin, R_NETWORK_MGM_CTRL__txer_pin__DEFAULT,
+ mdck, R_NETWORK_MGM_CTRL__mdck__DEFAULT,
+ mdoe, R_NETWORK_MGM_CTRL__mdoe__DEFAULT,
+ mdio, R_NETWORK_MGM_CTRL__mdio__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_REC_CONFIG(
+ max_size, R_NETWORK_REC_CONFIG__max_size__DEFAULT,
+ duplex, R_NETWORK_REC_CONFIG__duplex__DEFAULT,
+ bad_crc, R_NETWORK_REC_CONFIG__bad_crc__DEFAULT,
+ oversize, R_NETWORK_REC_CONFIG__oversize__DEFAULT,
+ undersize, R_NETWORK_REC_CONFIG__undersize__DEFAULT,
+ all_roots, R_NETWORK_REC_CONFIG__all_roots__DEFAULT,
+ tr_broadcast, R_NETWORK_REC_CONFIG__tr_broadcast__DEFAULT,
+ broadcast, R_NETWORK_REC_CONFIG__broadcast__DEFAULT,
+ individual, R_NETWORK_REC_CONFIG__individual__DEFAULT,
+ ma1, R_NETWORK_REC_CONFIG__ma1__DEFAULT,
+ ma0, R_NETWORK_REC_CONFIG__ma0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_SA_0(
+ ma0_low, R_NETWORK_SA_0__ma0_low__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_SA_1(
+ ma1_low, R_NETWORK_SA_1__ma1_low__DEFAULT,
+ ma0_high, R_NETWORK_SA_1__ma0_high__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_SA_2(
+ ma1_high, R_NETWORK_SA_2__ma1_high__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Network_interface_registers
+ REG_SET__R_NETWORK_TR_CTRL(
+ clr_error, R_NETWORK_TR_CTRL__clr_error__DEFAULT,
+ delay, R_NETWORK_TR_CTRL__delay__DEFAULT,
+ cancel, R_NETWORK_TR_CTRL__cancel__DEFAULT,
+ cd, R_NETWORK_TR_CTRL__cd__DEFAULT,
+ retry, R_NETWORK_TR_CTRL__retry__DEFAULT,
+ pad, R_NETWORK_TR_CTRL__pad__DEFAULT,
+ crc, R_NETWORK_TR_CTRL__crc__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR0_CONFIG(
+ ioe, R_PAR0_CONFIG__ioe__DEFAULT,
+ iseli, R_PAR0_CONFIG__iseli__DEFAULT,
+ iautofd, R_PAR0_CONFIG__iautofd__DEFAULT,
+ istrb, R_PAR0_CONFIG__istrb__DEFAULT,
+ iinit, R_PAR0_CONFIG__iinit__DEFAULT,
+ iperr, R_PAR0_CONFIG__iperr__DEFAULT,
+ iack, R_PAR0_CONFIG__iack__DEFAULT,
+ ibusy, R_PAR0_CONFIG__ibusy__DEFAULT,
+ ifault, R_PAR0_CONFIG__ifault__DEFAULT,
+ isel, R_PAR0_CONFIG__isel__DEFAULT,
+ ext_mode, R_PAR0_CONFIG__ext_mode__DEFAULT,
+ wide, R_PAR0_CONFIG__wide__DEFAULT,
+ dma, R_PAR0_CONFIG__dma__DEFAULT,
+ rle_in, R_PAR0_CONFIG__rle_in__DEFAULT,
+ rle_out, R_PAR0_CONFIG__rle_out__DEFAULT,
+ enable, R_PAR0_CONFIG__enable__DEFAULT,
+ force, R_PAR0_CONFIG__force__DEFAULT,
+ ign_ack, R_PAR0_CONFIG__ign_ack__DEFAULT,
+ oe_ack, R_PAR0_CONFIG__oe_ack__DEFAULT,
+ mode, R_PAR0_CONFIG__mode__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR0_CTRL(
+ ctrl, R_PAR0_CTRL__ctrl__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR0_CTRL_DATA(
+ peri_int, R_PAR0_CTRL_DATA__peri_int__DEFAULT,
+ oe, R_PAR0_CTRL_DATA__oe__DEFAULT,
+ seli, R_PAR0_CTRL_DATA__seli__DEFAULT,
+ autofd, R_PAR0_CTRL_DATA__autofd__DEFAULT,
+ strb, R_PAR0_CTRL_DATA__strb__DEFAULT,
+ init, R_PAR0_CTRL_DATA__init__DEFAULT,
+ ecp_cmd, R_PAR0_CTRL_DATA__ecp_cmd__DEFAULT,
+ data, R_PAR0_CTRL_DATA__data__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR0_DELAY(
+ fine_hold, R_PAR0_DELAY__fine_hold__DEFAULT,
+ hold, R_PAR0_DELAY__hold__DEFAULT,
+ fine_strb, R_PAR0_DELAY__fine_strb__DEFAULT,
+ strobe, R_PAR0_DELAY__strobe__DEFAULT,
+ fine_setup, R_PAR0_DELAY__fine_setup__DEFAULT,
+ setup, R_PAR0_DELAY__setup__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR1_CONFIG(
+ ioe, R_PAR1_CONFIG__ioe__DEFAULT,
+ iseli, R_PAR1_CONFIG__iseli__DEFAULT,
+ iautofd, R_PAR1_CONFIG__iautofd__DEFAULT,
+ istrb, R_PAR1_CONFIG__istrb__DEFAULT,
+ iinit, R_PAR1_CONFIG__iinit__DEFAULT,
+ iperr, R_PAR1_CONFIG__iperr__DEFAULT,
+ iack, R_PAR1_CONFIG__iack__DEFAULT,
+ ibusy, R_PAR1_CONFIG__ibusy__DEFAULT,
+ ifault, R_PAR1_CONFIG__ifault__DEFAULT,
+ isel, R_PAR1_CONFIG__isel__DEFAULT,
+ ext_mode, R_PAR1_CONFIG__ext_mode__DEFAULT,
+ dma, R_PAR1_CONFIG__dma__DEFAULT,
+ rle_in, R_PAR1_CONFIG__rle_in__DEFAULT,
+ rle_out, R_PAR1_CONFIG__rle_out__DEFAULT,
+ enable, R_PAR1_CONFIG__enable__DEFAULT,
+ force, R_PAR1_CONFIG__force__DEFAULT,
+ ign_ack, R_PAR1_CONFIG__ign_ack__DEFAULT,
+ oe_ack, R_PAR1_CONFIG__oe_ack__DEFAULT,
+ mode, R_PAR1_CONFIG__mode__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR1_CTRL(
+ ctrl, R_PAR1_CTRL__ctrl__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR1_CTRL_DATA(
+ peri_int, R_PAR1_CTRL_DATA__peri_int__DEFAULT,
+ oe, R_PAR1_CTRL_DATA__oe__DEFAULT,
+ seli, R_PAR1_CTRL_DATA__seli__DEFAULT,
+ autofd, R_PAR1_CTRL_DATA__autofd__DEFAULT,
+ strb, R_PAR1_CTRL_DATA__strb__DEFAULT,
+ init, R_PAR1_CTRL_DATA__init__DEFAULT,
+ ecp_cmd, R_PAR1_CTRL_DATA__ecp_cmd__DEFAULT,
+ data, R_PAR1_CTRL_DATA__data__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Parallel_printer_port_registers
+ REG_SET__R_PAR1_DELAY(
+ fine_hold, R_PAR1_DELAY__fine_hold__DEFAULT,
+ hold, R_PAR1_DELAY__hold__DEFAULT,
+ fine_strb, R_PAR1_DELAY__fine_strb__DEFAULT,
+ strobe, R_PAR1_DELAY__strobe__DEFAULT,
+ fine_setup, R_PAR1_DELAY__fine_setup__DEFAULT,
+ setup, R_PAR1_DELAY__setup__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PA_DATA(
+ data_out, R_PORT_PA_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PA_DIR(
+ dir7, R_PORT_PA_DIR__dir7__DEFAULT,
+ dir6, R_PORT_PA_DIR__dir6__DEFAULT,
+ dir5, R_PORT_PA_DIR__dir5__DEFAULT,
+ dir4, R_PORT_PA_DIR__dir4__DEFAULT,
+ dir3, R_PORT_PA_DIR__dir3__DEFAULT,
+ dir2, R_PORT_PA_DIR__dir2__DEFAULT,
+ dir1, R_PORT_PA_DIR__dir1__DEFAULT,
+ dir0, R_PORT_PA_DIR__dir0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PA_SET(
+ dir7, R_PORT_PA_SET__dir7__DEFAULT,
+ dir6, R_PORT_PA_SET__dir6__DEFAULT,
+ dir5, R_PORT_PA_SET__dir5__DEFAULT,
+ dir4, R_PORT_PA_SET__dir4__DEFAULT,
+ dir3, R_PORT_PA_SET__dir3__DEFAULT,
+ dir2, R_PORT_PA_SET__dir2__DEFAULT,
+ dir1, R_PORT_PA_SET__dir1__DEFAULT,
+ dir0, R_PORT_PA_SET__dir0__DEFAULT,
+ data_out, R_PORT_PA_SET__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PB_CONFIG(
+ cs7, R_PORT_PB_CONFIG__cs7__DEFAULT,
+ cs6, R_PORT_PB_CONFIG__cs6__DEFAULT,
+ cs5, R_PORT_PB_CONFIG__cs5__DEFAULT,
+ cs4, R_PORT_PB_CONFIG__cs4__DEFAULT,
+ cs3, R_PORT_PB_CONFIG__cs3__DEFAULT,
+ cs2, R_PORT_PB_CONFIG__cs2__DEFAULT,
+ scsi1, R_PORT_PB_CONFIG__scsi1__DEFAULT,
+ scsi0, R_PORT_PB_CONFIG__scsi0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PB_DATA(
+ data_out, R_PORT_PB_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PB_DIR(
+ dir7, R_PORT_PB_DIR__dir7__DEFAULT,
+ dir6, R_PORT_PB_DIR__dir6__DEFAULT,
+ dir5, R_PORT_PB_DIR__dir5__DEFAULT,
+ dir4, R_PORT_PB_DIR__dir4__DEFAULT,
+ dir3, R_PORT_PB_DIR__dir3__DEFAULT,
+ dir2, R_PORT_PB_DIR__dir2__DEFAULT,
+ dir1, R_PORT_PB_DIR__dir1__DEFAULT,
+ dir0, R_PORT_PB_DIR__dir0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PB_I2C(
+ syncser3, R_PORT_PB_I2C__syncser3__DEFAULT,
+ syncser1, R_PORT_PB_I2C__syncser1__DEFAULT,
+ i2c_en, R_PORT_PB_I2C__i2c_en__DEFAULT,
+ i2c_d, R_PORT_PB_I2C__i2c_d__DEFAULT,
+ i2c_clk, R_PORT_PB_I2C__i2c_clk__DEFAULT,
+ i2c_oe_, R_PORT_PB_I2C__i2c_oe___DEFAULT
+ );
+#endif
+
+#if USE_GROUP__General_port_configuration_registers
+ REG_SET__R_PORT_PB_SET(
+ syncser3, R_PORT_PB_SET__syncser3__DEFAULT,
+ syncser1, R_PORT_PB_SET__syncser1__DEFAULT,
+ i2c_en, R_PORT_PB_SET__i2c_en__DEFAULT,
+ i2c_d, R_PORT_PB_SET__i2c_d__DEFAULT,
+ i2c_clk, R_PORT_PB_SET__i2c_clk__DEFAULT,
+ i2c_oe_, R_PORT_PB_SET__i2c_oe___DEFAULT,
+ cs7, R_PORT_PB_SET__cs7__DEFAULT,
+ cs6, R_PORT_PB_SET__cs6__DEFAULT,
+ cs5, R_PORT_PB_SET__cs5__DEFAULT,
+ cs4, R_PORT_PB_SET__cs4__DEFAULT,
+ cs3, R_PORT_PB_SET__cs3__DEFAULT,
+ cs2, R_PORT_PB_SET__cs2__DEFAULT,
+ scsi1, R_PORT_PB_SET__scsi1__DEFAULT,
+ scsi0, R_PORT_PB_SET__scsi0__DEFAULT,
+ dir7, R_PORT_PB_SET__dir7__DEFAULT,
+ dir6, R_PORT_PB_SET__dir6__DEFAULT,
+ dir5, R_PORT_PB_SET__dir5__DEFAULT,
+ dir4, R_PORT_PB_SET__dir4__DEFAULT,
+ dir3, R_PORT_PB_SET__dir3__DEFAULT,
+ dir2, R_PORT_PB_SET__dir2__DEFAULT,
+ dir1, R_PORT_PB_SET__dir1__DEFAULT,
+ dir0, R_PORT_PB_SET__dir0__DEFAULT,
+ data_out, R_PORT_PB_SET__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI0_CMD(
+ asynch_setup, R_SCSI0_CMD__asynch_setup__DEFAULT,
+ command, R_SCSI0_CMD__command__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI0_CMD_DATA(
+ parity_in, R_SCSI0_CMD_DATA__parity_in__DEFAULT,
+ skip, R_SCSI0_CMD_DATA__skip__DEFAULT,
+ clr_status, R_SCSI0_CMD_DATA__clr_status__DEFAULT,
+ asynch_setup, R_SCSI0_CMD_DATA__asynch_setup__DEFAULT,
+ command, R_SCSI0_CMD_DATA__command__DEFAULT,
+ data_out, R_SCSI0_CMD_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI0_CTRL(
+ id_type, R_SCSI0_CTRL__id_type__DEFAULT,
+ sel_timeout, R_SCSI0_CTRL__sel_timeout__DEFAULT,
+ synch_per, R_SCSI0_CTRL__synch_per__DEFAULT,
+ rst, R_SCSI0_CTRL__rst__DEFAULT,
+ atn, R_SCSI0_CTRL__atn__DEFAULT,
+ my_id, R_SCSI0_CTRL__my_id__DEFAULT,
+ target_id, R_SCSI0_CTRL__target_id__DEFAULT,
+ fast_20, R_SCSI0_CTRL__fast_20__DEFAULT,
+ bus_width, R_SCSI0_CTRL__bus_width__DEFAULT,
+ synch, R_SCSI0_CTRL__synch__DEFAULT,
+ enable, R_SCSI0_CTRL__enable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI0_DATA(
+ data_out, R_SCSI0_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI0_STATUS_CTRL(
+ parity_in, R_SCSI0_STATUS_CTRL__parity_in__DEFAULT,
+ skip, R_SCSI0_STATUS_CTRL__skip__DEFAULT,
+ clr_status, R_SCSI0_STATUS_CTRL__clr_status__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI1_CMD(
+ asynch_setup, R_SCSI1_CMD__asynch_setup__DEFAULT,
+ command, R_SCSI1_CMD__command__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI1_CMD_DATA(
+ parity_in, R_SCSI1_CMD_DATA__parity_in__DEFAULT,
+ skip, R_SCSI1_CMD_DATA__skip__DEFAULT,
+ clr_status, R_SCSI1_CMD_DATA__clr_status__DEFAULT,
+ asynch_setup, R_SCSI1_CMD_DATA__asynch_setup__DEFAULT,
+ command, R_SCSI1_CMD_DATA__command__DEFAULT,
+ data_out, R_SCSI1_CMD_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI1_CTRL(
+ id_type, R_SCSI1_CTRL__id_type__DEFAULT,
+ sel_timeout, R_SCSI1_CTRL__sel_timeout__DEFAULT,
+ synch_per, R_SCSI1_CTRL__synch_per__DEFAULT,
+ rst, R_SCSI1_CTRL__rst__DEFAULT,
+ atn, R_SCSI1_CTRL__atn__DEFAULT,
+ my_id, R_SCSI1_CTRL__my_id__DEFAULT,
+ target_id, R_SCSI1_CTRL__target_id__DEFAULT,
+ fast_20, R_SCSI1_CTRL__fast_20__DEFAULT,
+ bus_width, R_SCSI1_CTRL__bus_width__DEFAULT,
+ synch, R_SCSI1_CTRL__synch__DEFAULT,
+ enable, R_SCSI1_CTRL__enable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI1_DATA(
+ data_out, R_SCSI1_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__SCSI_registers
+ REG_SET__R_SCSI1_STATUS_CTRL(
+ parity_in, R_SCSI1_STATUS_CTRL__parity_in__DEFAULT,
+ skip, R_SCSI1_STATUS_CTRL__skip__DEFAULT,
+ clr_status, R_SCSI1_STATUS_CTRL__clr_status__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Bus_interface_configuration_registers
+ REG_SET__R_SDRAM_CONFIG(
+ wmm1, R_SDRAM_CONFIG__wmm1__DEFAULT,
+ wmm0, R_SDRAM_CONFIG__wmm0__DEFAULT,
+ sh1, R_SDRAM_CONFIG__sh1__DEFAULT,
+ sh0, R_SDRAM_CONFIG__sh0__DEFAULT,
+ w, R_SDRAM_CONFIG__w__DEFAULT,
+ type1, R_SDRAM_CONFIG__type1__DEFAULT,
+ type0, R_SDRAM_CONFIG__type0__DEFAULT,
+ group_sel, R_SDRAM_CONFIG__group_sel__DEFAULT,
+ ca1, R_SDRAM_CONFIG__ca1__DEFAULT,
+ bank_sel1, R_SDRAM_CONFIG__bank_sel1__DEFAULT,
+ ca0, R_SDRAM_CONFIG__ca0__DEFAULT,
+ bank_sel0, R_SDRAM_CONFIG__bank_sel0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Bus_interface_configuration_registers
+ REG_SET__R_SDRAM_TIMING(
+ sdram, R_SDRAM_TIMING__sdram__DEFAULT,
+ mrs_data, R_SDRAM_TIMING__mrs_data__DEFAULT,
+ ref, R_SDRAM_TIMING__ref__DEFAULT,
+ ddr, R_SDRAM_TIMING__ddr__DEFAULT,
+ clk100, R_SDRAM_TIMING__clk100__DEFAULT,
+ ps, R_SDRAM_TIMING__ps__DEFAULT,
+ cmd, R_SDRAM_TIMING__cmd__DEFAULT,
+ pde, R_SDRAM_TIMING__pde__DEFAULT,
+ rc, R_SDRAM_TIMING__rc__DEFAULT,
+ rp, R_SDRAM_TIMING__rp__DEFAULT,
+ rcd, R_SDRAM_TIMING__rcd__DEFAULT,
+ cl, R_SDRAM_TIMING__cl__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL0_BAUD(
+ tr_baud, R_SERIAL0_BAUD__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL0_BAUD__rec_baud__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL0_CTRL(
+ tr_baud, R_SERIAL0_CTRL__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL0_CTRL__rec_baud__DEFAULT,
+ dma_err, R_SERIAL0_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL0_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL0_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL0_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL0_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL0_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL0_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL0_CTRL__rec_bitnr__DEFAULT,
+ txd, R_SERIAL0_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL0_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL0_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL0_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL0_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL0_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL0_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL0_CTRL__tr_bitnr__DEFAULT,
+ data_out, R_SERIAL0_CTRL__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL0_REC_CTRL(
+ dma_err, R_SERIAL0_REC_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL0_REC_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL0_REC_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL0_REC_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL0_REC_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL0_REC_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL0_REC_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL0_REC_CTRL__rec_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL0_TR_CTRL(
+ txd, R_SERIAL0_TR_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL0_TR_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL0_TR_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL0_TR_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL0_TR_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL0_TR_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL0_TR_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL0_TR_CTRL__tr_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL0_TR_DATA(
+ data_out, R_SERIAL0_TR_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL0_XOFF(
+ tx_stop, R_SERIAL0_XOFF__tx_stop__DEFAULT,
+ auto_xoff, R_SERIAL0_XOFF__auto_xoff__DEFAULT,
+ xoff_char, R_SERIAL0_XOFF__xoff_char__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL1_BAUD(
+ tr_baud, R_SERIAL1_BAUD__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL1_BAUD__rec_baud__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL1_CTRL(
+ tr_baud, R_SERIAL1_CTRL__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL1_CTRL__rec_baud__DEFAULT,
+ dma_err, R_SERIAL1_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL1_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL1_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL1_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL1_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL1_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL1_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL1_CTRL__rec_bitnr__DEFAULT,
+ txd, R_SERIAL1_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL1_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL1_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL1_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL1_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL1_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL1_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL1_CTRL__tr_bitnr__DEFAULT,
+ data_out, R_SERIAL1_CTRL__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL1_REC_CTRL(
+ dma_err, R_SERIAL1_REC_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL1_REC_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL1_REC_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL1_REC_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL1_REC_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL1_REC_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL1_REC_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL1_REC_CTRL__rec_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL1_TR_CTRL(
+ txd, R_SERIAL1_TR_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL1_TR_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL1_TR_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL1_TR_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL1_TR_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL1_TR_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL1_TR_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL1_TR_CTRL__tr_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL1_TR_DATA(
+ data_out, R_SERIAL1_TR_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL1_XOFF(
+ tx_stop, R_SERIAL1_XOFF__tx_stop__DEFAULT,
+ auto_xoff, R_SERIAL1_XOFF__auto_xoff__DEFAULT,
+ xoff_char, R_SERIAL1_XOFF__xoff_char__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL2_BAUD(
+ tr_baud, R_SERIAL2_BAUD__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL2_BAUD__rec_baud__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL2_CTRL(
+ tr_baud, R_SERIAL2_CTRL__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL2_CTRL__rec_baud__DEFAULT,
+ dma_err, R_SERIAL2_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL2_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL2_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL2_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL2_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL2_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL2_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL2_CTRL__rec_bitnr__DEFAULT,
+ txd, R_SERIAL2_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL2_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL2_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL2_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL2_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL2_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL2_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL2_CTRL__tr_bitnr__DEFAULT,
+ data_out, R_SERIAL2_CTRL__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL2_REC_CTRL(
+ dma_err, R_SERIAL2_REC_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL2_REC_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL2_REC_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL2_REC_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL2_REC_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL2_REC_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL2_REC_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL2_REC_CTRL__rec_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL2_TR_CTRL(
+ txd, R_SERIAL2_TR_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL2_TR_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL2_TR_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL2_TR_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL2_TR_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL2_TR_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL2_TR_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL2_TR_CTRL__tr_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL2_TR_DATA(
+ data_out, R_SERIAL2_TR_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL2_XOFF(
+ tx_stop, R_SERIAL2_XOFF__tx_stop__DEFAULT,
+ auto_xoff, R_SERIAL2_XOFF__auto_xoff__DEFAULT,
+ xoff_char, R_SERIAL2_XOFF__xoff_char__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL3_BAUD(
+ tr_baud, R_SERIAL3_BAUD__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL3_BAUD__rec_baud__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL3_CTRL(
+ tr_baud, R_SERIAL3_CTRL__tr_baud__DEFAULT,
+ rec_baud, R_SERIAL3_CTRL__rec_baud__DEFAULT,
+ dma_err, R_SERIAL3_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL3_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL3_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL3_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL3_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL3_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL3_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL3_CTRL__rec_bitnr__DEFAULT,
+ txd, R_SERIAL3_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL3_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL3_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL3_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL3_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL3_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL3_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL3_CTRL__tr_bitnr__DEFAULT,
+ data_out, R_SERIAL3_CTRL__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL3_REC_CTRL(
+ dma_err, R_SERIAL3_REC_CTRL__dma_err__DEFAULT,
+ rec_enable, R_SERIAL3_REC_CTRL__rec_enable__DEFAULT,
+ rts_, R_SERIAL3_REC_CTRL__rts___DEFAULT,
+ sampling, R_SERIAL3_REC_CTRL__sampling__DEFAULT,
+ rec_stick_par, R_SERIAL3_REC_CTRL__rec_stick_par__DEFAULT,
+ rec_par, R_SERIAL3_REC_CTRL__rec_par__DEFAULT,
+ rec_par_en, R_SERIAL3_REC_CTRL__rec_par_en__DEFAULT,
+ rec_bitnr, R_SERIAL3_REC_CTRL__rec_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL3_TR_CTRL(
+ txd, R_SERIAL3_TR_CTRL__txd__DEFAULT,
+ tr_enable, R_SERIAL3_TR_CTRL__tr_enable__DEFAULT,
+ auto_cts, R_SERIAL3_TR_CTRL__auto_cts__DEFAULT,
+ stop_bits, R_SERIAL3_TR_CTRL__stop_bits__DEFAULT,
+ tr_stick_par, R_SERIAL3_TR_CTRL__tr_stick_par__DEFAULT,
+ tr_par, R_SERIAL3_TR_CTRL__tr_par__DEFAULT,
+ tr_par_en, R_SERIAL3_TR_CTRL__tr_par_en__DEFAULT,
+ tr_bitnr, R_SERIAL3_TR_CTRL__tr_bitnr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL3_TR_DATA(
+ data_out, R_SERIAL3_TR_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Serial_port_registers
+ REG_SET__R_SERIAL3_XOFF(
+ tx_stop, R_SERIAL3_XOFF__tx_stop__DEFAULT,
+ auto_xoff, R_SERIAL3_XOFF__auto_xoff__DEFAULT,
+ xoff_char, R_SERIAL3_XOFF__xoff_char__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Timer_registers
+ REG_SET__R_SERIAL_PRESCALE(
+ ser_presc, R_SERIAL_PRESCALE__ser_presc__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__DMA_registers
+ REG_SET__R_SET_EOP(
+ ch9_eop, R_SET_EOP__ch9_eop__DEFAULT,
+ ch7_eop, R_SET_EOP__ch7_eop__DEFAULT,
+ ch5_eop, R_SET_EOP__ch5_eop__DEFAULT,
+ ch3_eop, R_SET_EOP__ch3_eop__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Shared_RAM_interface_registers
+ REG_SET__R_SHARED_RAM_ADDR(
+ base_addr, R_SHARED_RAM_ADDR__base_addr__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Shared_RAM_interface_registers
+ REG_SET__R_SHARED_RAM_CONFIG(
+ width, R_SHARED_RAM_CONFIG__width__DEFAULT,
+ enable, R_SHARED_RAM_CONFIG__enable__DEFAULT,
+ pint, R_SHARED_RAM_CONFIG__pint__DEFAULT,
+ clri, R_SHARED_RAM_CONFIG__clri__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Test_mode_registers
+ REG_SET__R_SINGLE_STEP(
+ single_step, R_SINGLE_STEP__single_step__DEFAULT,
+ step_wr, R_SINGLE_STEP__step_wr__DEFAULT,
+ step_rd, R_SINGLE_STEP__step_rd__DEFAULT,
+ step_fetch, R_SINGLE_STEP__step_fetch__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL1_CTRL(
+ tr_baud, R_SYNC_SERIAL1_CTRL__tr_baud__DEFAULT,
+ dma_enable, R_SYNC_SERIAL1_CTRL__dma_enable__DEFAULT,
+ mode, R_SYNC_SERIAL1_CTRL__mode__DEFAULT,
+ error, R_SYNC_SERIAL1_CTRL__error__DEFAULT,
+ rec_enable, R_SYNC_SERIAL1_CTRL__rec_enable__DEFAULT,
+ f_synctype, R_SYNC_SERIAL1_CTRL__f_synctype__DEFAULT,
+ f_syncsize, R_SYNC_SERIAL1_CTRL__f_syncsize__DEFAULT,
+ f_sync, R_SYNC_SERIAL1_CTRL__f_sync__DEFAULT,
+ clk_mode, R_SYNC_SERIAL1_CTRL__clk_mode__DEFAULT,
+ clk_halt, R_SYNC_SERIAL1_CTRL__clk_halt__DEFAULT,
+ bitorder, R_SYNC_SERIAL1_CTRL__bitorder__DEFAULT,
+ tr_enable, R_SYNC_SERIAL1_CTRL__tr_enable__DEFAULT,
+ wordsize, R_SYNC_SERIAL1_CTRL__wordsize__DEFAULT,
+ buf_empty, R_SYNC_SERIAL1_CTRL__buf_empty__DEFAULT,
+ buf_full, R_SYNC_SERIAL1_CTRL__buf_full__DEFAULT,
+ flow_ctrl, R_SYNC_SERIAL1_CTRL__flow_ctrl__DEFAULT,
+ clk_polarity, R_SYNC_SERIAL1_CTRL__clk_polarity__DEFAULT,
+ frame_polarity, R_SYNC_SERIAL1_CTRL__frame_polarity__DEFAULT,
+ status_polarity, R_SYNC_SERIAL1_CTRL__status_polarity__DEFAULT,
+ clk_driver, R_SYNC_SERIAL1_CTRL__clk_driver__DEFAULT,
+ frame_driver, R_SYNC_SERIAL1_CTRL__frame_driver__DEFAULT,
+ status_driver, R_SYNC_SERIAL1_CTRL__status_driver__DEFAULT,
+ def_out0, R_SYNC_SERIAL1_CTRL__def_out0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL1_TR_BYTE(
+ data_out, R_SYNC_SERIAL1_TR_BYTE__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL1_TR_DATA(
+ data_out, R_SYNC_SERIAL1_TR_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL1_TR_WORD(
+ data_out, R_SYNC_SERIAL1_TR_WORD__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL3_CTRL(
+ tr_baud, R_SYNC_SERIAL3_CTRL__tr_baud__DEFAULT,
+ dma_enable, R_SYNC_SERIAL3_CTRL__dma_enable__DEFAULT,
+ mode, R_SYNC_SERIAL3_CTRL__mode__DEFAULT,
+ error, R_SYNC_SERIAL3_CTRL__error__DEFAULT,
+ rec_enable, R_SYNC_SERIAL3_CTRL__rec_enable__DEFAULT,
+ f_synctype, R_SYNC_SERIAL3_CTRL__f_synctype__DEFAULT,
+ f_syncsize, R_SYNC_SERIAL3_CTRL__f_syncsize__DEFAULT,
+ f_sync, R_SYNC_SERIAL3_CTRL__f_sync__DEFAULT,
+ clk_mode, R_SYNC_SERIAL3_CTRL__clk_mode__DEFAULT,
+ clk_halt, R_SYNC_SERIAL3_CTRL__clk_halt__DEFAULT,
+ bitorder, R_SYNC_SERIAL3_CTRL__bitorder__DEFAULT,
+ tr_enable, R_SYNC_SERIAL3_CTRL__tr_enable__DEFAULT,
+ wordsize, R_SYNC_SERIAL3_CTRL__wordsize__DEFAULT,
+ buf_empty, R_SYNC_SERIAL3_CTRL__buf_empty__DEFAULT,
+ buf_full, R_SYNC_SERIAL3_CTRL__buf_full__DEFAULT,
+ flow_ctrl, R_SYNC_SERIAL3_CTRL__flow_ctrl__DEFAULT,
+ clk_polarity, R_SYNC_SERIAL3_CTRL__clk_polarity__DEFAULT,
+ frame_polarity, R_SYNC_SERIAL3_CTRL__frame_polarity__DEFAULT,
+ status_polarity, R_SYNC_SERIAL3_CTRL__status_polarity__DEFAULT,
+ clk_driver, R_SYNC_SERIAL3_CTRL__clk_driver__DEFAULT,
+ frame_driver, R_SYNC_SERIAL3_CTRL__frame_driver__DEFAULT,
+ status_driver, R_SYNC_SERIAL3_CTRL__status_driver__DEFAULT,
+ def_out0, R_SYNC_SERIAL3_CTRL__def_out0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL3_TR_BYTE(
+ data_out, R_SYNC_SERIAL3_TR_BYTE__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL3_TR_DATA(
+ data_out, R_SYNC_SERIAL3_TR_DATA__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Syncrounous_serial_port_registers
+ REG_SET__R_SYNC_SERIAL3_TR_WORD(
+ data_out, R_SYNC_SERIAL3_TR_WORD__data_out__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Timer_registers
+ REG_SET__R_SYNC_SERIAL_PRESCALE(
+ clk_sel_u3, R_SYNC_SERIAL_PRESCALE__clk_sel_u3__DEFAULT,
+ word_stb_sel_u3, R_SYNC_SERIAL_PRESCALE__word_stb_sel_u3__DEFAULT,
+ clk_sel_u1, R_SYNC_SERIAL_PRESCALE__clk_sel_u1__DEFAULT,
+ word_stb_sel_u1, R_SYNC_SERIAL_PRESCALE__word_stb_sel_u1__DEFAULT,
+ prescaler, R_SYNC_SERIAL_PRESCALE__prescaler__DEFAULT,
+ warp_mode, R_SYNC_SERIAL_PRESCALE__warp_mode__DEFAULT,
+ frame_rate, R_SYNC_SERIAL_PRESCALE__frame_rate__DEFAULT,
+ word_rate, R_SYNC_SERIAL_PRESCALE__word_rate__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Test_mode_registers
+ REG_SET__R_TEST_MODE(
+ single_step, R_TEST_MODE__single_step__DEFAULT,
+ step_wr, R_TEST_MODE__step_wr__DEFAULT,
+ step_rd, R_TEST_MODE__step_rd__DEFAULT,
+ step_fetch, R_TEST_MODE__step_fetch__DEFAULT,
+ mmu_test, R_TEST_MODE__mmu_test__DEFAULT,
+ usb_test, R_TEST_MODE__usb_test__DEFAULT,
+ scsi_timer_test, R_TEST_MODE__scsi_timer_test__DEFAULT,
+ backoff, R_TEST_MODE__backoff__DEFAULT,
+ snmp_test, R_TEST_MODE__snmp_test__DEFAULT,
+ snmp_inc, R_TEST_MODE__snmp_inc__DEFAULT,
+ ser_loop, R_TEST_MODE__ser_loop__DEFAULT,
+ baudrate, R_TEST_MODE__baudrate__DEFAULT,
+ timer, R_TEST_MODE__timer__DEFAULT,
+ cache_test, R_TEST_MODE__cache_test__DEFAULT,
+ tag_test, R_TEST_MODE__tag_test__DEFAULT,
+ cache_enable, R_TEST_MODE__cache_enable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Timer_registers
+ REG_SET__R_TIMER_CTRL(
+ timerdiv1, R_TIMER_CTRL__timerdiv1__DEFAULT,
+ timerdiv0, R_TIMER_CTRL__timerdiv0__DEFAULT,
+ presc_timer1, R_TIMER_CTRL__presc_timer1__DEFAULT,
+ i1, R_TIMER_CTRL__i1__DEFAULT,
+ tm1, R_TIMER_CTRL__tm1__DEFAULT,
+ clksel1, R_TIMER_CTRL__clksel1__DEFAULT,
+ presc_ext, R_TIMER_CTRL__presc_ext__DEFAULT,
+ i0, R_TIMER_CTRL__i0__DEFAULT,
+ tm0, R_TIMER_CTRL__tm0__DEFAULT,
+ clksel0, R_TIMER_CTRL__clksel0__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Timer_registers
+ REG_SET__R_TIMER_PRESCALE(
+ tim_presc, R_TIMER_PRESCALE__tim_presc__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__USB_interface_control_registers
+ REG_SET__R_USB_IRQ_MASK_CLR(
+ iso_eof, R_USB_IRQ_MASK_CLR__iso_eof__DEFAULT,
+ intr_eof, R_USB_IRQ_MASK_CLR__intr_eof__DEFAULT,
+ iso_eot, R_USB_IRQ_MASK_CLR__iso_eot__DEFAULT,
+ intr_eot, R_USB_IRQ_MASK_CLR__intr_eot__DEFAULT,
+ ctl_eot, R_USB_IRQ_MASK_CLR__ctl_eot__DEFAULT,
+ bulk_eot, R_USB_IRQ_MASK_CLR__bulk_eot__DEFAULT,
+ epid_attn, R_USB_IRQ_MASK_CLR__epid_attn__DEFAULT,
+ sof, R_USB_IRQ_MASK_CLR__sof__DEFAULT,
+ port_status, R_USB_IRQ_MASK_CLR__port_status__DEFAULT,
+ ctl_status, R_USB_IRQ_MASK_CLR__ctl_status__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__USB_interface_control_registers
+ REG_SET__R_USB_IRQ_MASK_CLR_DEV(
+ out_eot, R_USB_IRQ_MASK_CLR_DEV__out_eot__DEFAULT,
+ ep3_in_eot, R_USB_IRQ_MASK_CLR_DEV__ep3_in_eot__DEFAULT,
+ ep2_in_eot, R_USB_IRQ_MASK_CLR_DEV__ep2_in_eot__DEFAULT,
+ ep1_in_eot, R_USB_IRQ_MASK_CLR_DEV__ep1_in_eot__DEFAULT,
+ ep0_in_eot, R_USB_IRQ_MASK_CLR_DEV__ep0_in_eot__DEFAULT,
+ epid_attn, R_USB_IRQ_MASK_CLR_DEV__epid_attn__DEFAULT,
+ sof, R_USB_IRQ_MASK_CLR_DEV__sof__DEFAULT,
+ port_status, R_USB_IRQ_MASK_CLR_DEV__port_status__DEFAULT,
+ ctl_status, R_USB_IRQ_MASK_CLR_DEV__ctl_status__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__USB_interface_control_registers
+ REG_SET__R_USB_IRQ_MASK_SET(
+ iso_eof, R_USB_IRQ_MASK_SET__iso_eof__DEFAULT,
+ intr_eof, R_USB_IRQ_MASK_SET__intr_eof__DEFAULT,
+ iso_eot, R_USB_IRQ_MASK_SET__iso_eot__DEFAULT,
+ intr_eot, R_USB_IRQ_MASK_SET__intr_eot__DEFAULT,
+ ctl_eot, R_USB_IRQ_MASK_SET__ctl_eot__DEFAULT,
+ bulk_eot, R_USB_IRQ_MASK_SET__bulk_eot__DEFAULT,
+ epid_attn, R_USB_IRQ_MASK_SET__epid_attn__DEFAULT,
+ sof, R_USB_IRQ_MASK_SET__sof__DEFAULT,
+ port_status, R_USB_IRQ_MASK_SET__port_status__DEFAULT,
+ ctl_status, R_USB_IRQ_MASK_SET__ctl_status__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__USB_interface_control_registers
+ REG_SET__R_USB_IRQ_MASK_SET_DEV(
+ out_eot, R_USB_IRQ_MASK_SET_DEV__out_eot__DEFAULT,
+ ep3_in_eot, R_USB_IRQ_MASK_SET_DEV__ep3_in_eot__DEFAULT,
+ ep2_in_eot, R_USB_IRQ_MASK_SET_DEV__ep2_in_eot__DEFAULT,
+ ep1_in_eot, R_USB_IRQ_MASK_SET_DEV__ep1_in_eot__DEFAULT,
+ ep0_in_eot, R_USB_IRQ_MASK_SET_DEV__ep0_in_eot__DEFAULT,
+ epid_attn, R_USB_IRQ_MASK_SET_DEV__epid_attn__DEFAULT,
+ sof, R_USB_IRQ_MASK_SET_DEV__sof__DEFAULT,
+ port_status, R_USB_IRQ_MASK_SET_DEV__port_status__DEFAULT,
+ ctl_status, R_USB_IRQ_MASK_SET_DEV__ctl_status__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__USB_interface_control_registers
+ REG_SET__R_USB_PORT1_DISABLE(
+ disable, R_USB_PORT1_DISABLE__disable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__USB_interface_control_registers
+ REG_SET__R_USB_PORT2_DISABLE(
+ disable, R_USB_PORT2_DISABLE__disable__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_VECT_MASK_CLR(
+ usb, R_VECT_MASK_CLR__usb__DEFAULT,
+ dma9, R_VECT_MASK_CLR__dma9__DEFAULT,
+ dma8, R_VECT_MASK_CLR__dma8__DEFAULT,
+ dma7, R_VECT_MASK_CLR__dma7__DEFAULT,
+ dma6, R_VECT_MASK_CLR__dma6__DEFAULT,
+ dma5, R_VECT_MASK_CLR__dma5__DEFAULT,
+ dma4, R_VECT_MASK_CLR__dma4__DEFAULT,
+ dma3, R_VECT_MASK_CLR__dma3__DEFAULT,
+ dma2, R_VECT_MASK_CLR__dma2__DEFAULT,
+ dma1, R_VECT_MASK_CLR__dma1__DEFAULT,
+ dma0, R_VECT_MASK_CLR__dma0__DEFAULT,
+ ext_dma1, R_VECT_MASK_CLR__ext_dma1__DEFAULT,
+ ext_dma0, R_VECT_MASK_CLR__ext_dma0__DEFAULT,
+ pa, R_VECT_MASK_CLR__pa__DEFAULT,
+ irq_intnr, R_VECT_MASK_CLR__irq_intnr__DEFAULT,
+ sw, R_VECT_MASK_CLR__sw__DEFAULT,
+ serial, R_VECT_MASK_CLR__serial__DEFAULT,
+ snmp, R_VECT_MASK_CLR__snmp__DEFAULT,
+ network, R_VECT_MASK_CLR__network__DEFAULT,
+ scsi1, R_VECT_MASK_CLR__scsi1__DEFAULT,
+ scsi0, R_VECT_MASK_CLR__scsi0__DEFAULT,
+ timer1, R_VECT_MASK_CLR__timer1__DEFAULT,
+ timer0, R_VECT_MASK_CLR__timer0__DEFAULT,
+ nmi, R_VECT_MASK_CLR__nmi__DEFAULT,
+ some, R_VECT_MASK_CLR__some__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ REG_SET__R_VECT_MASK_SET(
+ usb, R_VECT_MASK_SET__usb__DEFAULT,
+ dma9, R_VECT_MASK_SET__dma9__DEFAULT,
+ dma8, R_VECT_MASK_SET__dma8__DEFAULT,
+ dma7, R_VECT_MASK_SET__dma7__DEFAULT,
+ dma6, R_VECT_MASK_SET__dma6__DEFAULT,
+ dma5, R_VECT_MASK_SET__dma5__DEFAULT,
+ dma4, R_VECT_MASK_SET__dma4__DEFAULT,
+ dma3, R_VECT_MASK_SET__dma3__DEFAULT,
+ dma2, R_VECT_MASK_SET__dma2__DEFAULT,
+ dma1, R_VECT_MASK_SET__dma1__DEFAULT,
+ dma0, R_VECT_MASK_SET__dma0__DEFAULT,
+ ext_dma1, R_VECT_MASK_SET__ext_dma1__DEFAULT,
+ ext_dma0, R_VECT_MASK_SET__ext_dma0__DEFAULT,
+ pa, R_VECT_MASK_SET__pa__DEFAULT,
+ irq_intnr, R_VECT_MASK_SET__irq_intnr__DEFAULT,
+ sw, R_VECT_MASK_SET__sw__DEFAULT,
+ serial, R_VECT_MASK_SET__serial__DEFAULT,
+ snmp, R_VECT_MASK_SET__snmp__DEFAULT,
+ network, R_VECT_MASK_SET__network__DEFAULT,
+ scsi1, R_VECT_MASK_SET__scsi1__DEFAULT,
+ scsi0, R_VECT_MASK_SET__scsi0__DEFAULT,
+ timer1, R_VECT_MASK_SET__timer1__DEFAULT,
+ timer0, R_VECT_MASK_SET__timer0__DEFAULT,
+ nmi, R_VECT_MASK_SET__nmi__DEFAULT,
+ some, R_VECT_MASK_SET__some__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Bus_interface_configuration_registers
+ REG_SET__R_WAITSTATES(
+ pcs4_7_zw, R_WAITSTATES__pcs4_7_zw__DEFAULT,
+ pcs4_7_ew, R_WAITSTATES__pcs4_7_ew__DEFAULT,
+ pcs4_7_lw, R_WAITSTATES__pcs4_7_lw__DEFAULT,
+ pcs0_3_zw, R_WAITSTATES__pcs0_3_zw__DEFAULT,
+ pcs0_3_ew, R_WAITSTATES__pcs0_3_ew__DEFAULT,
+ pcs0_3_lw, R_WAITSTATES__pcs0_3_lw__DEFAULT,
+ sram_zw, R_WAITSTATES__sram_zw__DEFAULT,
+ sram_ew, R_WAITSTATES__sram_ew__DEFAULT,
+ sram_lw, R_WAITSTATES__sram_lw__DEFAULT,
+ flash_zw, R_WAITSTATES__flash_zw__DEFAULT,
+ flash_ew, R_WAITSTATES__flash_ew__DEFAULT,
+ flash_lw, R_WAITSTATES__flash_lw__DEFAULT
+ );
+#endif
+
+#if USE_GROUP__Timer_registers
+ REG_SET__R_WATCHDOG(
+ key, R_WATCHDOG__key__DEFAULT,
+ enable, R_WATCHDOG__enable__DEFAULT
+ );
+#endif
+#endif
+} /* init_shadow__hwregs */
--- /dev/null
+/*!**********************************************************************
+*!
+*! FILE NAME: hwregs.h
+*!
+*! DESCRIPTION: Interface to shadow registers.
+*!
+*! FUNCTIONS: none
+*!
+*! NOTE: This file is automatically generated, do _not_ edit.
+*! Created: Thu Oct 3 01:21:27 2002
+*! By: Id: shadow_gen,v 1.14 2002/10/02 20:31:22 hp Exp
+*! From: /n/asic/projects/etrax_ng/doc/work/etrax_ng_regs.rd 1.168
+*! /n/asic/projects/etrax_ng/include//hwregs.ctrl 1.3
+*!
+*! MACROS: REG_GET
+*! REG_IGET
+*! REG_VGET
+*! REG_SET
+*! REG_ISET
+*! REG_VSET
+*! REG_SET_VAL
+*! REG_SET__register-name (one for each register)
+*! REG_SET__register-name__SHADOW (one for each register)
+*! REG_MASK__register-name (one for each register)
+*! REG_VAL__register-name (one for each register)
+*! REG_EQL
+*! REG_IEQL
+*! REG_VEQL
+*! REG_VAL
+*! REG_CHK_VAL
+*! REG_RD
+*! REG_IRD
+*! REG_WR
+*! REG_IWR
+*! REG_ADDR
+*! REG_BITNR
+*!
+*!----------------------------------------------------------------------
+*! HISTORY
+*!
+*! DATE NAME CHANGES
+*! ---- ---- -------
+*! Apr 01 1998 Jan Bengtsson Initial version
+*! Oct 01 2002 Hans-Peter Nilsson Large mechanical changes to correct
+*! use of the ## operator.
+*!----------------------------------------------------------------------
+*!
+*! (C) Copyright 1998, 2002 Axis Communications AB, LUND, SWEDEN
+*!
+*!**********************************************************************/
+/* %Z% %M% %I% %G% */
+
+#ifndef __HWREGS_H__
+#define __HWREGS_H__
+
+/********************** INCLUDE FILES SECTION **************************/
+#ifndef __ASSEMBLER__
+#include "compiler.h"
+#include "debug.h"
+#endif /* __ASSEMBLER__ */
+
+#include "project.h"
+#include "hwregs_def.h"
+
+#ifndef __ASSEMBLER__
+
+#ifndef __REG_GENERAL_1_H__
+#define __REG_GENERAL_1_H__
+
+/*
+** This part of hwregs.h is common to all shadow
+** register modules, and should therefore only be included once to
+** avoid macro redefinitions.
+*/
+
+/* REG_DEBUG is by default controlled by DEBUG from debug.h. */
+#ifndef REG_DEBUG
+#ifdef DEBUG
+#define REG_DEBUG 1
+#else
+#define REG_DEBUG 0
+#endif /* DEBUG */
+#endif /* REG_DEBUG */
+
+#endif /* __REG_GENERAL_1_H__ */
+
+#endif /* __ASSEMBLER__ */
+
+/********************** TYPE DEFINITION SECTION ************************/
+#ifndef __ASSEMBLER__
+
+#ifndef REG_NO_SHADOW
+
+/* Only write only registers need a shadow register. */
+
+typedef struct {
+#if USE_GROUP__Bus_interface_configuration_registers
+ byte R_WAITSTATES[4];
+ byte R_BUS_CONFIG[4];
+ byte R_DRAM_TIMING[4];
+ byte R_DRAM_CONFIG[4];
+#endif
+#if USE_GROUP__External_DMA_registers
+ byte R_EXT_DMA_0_CMD[4];
+ byte R_EXT_DMA_0_ADDR[4];
+ byte R_EXT_DMA_1_CMD[4];
+ byte R_EXT_DMA_1_ADDR[4];
+#endif
+#if USE_GROUP__Timer_registers
+ byte R_TIMER_CTRL[4];
+ byte R_WATCHDOG[4];
+#endif
+#if USE_GROUP__General_config_registers
+ byte R_GEN_CONFIG[4];
+#endif
+#if USE_GROUP__General_port_configuration_registers
+ byte R_PORT_PA_SET[4];
+#endif
+#if USE_GROUP__General_config_registers
+ byte R_GEN_CONFIG_II[4];
+#endif
+#if USE_GROUP__General_port_configuration_registers
+ byte R_PORT_PB_SET[4];
+#endif
+#if USE_GROUP__DMA_registers
+ byte R_SET_EOP[4];
+#endif
+#if USE_GROUP__ATA_interface_registers || \
+ USE_GROUP__Parallel_printer_port_registers || \
+ USE_GROUP__SCSI_registers || \
+ USE_GROUP__Shared_RAM_interface_registers
+ byte R_ATA_CTRL_DATA[4];
+ byte R_ATA_CONFIG[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers
+ byte R_PAR0_DELAY[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers || \
+ USE_GROUP__SCSI_registers || \
+ USE_GROUP__USB_interface_control_registers
+ byte R_PAR1_CTRL_DATA[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers || \
+ USE_GROUP__SCSI_registers
+ byte R_PAR1_CONFIG[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers
+ byte R_PAR1_DELAY[4];
+#endif
+#if USE_GROUP__Serial_port_registers
+ byte R_ALT_SER_BAUDRATE[4];
+ byte R_SERIAL0_CTRL[4];
+ byte R_SERIAL0_XOFF[4];
+#endif
+#if USE_GROUP__Serial_port_registers || \
+ USE_GROUP__Syncrounous_serial_port_registers || \
+ USE_GROUP__USB_interface_control_registers
+ byte R_SERIAL1_CTRL[4];
+#endif
+#if USE_GROUP__Serial_port_registers || \
+ USE_GROUP__Syncrounous_serial_port_registers
+ byte R_SERIAL1_XOFF[4];
+#endif
+#if USE_GROUP__Serial_port_registers
+ byte R_SERIAL2_CTRL[4];
+ byte R_SERIAL2_XOFF[4];
+#endif
+#if USE_GROUP__Serial_port_registers || \
+ USE_GROUP__Syncrounous_serial_port_registers
+ byte R_SERIAL3_CTRL[4];
+ byte R_SERIAL3_XOFF[4];
+#endif
+#if USE_GROUP__Network_interface_registers
+ byte R_NETWORK_SA_0[4];
+ byte R_NETWORK_SA_1[4];
+ byte R_NETWORK_SA_2[4];
+ byte R_NETWORK_GA_0[4];
+ byte R_NETWORK_GA_1[4];
+ byte R_NETWORK_REC_CONFIG[4];
+ byte R_NETWORK_GEN_CONFIG[4];
+ byte R_NETWORK_TR_CTRL[4];
+ byte R_NETWORK_MGM_CTRL[4];
+#endif
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ byte R_IRQ_MASK0_CLR[4];
+ byte R_IRQ_MASK0_SET[4];
+ byte R_IRQ_MASK1_CLR[4];
+ byte R_IRQ_MASK1_SET[4];
+ byte R_IRQ_MASK2_CLR[4];
+ byte R_IRQ_MASK2_SET[4];
+ byte R_VECT_MASK_CLR[4];
+ byte R_VECT_MASK_SET[4];
+#endif
+#if USE_GROUP__Timer_registers
+ byte R_CLOCK_PRESCALE[4];
+ byte R_SYNC_SERIAL_PRESCALE[4];
+#endif
+#if USE_GROUP__Test_mode_registers
+ byte R_TEST_MODE[4];
+#endif
+#if USE_GROUP__DMA_registers
+ byte R_DMA_CH0_CLR_INTR[1];
+ byte R_DMA_CH1_CLR_INTR[1];
+ byte R_DMA_CH2_CLR_INTR[1];
+ byte R_DMA_CH3_CLR_INTR[1];
+ byte R_DMA_CH4_CLR_INTR[1];
+ byte R_DMA_CH8_SUB0_CLR_INTR[1];
+ byte R_DMA_CH5_CLR_INTR[1];
+ byte R_DMA_CH8_SUB1_CLR_INTR[1];
+ byte R_DMA_CH6_CLR_INTR[1];
+ byte R_DMA_CH8_SUB2_CLR_INTR[1];
+ byte R_DMA_CH7_CLR_INTR[1];
+ byte R_DMA_CH8_SUB3_CLR_INTR[1];
+ byte R_DMA_CH8_CLR_INTR[1];
+ byte R_DMA_CH9_CLR_INTR[1];
+#endif
+#if USE_GROUP__USB_interface_control_registers
+ byte R_USB_IRQ_MASK_SET[2];
+ byte R_USB_IRQ_MASK_CLR[2];
+#endif
+#if USE_GROUP__MMU_registers
+ byte R_MMU_CONFIG[4];
+ byte R_MMU_KBASE_LO[4];
+ byte R_MMU_KBASE_HI[4];
+#endif
+} reg_shadow_type__hwregs;
+
+#else /* REG_NO_SHADOW */
+
+typedef const udword reg_shadow_type__hwregs;
+
+#endif /* REG_NO_SHADOW */
+
+extern reg_shadow_type__hwregs reg_shadow__hwregs;
+
+#if REG_DEBUG
+
+/*
+ * Only write only registers need an initiated flag.
+ * Flag is set to all ones at startup, and cleared to
+ * zero when initiated.
+ */
+
+#ifndef REG_NO_SHADOW
+
+typedef struct {
+#if USE_GROUP__Bus_interface_configuration_registers
+ byte R_WAITSTATES[4];
+ byte R_BUS_CONFIG[4];
+ byte R_DRAM_TIMING[4];
+ byte R_DRAM_CONFIG[4];
+#endif
+#if USE_GROUP__External_DMA_registers
+ byte R_EXT_DMA_0_CMD[4];
+ byte R_EXT_DMA_0_ADDR[4];
+ byte R_EXT_DMA_1_CMD[4];
+ byte R_EXT_DMA_1_ADDR[4];
+#endif
+#if USE_GROUP__Timer_registers
+ byte R_TIMER_CTRL[4];
+ byte R_WATCHDOG[4];
+#endif
+#if USE_GROUP__General_config_registers
+ byte R_GEN_CONFIG[4];
+#endif
+#if USE_GROUP__General_port_configuration_registers
+ byte R_PORT_PA_SET[4];
+#endif
+#if USE_GROUP__General_config_registers
+ byte R_GEN_CONFIG_II[4];
+#endif
+#if USE_GROUP__General_port_configuration_registers
+ byte R_PORT_PB_SET[4];
+#endif
+#if USE_GROUP__DMA_registers
+ byte R_SET_EOP[4];
+#endif
+#if USE_GROUP__ATA_interface_registers || \
+ USE_GROUP__Parallel_printer_port_registers || \
+ USE_GROUP__SCSI_registers || \
+ USE_GROUP__Shared_RAM_interface_registers
+ byte R_ATA_CTRL_DATA[4];
+ byte R_ATA_CONFIG[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers
+ byte R_PAR0_DELAY[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers || \
+ USE_GROUP__SCSI_registers || \
+ USE_GROUP__USB_interface_control_registers
+ byte R_PAR1_CTRL_DATA[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers || \
+ USE_GROUP__SCSI_registers
+ byte R_PAR1_CONFIG[4];
+#endif
+#if USE_GROUP__Parallel_printer_port_registers
+ byte R_PAR1_DELAY[4];
+#endif
+#if USE_GROUP__Serial_port_registers
+ byte R_ALT_SER_BAUDRATE[4];
+ byte R_SERIAL0_CTRL[4];
+ byte R_SERIAL0_XOFF[4];
+#endif
+#if USE_GROUP__Serial_port_registers || \
+ USE_GROUP__Syncrounous_serial_port_registers || \
+ USE_GROUP__USB_interface_control_registers
+ byte R_SERIAL1_CTRL[4];
+#endif
+#if USE_GROUP__Serial_port_registers || \
+ USE_GROUP__Syncrounous_serial_port_registers
+ byte R_SERIAL1_XOFF[4];
+#endif
+#if USE_GROUP__Serial_port_registers
+ byte R_SERIAL2_CTRL[4];
+ byte R_SERIAL2_XOFF[4];
+#endif
+#if USE_GROUP__Serial_port_registers || \
+ USE_GROUP__Syncrounous_serial_port_registers
+ byte R_SERIAL3_CTRL[4];
+ byte R_SERIAL3_XOFF[4];
+#endif
+#if USE_GROUP__Network_interface_registers
+ byte R_NETWORK_SA_0[4];
+ byte R_NETWORK_SA_1[4];
+ byte R_NETWORK_SA_2[4];
+ byte R_NETWORK_GA_0[4];
+ byte R_NETWORK_GA_1[4];
+ byte R_NETWORK_REC_CONFIG[4];
+ byte R_NETWORK_GEN_CONFIG[4];
+ byte R_NETWORK_TR_CTRL[4];
+ byte R_NETWORK_MGM_CTRL[4];
+#endif
+#if USE_GROUP__Interrupt_mask_and_status_registers
+ byte R_IRQ_MASK0_CLR[4];
+ byte R_IRQ_MASK0_SET[4];
+ byte R_IRQ_MASK1_CLR[4];
+ byte R_IRQ_MASK1_SET[4];
+ byte R_IRQ_MASK2_CLR[4];
+ byte R_IRQ_MASK2_SET[4];
+ byte R_VECT_MASK_CLR[4];
+ byte R_VECT_MASK_SET[4];
+#endif
+#if USE_GROUP__Timer_registers
+ byte R_CLOCK_PRESCALE[4];
+ byte R_SYNC_SERIAL_PRESCALE[4];
+#endif
+#if USE_GROUP__Test_mode_registers
+ byte R_TEST_MODE[4];
+#endif
+#if USE_GROUP__DMA_registers
+ byte R_DMA_CH0_CLR_INTR[1];
+ byte R_DMA_CH1_CLR_INTR[1];
+ byte R_DMA_CH2_CLR_INTR[1];
+ byte R_DMA_CH3_CLR_INTR[1];
+ byte R_DMA_CH4_CLR_INTR[1];
+ byte R_DMA_CH8_SUB0_CLR_INTR[1];
+ byte R_DMA_CH5_CLR_INTR[1];
+ byte R_DMA_CH8_SUB1_CLR_INTR[1];
+ byte R_DMA_CH6_CLR_INTR[1];
+ byte R_DMA_CH8_SUB2_CLR_INTR[1];
+ byte R_DMA_CH7_CLR_INTR[1];
+ byte R_DMA_CH8_SUB3_CLR_INTR[1];
+ byte R_DMA_CH8_CLR_INTR[1];
+ byte R_DMA_CH9_CLR_INTR[1];
+#endif
+#if USE_GROUP__USB_interface_control_registers
+ byte R_USB_IRQ_MASK_SET[2];
+ byte R_USB_IRQ_MASK_CLR[2];
+#endif
+#if USE_GROUP__MMU_registers
+ byte R_MMU_CONFIG[4];
+ byte R_MMU_KBASE_LO[4];
+ byte R_MMU_KBASE_HI[4];
+#endif
+} reg_initiated_type__hwregs;
+
+#else /* REG_NO_SHADOW */
+
+typedef const udword reg_initiated_type__hwregs;
+
+#endif /* REG_NO_SHADOW */
+
+extern reg_initiated_type__hwregs reg_initiated__hwregs;
+
+#endif /* REG_DEBUG */
+
+extern void init_shadow__hwregs();
+
+#endif /* __ASSEMBLER__ */
+
+
+/********************** CONSTANT AND MACRO SECTION *********************/
+#ifndef __REG_GENERAL_2_H__
+#define __REG_GENERAL_2_H__
+
+/*
+** This part of hwregs.h is common to all shadow
+** register modules, and should therefore only be included once to
+** avoid macro redefinitions.
+*/
+
+#ifndef __ASSEMBLER__
+
+/*
+ * Register type-casts
+ */
+#define REG_TYPECAST_UDWORD (volatile udword*)
+#define REG_TYPECAST_RO_UDWORD (const volatile udword*)
+#define REG_TYPECAST_UWORD (volatile uword*)
+#define REG_TYPECAST_RO_UWORD (const volatile uword*)
+#define REG_TYPECAST_BYTE (volatile byte*)
+#define REG_TYPECAST_RO_BYTE (const volatile byte*)
+
+/*
+ * Shadow register type-casts
+ */
+#define REG_STYPECAST_UDWORD (udword*)
+#define REG_STYPECAST_UWORD (uword*)
+#define REG_STYPECAST_BYTE (byte*)
+
+#else
+
+/*
+ * Register type-casts
+ */
+#define REG_TYPECAST_UDWORD
+#define REG_TYPECAST_RO_UDWORD
+#define REG_TYPECAST_UWORD
+#define REG_TYPECAST_RO_UWORD
+#define REG_TYPECAST_BYTE
+#define REG_TYPECAST_RO_BYTE
+
+/*
+ * Shadow register type-casts
+ */
+#define REG_STYPECAST_UDWORD
+#define REG_STYPECAST_UWORD
+#define REG_STYPECAST_BYTE
+
+#endif
+
+
+#define REG_UDWORD udword
+#define REG_UWORD uword
+#define REG_BYTE byte
+
+#define REG__on 0xffffffffU
+#define REG__off 0
+
+#endif /* __REG_GENERAL_2_H__ */
+
+#include "hwregs_int.h"
+
+#ifndef __REG_GENERAL_3_H__
+#define __REG_GENERAL_3_H__
+
+/*
+** This part of hwregs.h is common to all shadow
+** register modules, and should therefore only be included once to
+** avoid macro redefinitions.
+*/
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_GET
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*#
+*# RETURNS : Value of field field in register reg.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR.
+*#
+*# DESCRIPTION : Read a field in a register. Also see description
+*# of REG_GET_WO, REG_GET_RO, and REG_GET_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_GET(reg,field) ( \
+ reg##__GET(reg##_, field##_) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_IGET
+*#
+*# PARAMETERS : i : Interface number.
+*# reg : Name of a register.
+*# field : Name of a field.
+*#
+*# RETURNS : Value of field field in register reg.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR, and REG_IERROR.
+*#
+*# DESCRIPTION : Read a field in a register for interface i.
+*# Also see description of REG_IGET_WO, REG_IGET_RO,
+*# and REG_IGET_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_IGET(i,reg,field) ( \
+ reg##__IGET(i, reg##_, field##_) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_VGET
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# var : Variable or value to read from.
+*#
+*# RETURNS : Value of field field in variable var.
+*#
+*# SIDE EFFECTS: None.
+*#
+*# DESCRIPTION : Interprets variable var as register reg, and read field
+*# field from variable var.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*#**********************************************************************/
+
+#define REG_VGET(reg,field,var) ( \
+ ((reg##__TYPE var) & reg##__##field##__##field##__MASK) >> \
+ reg##__##field##__BITNR \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_SET
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : Value to write to field.
+*#
+*# RETURNS : Integer value written to complete register.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR and REG_VERROR.
+*#
+*# DESCRIPTION : Write val parameter to field field in register reg.
+*# Parameter reg must be a write only or read write
+*# register. Also see description of REG_SET_WO, and
+*# REG_SET_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_SET(reg,field,val) ( \
+ reg##__SET(reg##_, field##_, val) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_ISET
+*#
+*# PARAMETERS : i : Interface number.
+*# reg : Name of a register.
+*# field : Name of a field.
+*# val : Value to write to field.
+*#
+*# RETURNS : Integer value written to complete register.
+*#
+*# SIDE EFFECTS: May evaluate REG_IERROR, REG_SERROR, and REG_VERROR.
+*#
+*# DESCRIPTION : Write val parameter to field field in register reg
+*# of interface i. Parameter reg must be a write only
+*# or read write register. Also see description of
+*# REG_ISET_WO, and REG_ISET_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_ISET(i,reg,field,val) ( \
+ reg##__ISET(i, reg##_, field##_, val) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_VSET
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : Value to write to field.
+*# var : Variable to write to.
+*#
+*# RETURNS : Integer value of variable var after write.
+*#
+*# SIDE EFFECTS: May evaluate REG_VERROR.
+*#
+*# DESCRIPTION : Interpret variable var as register reg, and write val
+*# parameter to field field in variable var.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_VSET(reg,field,val,var) ( \
+ var = \
+ ((reg##__TYPE var) & REG_IMASK (reg##_, field##_)) | \
+ (reg##__##field##__##field##__VAL(reg##_, field##_, val) << \
+ reg##__##field##__BITNR) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_SET_VAL
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : Integer value to write to symbolic field.
+*#
+*# RETURNS : Integer value written to complete register.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR and REG_VERROR.
+*#
+*# DESCRIPTION : Write val parameter to field field in register reg.
+*# Parameter reg must be a write only or read write register.
+*# Also see description of REG_SET_VAL_WO, and REG_SET_VAL_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_SET_VAL(reg,field,val) ( \
+ reg##__SET_VAL(reg##_, field##_, val) \
+)
+
+/*
+ * See end of file for these.
+ *
+ * #define REG_SET__register-name
+ * #define REG_SET__register-name__SHADOW
+ * #define REG_MASK__register-name
+ * #define REG_VAL__register-name
+ */
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_EQL
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : Value to compare with field.
+*#
+*# RETURNS : TRUE, FALSE
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR and REG_VERROR.
+*#
+*# DESCRIPTION : Compare val parameter with field field in register reg.
+*# Also description of REG_EQL_WO, REG_EQL_RO, and
+*# REG_EQL_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+#define REG_EQL(reg,field,val) ( \
+ reg##__EQL(reg##_, field##_, val) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_IEQL
+*#
+*# PARAMETERS : i : Interface number.
+*# reg : Name of a register.
+*# field : Name of a field.
+*# val : Value to compare with field.
+*#
+*# RETURNS : TRUE, FALSE
+*#
+*# SIDE EFFECTS: May evaluate REG_VERROR, REG_IERROR, and REG_SERROR.
+*#
+*# DESCRIPTION : Compare val parameter with field field in register reg
+*# of interface i. Also see description of REG_IEQL_WO,
+*# REG_IEQ_RO, and REG_IEQL_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_IEQL(i,reg,field,val) ( \
+ reg##__IEQL(i,reg##_,field##_,val) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_VEQL
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : Value to compare with field.
+*# var : Variable (or value) to compare with.
+*#
+*# RETURNS : TRUE, FALSE
+*#
+*# SIDE EFFECTS: May evaluate REG_VERROR.
+*#
+*# DESCRIPTION : Interprets variable var as register reg, and compare
+*# compare field field with parameter val.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_VEQL(reg,field,val,var) ( \
+ ( ((reg##__TYPE (var)) & reg##__##field##__##field##__MASK) >> \
+ reg##__##field##__BITNR \
+ ) == reg##__##field##__##field##__VAL(reg##_, field##_, val) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_VAL
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : A symbolic constant.
+*#
+*# RETURNS : val or (val << REG_VERROR()) macro.
+*#
+*# SIDE EFFECTS: May evaluate REG_VERROR macro.
+*#
+*# DESCRIPTION : Convert a symbolic constant to an integer value.
+*# Intended to be used for enumerated fields. Also
+*# Also works for value fields, in which case the val
+*# parameter is checked for range and returned if OK,
+*# and if val is out of range (val << REG_VERROR) is
+*# returned. Also see description of REG_VAL_VAL, and
+*# REG_VAL_ENUM.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg and field parameters when
+*# passing on to other macros.
+*#**********************************************************************/
+
+#define REG_VAL(reg,field,val) ( \
+ reg##__##field##__##field##__VAL(reg##_, field##_, val) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_CHK_VAL
+*#
+*# PARAMETERS : reg : Name of a register.
+*# field : Name of a field.
+*# val : An integer value.
+*#
+*# RETURNS : 1 if val is within allowed range for field, otherwise 0.
+*#
+*# SIDE EFFECTS: None.
+*#
+*# DESCRIPTION : Check if parameter val is within the field range,
+*# and return 1 if it is, otherwise 0.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*#**********************************************************************/
+
+#define REG_CHK_VAL(reg,field,val) ( \
+ (udword)(~(val)) <= (udword)(~(reg##__##field##__MIN)) && \
+ (udword)(val) <= (udword)(reg##__##field##__MAX) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_RD
+*#
+*# PARAMETERS : reg : Name of a register.
+*#
+*# RETURNS : Contents of register reg.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR.
+*#
+*# DESCRIPTION : Read contents of register reg. Also see description of
+*# REG_RD_WO, REG_RD_RO, and REG_RD_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg parameter when passing
+*# on to other macros.
+*#**********************************************************************/
+
+#define REG_RD(reg) ( \
+ reg##__RD(reg##_) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_IRD
+*#
+*# PARAMETERS : i : Interface number.
+*# reg : Name of a register.
+*#
+*# RETURNS : Contents of register reg.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR and REG_IERROR.
+*#
+*# DESCRIPTION : Read contents of register reg. Also see description of
+*# REG_IRD_WO, REG_IRD_RO, and REG_IRD_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg parameter when passing
+*# on to other macros.
+*#**********************************************************************/
+
+#define REG_IRD(i,reg) ( \
+ reg##__IRD(i,reg##_) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_WR
+*#
+*# PARAMETERS : reg : Name of a register.
+*# var : Variable (or value) to write to reg.
+*#
+*# RETURNS : integer value written to register reg.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR.
+*#
+*# DESCRIPTION : Write value of var parameter to register reg. Also see
+*# description of REG_WR_WO, and REG_WR_RW.
+*#
+*#----------------------------------------------------------------------
+*# HISTORY
+*#
+*# DATE NAME CHANGES
+*# ---- ---- -------
+*# Apr 01 1998 Jan Bengtsson Initial version
+*# Oct 01 2002 Hans-Peter Nilsson To stop premature evaluation, append
+*# _ to reg parameter when passing
+*# on to other macros.
+*#**********************************************************************/
+
+#define REG_WR(reg,var) ( \
+ reg##__WR(reg##_,var) \
+)
+
+/*#**********************************************************************
+*#
+*# MACRO NAME : REG_IWR
+*#
+*# PARAMETERS : i : Interface number.
+*# reg : Name of a register.
+*# var : Variable (or value) to write to reg.
+*#
+*# RETURNS : integer value written to register reg.
+*#
+*# SIDE EFFECTS: May evaluate REG_SERROR.
+*#
+*# DESCRIPTION : Write value of var parameter to register reg of
+*# interface i.&