Open Issues:
======================================================================
+* Enabling too many BOOTP Vendor Extensions easily overflows the 64
+ byte limit imposed by the BOOTP header definition. While this is
+ not a problem on our side, some DHCP servers will complain. Should
+ we break up long BOOTP requests into several shorter ones?
+
* Boot with RAMDisk:
No need to copy ramdisk image when it's already in RAM ??? Or do we
Modifications for 0.6.3:
======================================================================
+* Added support for MBX860T (thanks to Rob Taylor)
+
+* Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+ Work In Progress (TM); current status: boots to command line input.
+ EPIC code non-functional (interrupts disabled), No net, No IDE.
+
+* Add support for Status LED
+
+* Optionally panic() to reboot instead of hanging
+
* Misc bug fixes
* All frequencies in HZ now (internally)
N: Paolo Scaffardi
E: arsenio@tin.it
-D: FADS823 configuration, MPC823 video support, I2C, wireless keyboard
+D: FADS823 configuration, MPC823 video support, I2C, wireless keyboard, lots more
+
+N: Rob Taylor
+E: robt@flyingpig.com
+D: Port to MBX860T and Sandpoint8240
N: Christian Vejlbo
E: christian.vejlbo@tellabs.com
CPCI405 ADCIOP \
cogent_mpc8xx \
GENIETV \
- cogent_mpc8260 hymod
+ cogent_mpc8260 hymod \
+ Sandpoint8240
do
make distclean >/dev/null
make ${i}_config
echo "CPU = mpc8xx" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >config.h
+MBX860T_config: unconfig
+ @echo "Configuring for $(@:_config=) Board..." ; \
+ cd include ; \
+ echo "ARCH = ppc" > config.mk ; \
+ echo "BOARD = mbx" >>config.mk ; \
+ echo "CPU = mpc8xx" >>config.mk ; \
+ echo "#include <config_$(@:_config=).h>" >config.h
+
+Sandpoint8240_config: unconfig
+ @echo "Configuring for $(@:_config=) Board..." ; \
+ cd include ; \
+ echo "ARCH = ppc" > config.mk ; \
+ echo "BOARD = sandpoint" >>config.mk ; \
+ echo "CPU = mpc8240" >>config.mk ; \
+ echo "#include <config_$(@:_config=).h>" >config.h
+
hymod_config: unconfig
@echo "Configuring for $(@:_config=) Board..." ; \
cd include ; \
- ppc Files generic to PowerPC architecture
- tools Tools to build S-Record or PPCBoot images, etc.
-- mpc8xx Files specific to Motorola MPC8xx CPUs
-- ppc4xx Files specific to IBM 4xx CPUs
+- mpc8xx Files specific to Motorola MPC8xx CPUs
+- mpc8240 Files specific to Motorola MPC8240 CPU
+- mpc8260 Files specific to Motorola MPC8260 CPU
+- ppc4xx Files specific to IBM 4xx CPUs
- adciop Files specific to ADCIOP boards
- cogent Files specific to Cogent boards
(need further configuration)
- cpci405 Files specific to CPCI405 boards
- etx094 Files specific to ETX_094 boards
-- fads Files specific to Motorola FADS boards
+- fads Files specific to FADS boards
- genietv Files specific to GENIETV boards
- hymod Files specific to HYMOD boards
- ivms8 Files specific to IVMS8 boards
-- mbx8xx Files specific to Motorola MBX boards
+- mbx8xx Files specific to MBX boards
- spd8xx Files specific to SPD8xxTS boards
+- sandpoint Files specific to Sandpoint boards
- tqm8xx Files specific to TQM8xxL boards
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#include <kgdb.h>
#endif
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
#include <version.h>
static char *failed = "*** failed ***\n";
* Enable Interrupts
*/
interrupt_init (bd);
+#ifdef CONFIG_STATUS_LED
+ status_led_set (STATUS_LED_BLINKING);
+#endif
udelay(20);
*/
#include <mpc8xx_irq.h>
#include <ppcboot.h>
-#include <config.h> /* for PIO mode selection */
+#include <config.h>
#include <command.h>
#include <image.h>
#ifdef CONFIG_IDE_PCMCIA
# define __ldiv_t_defined 1
#endif
-#ifdef DEBUG
+#undef IDE_DEBUG
+
+#ifdef IDE_DEBUG
#define PRINTF(fmt,args...) do { \
printf (fmt ,##args); \
} while (0)
/* ------------------------------------------------------------------------- */
-#ifdef CONFIG_IDE_PCMCIA
-/*
- * Allow configuration to select PCMCIA slot,
- * or try to generate a useful default
- */
-#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
-
- /* The RPX series use SLOT_B */
-#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
-# define CONFIG_PCMCIA_SLOT_B
-#elif defined(CONFIG_ADS) /* The ADS board use SLOT_A */
-# define CONFIG_PCMCIA_SLOT_A
-#elif defined(CONFIG_FADS) /* The FADS series are a mess */
-# if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
-# define CONFIG_PCMCIA_SLOT_A
-# else
-# define CONFIG_PCMCIA_SLOT_B
-# endif
-#elif defined(CONFIG_TQM860L) || defined(CONFIG_TQM855L) /* The TQM8xxL modules */
-# define CONFIG_PCMCIA_SLOT_A /* ... use SLOT_A on MPC860/855 */
-#elif defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
-# define CONFIG_PCMCIA_SLOT_B /* ... and SLOT_B else */
-#elif defined(CONFIG_SPD823TS) /* The SPD8xx use SLOT_B */
-# define CONFIG_PCMCIA_SLOT_B
-#else
-# error "PCMCIA Slot not configured"
-#endif
-
-#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
-
-/* Make sure exactly one slot is defined - we support only one for now */
-#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
-#error Neither CONFIG_PCMCIA_SLOT_A nor CONFIG_PCMCIA_SLOT_B configured
-#endif
-#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
-#error Both CONFIG_PCMCIA_SLOT_A and CONFIG_PCMCIA_SLOT_B configured
-#endif
-
-#define PCMCIA_SOCKETS_NO 1
-#define PCMCIA_MEM_WIN_NO 4
-#define PCMCIA_IO_WIN_NO 2
-
-/* define _slot_ to be able to optimize macros */
-#ifdef CONFIG_PCMCIA_SLOT_A
-# define _slot_ 0
-# define PCMCIA_SLOT_MSG "SLOT_A"
-#else
-# define _slot_ 1
-# define PCMCIA_SLOT_MSG "SLOT_B"
-#endif
-
-/*
- * The TQM850L hardware has two pins swapped! Grrrrgh!
- */
-#ifdef CONFIG_TQM850L
-#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXOE
-#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXRESET
-#else
-#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXRESET
-#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXOE
-#endif
-
-/* look up table for pgcrx registers */
-
-#if 0
-static u_int *pcmcia_pgcrx[2] = {
- &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
- &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
-};
-
-#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
-#endif
-
-/*
- * This structure is used to address each window in the PCMCIA controller.
- *
- * Keep in mind that we assume that pcmcia_win_t[n+1] is mapped directly
- * after pcmcia_win_t[n]...
- */
-
-typedef struct {
- ulong br;
- ulong or;
-} pcmcia_win_t;
-
-/* ------------------------------------------------------------------------- */
-
-/*
- * Memory Map Information:
- *
- * BR0 / OR0: EPROM1 Base 0xFF000000 Size 512KB
- * BR1 / OR1: EPROM2 Base 0xFF080000 Size 512KB
- * BR2 / OR2: SRAM Base 0xFE200000 Size 2MB
- * BR3 / OR3: SDRAM Base 0x00000000 Size 16MB (max. 64 MB used)
- * BR4 / OR4: PER-8 Base 0xFE000000 Size 1MB
- * BR5 / OR5: SHARC Base 0xFE400000 Size 4MB
- */
-/* ------------------------------------------------------------------------- */
-
-#endif /* CONFIG_IDE_PCMCIA */
-
/* Current I/O Device */
static int curr_device = -1;
udelay (10000); /* 10 ms */
c = inb (dev, ATA_STATUS);
- ++i;
if (i > (ATA_RESET_TIME * 100)) {
puts ("** Timeout **\n");
ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
| timings
#endif
;
+ PRINTF ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0);
pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1;
pcmp->pcmc_por1 = CFG_PCMCIA_POR1
| timings
#endif
;
+ PRINTF ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1);
pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2;
pcmp->pcmc_por2 = CFG_PCMCIA_POR2
| timings
#endif
;
+ PRINTF ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2);
pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3;
pcmp->pcmc_por3 = CFG_PCMCIA_POR3
| timings
#endif
;
+ PRINTF ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3);
/* IDE 1
*/
| timings
#endif
;
+ PRINTF ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4);
pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5;
pcmp->pcmc_por5 = CFG_PCMCIA_POR5
| timings
#endif
;
+ PRINTF ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5);
pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6;
pcmp->pcmc_por6 = CFG_PCMCIA_POR6
| timings
#endif
;
+ PRINTF ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6);
pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7;
pcmp->pcmc_por7 = CFG_PCMCIA_POR7
| timings
#endif
;
+ PRINTF ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);
}
{
ldiv_t mb, gb;
ide_dev_id_t *idp = &(ide_device[device]);
+ char *mod, *ser;
if (idp->size == 0) {
puts ("not available\n");
gb.rem += 512;
gb.rem /= 1024;
- printf ("Model: %s Serial #: %s ", idp->model, idp->serial_no);
+ mod = idp->model; while (*mod && (*mod==' ')) ++mod;
+ ser = idp->serial_no; while (*ser && (*ser==' ')) ++ser;
+
+ printf ("Model: %s Serial #: %s ", mod, ser);
printf ("Capacity: %ld.%ld MB = %ld.%ld GB\n",
mb.quot, mb.rem, gb.quot, gb.rem);
}
immr->im_ioport.iop_pcso &= ~(CFG_PC_IDE_RESET);
immr->im_ioport.iop_pcdir |= CFG_PC_IDE_RESET; /* Make output */
+#if 1
/* assert IDE RESET signal */
immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
udelay (20000);
/* de-assert RESET signal of IDE */
immr->im_ioport.iop_pcdat |= CFG_PC_IDE_RESET;
+#else
+ /* assert IDE RESET signal */
+ immr->im_ioport.iop_pcdat |= CFG_PC_IDE_RESET;
+ udelay (20000);
+ /* de-assert RESET signal of IDE */
+ immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
+#endif
#else
#error IDE reset pin not configured
#endif
+
+#ifdef CFG_PB_IDE_MOTOR
+ immr->im_cpm.cp_pbpar &= ~(CFG_PB_IDE_MOTOR); /* IDE Motor in pin */
+ immr->im_cpm.cp_pbodr &= ~(CFG_PB_IDE_MOTOR);
+ immr->im_cpm.cp_pbdir &= ~(CFG_PB_IDE_MOTOR); /* input */
+ if ((immr->im_cpm.cp_pbdat & CFG_PB_IDE_MOTOR) == 0) {
+ printf ("\nWarning: 5V for IDE Motor missing\n");
+ }
+#endif /* CFG_PB_IDE_MOTOR */
+
udelay (100000);
}
return 0;
}
+#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
/* avoid "bootd" recursion */
if ((len < 0) && (cmdtp->cmd == do_bootd)) {
#ifdef DEBUG_PARSER
printf ("'bootd' recursion detected\n");
return 0;
}
-
+#endif /* CFG_CMD_BOOTD */
/* OK - call function */
(cmdtp->cmd) (cmdtp, bd, flag, argc, argv);
LDSCRIPT := $(BOARD)/ppcboot.lds
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \
- -D__KERNEL__ \
+ -D__KERNEL__ -D__powerpc__ \
-I$(TOPDIR)/include \
-fno-builtin \
-pipe $(PLATFORM_CPPFLAGS)
{
vu_long *addr = (vu_long*)(info->start[0]);
int flag, prot, sect;
- ulong start, now, last;
+ ulong type, start, now, last;
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
- if ((info->flash_id == FLASH_UNKNOWN) ||
- (info->flash_id > FLASH_AMD_COMP)) {
- printf ("Can't erase unknown flash type - aborted\n");
+ type = (info->flash_id & FLASH_VENDMASK);
+ if ((type != FLASH_MAN_SST) && (type != FLASH_MAN_STM)) {
+ printf ("Can't erase unknown flash type %08lx - aborted\n",
+ info->flash_id);
return;
}
/* MPC860T Fast Ethernet Controller. It isn't part of the CPM, but
* it fits within the address space.
*/
+
typedef struct fec {
- uint fec_addr_low; /* LS 32 bits of station address */
- ushort fec_addr_high; /* MS 16 bits of address */
- ushort res1;
- uint fec_hash_table_high;
- uint fec_hash_table_low;
- uint fec_r_des_start;
- uint fec_x_des_start;
- uint fec_r_buff_size;
- uint res2[9];
- uint fec_ecntrl;
- uint fec_ievent;
- uint fec_imask;
- uint fec_ivec;
- uint fec_r_des_active;
- uint fec_x_des_active;
- uint res3[10];
- uint fec_mii_data;
- uint fec_mii_speed;
- uint res4[17];
- uint fec_r_bound;
- uint fec_r_fstart;
- uint res5[6];
- uint fec_x_fstart;
- uint res6[17];
- uint fec_fun_code;
- uint res7[3];
- uint fec_r_cntrl;
- uint fec_r_hash;
- uint res8[14];
- uint fec_x_cntrl;
- uint res9[0x1e];
+ uint fec_addr_low; /* lower 32 bits of station address */
+ ushort fec_addr_high; /* upper 16 bits of station address */
+ ushort res1; /* reserved */
+ uint fec_hash_table_high; /* upper 32-bits of hash table */
+ uint fec_hash_table_low; /* lower 32-bits of hash table */
+ uint fec_r_des_start; /* beginning of Rx descriptor ring */
+ uint fec_x_des_start; /* beginning of Tx descriptor ring */
+ uint fec_r_buff_size; /* Rx buffer size */
+ uint res2[9]; /* reserved */
+ uint fec_ecntrl; /* ethernet control register */
+ uint fec_ievent; /* interrupt event register */
+ uint fec_imask; /* interrupt mask register */
+ uint fec_ivec; /* interrupt level and vector status */
+ uint fec_r_des_active; /* Rx ring updated flag */
+ uint fec_x_des_active; /* Tx ring updated flag */
+ uint res3[10]; /* reserved */
+ uint fec_mii_data; /* MII data register */
+ uint fec_mii_speed; /* MII speed control register */
+ uint res4[17]; /* reserved */
+ uint fec_r_bound; /* end of RAM (read-only) */
+ uint fec_r_fstart; /* Rx FIFO start address */
+ uint res5[6]; /* reserved */
+ uint fec_x_fstart; /* Tx FIFO start address */
+ uint res6[17]; /* reserved */
+ uint fec_fun_code; /* fec SDMA function code */
+ uint res7[3]; /* reserved */
+ uint fec_r_cntrl; /* Rx control register */
+ uint fec_r_hash; /* Rx hash register */
+ uint res8[14]; /* reserved */
+ uint fec_x_cntrl; /* Tx control register */
+ uint res9[0x1e]; /* reserved */
} fec_t;
/* The FEC and LCD color map share the same address space....
--- /dev/null
+/* originally from linux source.
+ * removed the dependacies on CONFIG_ values
+ * removed virt_to_phys stuff (and in fact everything surrounded by #if __KERNEL__)
+ * Modified By Rob Taylor, Flying Pig Systems, 2000
+ */
+
+#ifndef _PPC_IO_H
+#define _PPC_IO_H
+
+#include <linux/config.h>
+#include <asm/byteorder.h>
+
+#define SIO_CONFIG_RA 0x398
+#define SIO_CONFIG_RD 0x399
+
+
+#define readb(addr) in_8((volatile u8 *)(addr))
+#define writeb(b,addr) out_8((volatile u8 *)(addr), (b))
+#if !defined(__BIG_ENDIAN)
+#define readw(addr) (*(volatile u16 *) (addr))
+#define readl(addr) (*(volatile u32 *) (addr))
+#define writew(b,addr) ((*(volatile u16 *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile u32 *) (addr)) = (b))
+#else
+#define readw(addr) in_le16((volatile u16 *)(addr))
+#define readl(addr) in_le32((volatile u32 *)(addr))
+#define writew(b,addr) out_le16((volatile u16 *)(addr),(b))
+#define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
+#endif
+
+/*
+ * The insw/outsw/insl/outsl macros don't do byte-swapping.
+ * They are only used in practice for transferring buffers which
+ * are arrays of bytes, and byte-swapping is not appropriate in
+ * that case. - paulus
+ */
+#define insb(port, buf, ns) _insb((u8 *)((port)+_IO_BASE), (buf), (ns))
+#define outsb(port, buf, ns) _outsb((u8 *)((port)+_IO_BASE), (buf), (ns))
+#define insw(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define outsw(port, buf, ns) _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define insl(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+#define outsl(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+
+#define inb(port) in_8((u8 *)((port)+_IO_BASE))
+#define outb(val, port) out_8((u8 *)((port)+_IO_BASE), (val))
+#if !defined(__BIG_ENDIAN)
+#define inw(port) in_be16((u16 *)((port)+_IO_BASE))
+#define outw(val, port) out_be16((u16 *)((port)+_IO_BASE), (val))
+#define inl(port) in_be32((u32 *)((port)+_IO_BASE))
+#define outl(val, port) out_be32((u32 *)((port)+_IO_BASE), (val))
+#else
+#define inw(port) in_le16((u16 *)((port)+_IO_BASE))
+#define outw(val, port) out_le16((u16 *)((port)+_IO_BASE), (val))
+#define inl(port) in_le32((u32 *)((port)+_IO_BASE))
+#define outl(val, port) out_le32((u32 *)((port)+_IO_BASE), (val))
+#endif
+
+#define inb_p(port) in_8((u8 *)((port)+_IO_BASE))
+#define outb_p(val, port) out_8((u8 *)((port)+_IO_BASE), (val))
+#define inw_p(port) in_le16((u16 *)((port)+_IO_BASE))
+#define outw_p(val, port) out_le16((u16 *)((port)+_IO_BASE), (val))
+#define inl_p(port) in_le32((u32 *)((port)+_IO_BASE))
+#define outl_p(val, port) out_le32((u32 *)((port)+_IO_BASE), (val))
+
+extern void _insb(volatile u8 *port, void *buf, int ns);
+extern void _outsb(volatile u8 *port, const void *buf, int ns);
+extern void _insw(volatile u16 *port, void *buf, int ns);
+extern void _outsw(volatile u16 *port, const void *buf, int ns);
+extern void _insl(volatile u32 *port, void *buf, int nl);
+extern void _outsl(volatile u32 *port, const void *buf, int nl);
+extern void _insw_ns(volatile u16 *port, void *buf, int ns);
+extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
+extern void _insl_ns(volatile u32 *port, void *buf, int nl);
+extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
+
+/*
+ * The *_ns versions below don't do byte-swapping.
+ * Neither do the standard versions now, these are just here
+ * for older code.
+ */
+#define insw_ns(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define outsw_ns(port, buf, ns) _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define insl_ns(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+#define outsl_ns(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+
+
+#define IO_SPACE_LIMIT ~0
+
+#define memset_io(a,b,c) memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
+
+/*
+ * Enforce In-order Execution of I/O:
+ * Acts as a barrier to ensure all previous I/O accesses have
+ * completed before any further ones are issued.
+ */
+#define eieio() __asm__ __volatile__ ("eieio" : : : "memory");
+#define sync() __asm__ __volatile__ ("sync" : : : "memory");
+
+/* Enforce in-order execution of data I/O.
+ * No distinction between read/write on PPC; use eieio for all three.
+ */
+#define iobarrier_rw() eieio()
+#define iobarrier_r() eieio()
+#define iobarrier_w() eieio()
+
+/*
+ * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
+ */
+extern inline int in_8(volatile u8 *addr)
+{
+ int ret;
+
+ __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
+ return ret;
+}
+
+extern inline void out_8(volatile u8 *addr, int val)
+{
+ __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+extern inline int in_le16(volatile u16 *addr)
+{
+ int ret;
+
+ __asm__ __volatile__("lhbrx %0,0,%1; eieio" : "=r" (ret) :
+ "r" (addr), "m" (*addr));
+ return ret;
+}
+
+extern inline int in_be16(volatile u16 *addr)
+{
+ int ret;
+
+ __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
+ return ret;
+}
+
+extern inline void out_le16(volatile u16 *addr, int val)
+{
+ __asm__ __volatile__("sthbrx %1,0,%2; eieio" : "=m" (*addr) :
+ "r" (val), "r" (addr));
+}
+
+extern inline void out_be16(volatile u16 *addr, int val)
+{
+ __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+extern inline unsigned in_le32(volatile u32 *addr)
+{
+ unsigned ret;
+
+ __asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
+ "r" (addr), "m" (*addr));
+ return ret;
+}
+
+extern inline unsigned in_be32(volatile u32 *addr)
+{
+ unsigned ret;
+
+ __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
+ return ret;
+}
+
+extern inline void out_le32(volatile unsigned *addr, int val)
+{
+ __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
+ "r" (val), "r" (addr));
+}
+
+extern inline void out_be32(volatile unsigned *addr, int val)
+{
+ __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+}
+
+#endif
--- /dev/null
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_PPC_MC146818RTC_H
+#define __ASM_PPC_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* __ASM_PPC_MC146818RTC_H */
--- /dev/null
+/* originally from linux source (asm-ppc/io.h).
+ * Sanity added by Rob Taylor, Flying Pig Systems, 2000
+ */
+#ifndef _PCI_IO_H_
+#define _PCI_IO_H_
+
+#include "io.h"
+
+
+#define pci_read_le16(addr, dest) \
+ __asm__ __volatile__("lhbrx %0,0,%1" : "=r" (dest) : \
+ "r" (addr), "m" (*addr));
+
+#define pci_write_le16(addr, val) \
+ __asm__ __volatile__("sthbrx %1,0,%2" : "=m" (*addr) : \
+ "r" (val), "r" (addr));
+
+
+#define pci_read_le32(addr, dest) \
+ __asm__ __volatile__("lwbrx %0,0,%1" : "=r" (dest) : \
+ "r" (addr), "m" (*addr));
+
+#define pci_write_le32(addr, val) \
+__asm__ __volatile__("stwbrx %1,0,%2" : "=m" (*addr) : \
+ "r" (val), "r" (addr));
+
+#define pci_readb(addr,b) ((b) = *(volatile u8 *) (addr))
+#define pci_writeb(b,addr) ((*(volatile u8 *) (addr)) = (b))
+
+#if !defined(__BIG_ENDIAN)
+#define pci_readw(addr,b) ((b) = *(volatile u16 *) (addr))
+#define pci_readl(addr,b) ((b) = *(volatile u32 *) (addr))
+#define pci_writew(b,addr) ((*(volatile u16 *) (addr)) = (b))
+#define pci_writel(b,addr) ((*(volatile u32 *) (addr)) = (b))
+#else
+#define pci_readw(addr,b) pci_read_le16((volatile u16 *)(addr),(b))
+#define pci_readl(addr,b) pci_read_le32((volatile u32 *)(addr),(b))
+#define pci_writew(b,addr) pci_write_le16((volatile u16 *)(addr),(b))
+#define pci_writel(b,addr) pci_write_le32((volatile u32 *)(addr),(b))
+#endif
+
+
+#endif /* _PCI_IO_H_ */
#define _MACH_oak 0x00000800 /* IBM "Oak" 403 eval. board */
#define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */
#define _MACH_8260 0x00002000 /* Generic 8260 */
-#define _MACH_tqm860 0x00004000 /* TQM860/L */
-#define _MACH_tqm8xxL 0x00008000 /* TQM8xxL */
+#define _MACH_sandpoint 0x00004000 /* Motorola SPS Processor eval board */
+#define _MACH_tqm860 0x00008000 /* TQM860/L */
+#define _MACH_tqm8xxL 0x00010000 /* TQM8xxL */
/* see residual.h for these */
: "=r" (rval)); rval;})
#define mtspr(rn, v) asm volatile("mtspr " stringify(rn) ",%0" : : "r" (v))
+#define tlbie(v) asm volatile("tlbie %0 \n sync" : : "r" (v))
+
/* Segment Registers */
#define SR0 0
#elif defined(CONFIG_8260)
#define _machine _MACH_8260
#define have_of 0
+#elif defined(CONFIG_SANDPOINT)
+#define _machine _MACH_sandpoint
+#define have_of 0
#else
#error "Machine not defined correctly"
#endif
ushort sen_taddrl; /* temp address (LSB) */
} scc_enet_t;
+/**********************************************************************
+ *
+ * Board specific configuration settings.
+ *
+ * Please note that we use the presence of a #define SCC_ENET and/or
+ * #define FEC_ENET to enable the SCC resp. FEC ethernet drivers.
+ **********************************************************************/
+
+
/*** MBX ************************************************************/
#ifdef CONFIG_MBX
#define SICR_ENET_CLKRT ((uint)0x00260000)
#endif /* CONFIG_SM850 */
+/*** IVMS8 **********************************************************/
+
+/* The IVMS8 uses the FEC on a MPC860T for Ethernet */
+
+#ifdef CONFIG_IVMS8
+
+#define FEC_ENET /* use FEC for EThernet */
+#undef SCC_ENET
+
+#define PB_ENET_POWER ((uint)0x00010000) /* PB 15 */
+
+#define PC_ENET_RESET ((ushort)0x0010) /* PC 11 */
+
+#define PD_MII_TXD1 ((ushort)0x1000) /* PD 3 */
+#define PD_MII_TXD2 ((ushort)0x0800) /* PD 4 */
+#define PD_MII_TXD3 ((ushort)0x0400) /* PD 5 */
+#define PD_MII_RX_DV ((ushort)0x0200) /* PD 6 */
+#define PD_MII_RX_ERR ((ushort)0x0100) /* PD 7 */
+#define PD_MII_RX_CLK ((ushort)0x0080) /* PD 8 */
+#define PD_MII_TXD0 ((ushort)0x0040) /* PD 9 */
+#define PD_MII_RXD0 ((ushort)0x0020) /* PD 10 */
+#define PD_MII_TX_ERR ((ushort)0x0010) /* PD 11 */
+#define PD_MII_MDC ((ushort)0x0008) /* PD 12 */
+#define PD_MII_RXD1 ((ushort)0x0004) /* PD 13 */
+#define PD_MII_RXD2 ((ushort)0x0002) /* PD 14 */
+#define PD_MII_RXD3 ((ushort)0x0001) /* PD 15 */
+
+#define PD_MII_MASK ((ushort)0x1FFF) /* PD 3...15 */
+
+#endif /* CONFIG_IVMS8 */
+
/*********************************************************************/
/* SCC Event register as used by Ethernet.
#undef CONFIG_WATCHDOG /* watchdog disabled */
+#define CONFIG_STATUS_LED 1 /* Status LED enabled */
+
#define CONFIG_BOOTP_MASK CONFIG_BOOTP_ALL
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#if 0
#define CONFIG_COMMANDS \
((CONFIG_CMD_DFL & ~(CFG_CMD_FLASH)) | CFG_CMD_IDE) /* no Flash, but IDE */
+#define CONFIG_COMMANDS ((CONFIG_CMD_DFL | CFG_CMD_IDE) & ~(CFG_CMD_NET))
#else
-#define CONFIG_COMMANDS \
- (CONFIG_CMD_DFL & ~(CFG_CMD_NET))
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_IDE)
#endif /* 0 */
#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT
#define CFG_PB_SDRAM_CLKE 0x00008000 /* PB 16 */
#define CFG_PB_ETH_POWERDOWN 0x00010000 /* PB 15 */
+#define CFG_PB_IDE_MOTOR 0x00020000 /* PB 14 */
#define CFG_PC_ETH_RESET ((ushort)0x0010) /* PC 11 */
#define CFG_PC_IDE_RESET ((ushort)0x0020) /* PC 10 */
*/
#define SCCR_MASK SCCR_EBDF11
/* 0x01800014 */
-#define CFG_SCCR (SCCR_COM00 | /*SCCR_TBS|*/ \
+#define CFG_SCCR (SCCR_COM01 | /*SCCR_TBS|*/ \
SCCR_RTDIV | SCCR_RTSEL | \
/*SCCR_CRQEN|*/ /*SCCR_PRQEN|*/ \
SCCR_EBDF00 | SCCR_DFSYNC00 | \
#define CFG_PCMCIA_IO_ADDR (0xEC000000)
#define CFG_PCMCIA_IO_SIZE ( 64 << 20 )
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_IDE_PCMCIA 1 /* PCMCIA interface required */
+#if 0
+#define CONFIG_IDE_LED 1 /* LED for ide supported */
+#endif
+#define CONFIG_IDE_RESET 1 /* reset for ide supported */
+
+#define CFG_IDE_MAXBUS 1 /* The IVMS8 has only 1 IDE bus */
+#define CFG_IDE_MAXDEVICE 1 /* ... and only 1 IDE device */
+
+#define CFG_ATA_BASE_ADDR 0xFE100000
+#define CFG_ATA_IDE0_OFFSET 0x0000
+#undef CFG_ATA_IDE1_OFFSET /* only one IDE bus available */
+
+#define CFG_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */
+#define CFG_ATA_REG_OFFSET 0x0080 /* Offset for normal register accesses */
+#define CFG_ATA_ALT_OFFSET 0x0100 /* Offset for alternate registers */
+
/*-----------------------------------------------------------------------
*
*-----------------------------------------------------------------------
--- /dev/null
+
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_MPC8240 1
+#define CONFIG_SANDPOINT 1
+
+#define CONFIG_BAUDRATE 9600
+#define CONFIG_DRAM_SPEED 100 /* MHz */
+#define CONFIG_BOOTCOMMAND "bootm FE020000" /* autoboot command */
+#define CONFIG_BOOTARGS " "
+
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL & ~CFG_CMD_NET)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+
+/*
+ * Miscellaneous configurable options
+ */
+#undef CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT ":>" /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 8 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_LOAD_ADDR 0x00100000 /* default load address */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0xFFF00000
+#define CFG_FLASH_SIZE ((uint)(512 * 1024)) /* sandpoint has tiny eeprom */
+
+#ifdef DEBUG
+ #define CFG_MONITOR_BASE CFG_SDRAM_BASE
+#else
+ #define CFG_MONITOR_BASE CFG_FLASH_BASE
+#endif
+
+#ifdef DEBUG
+#define CFG_MONITOR_LEN (4 <<20) /* if we're running in ram, give us plenty of space for debug info*/
+#else
+#define CFG_MONITOR_LEN (512 << 10) /* Reserve 512 kB for Monitor */
+#endif
+#define CFG_MALLOC_LEN (512 << 10) /* Reserve 512 kB for malloc() */
+
+#define CFG_TFTP_LOADADDR 0x00100000 /* default load address */
+
+#define CFG_MEMTEST_START 0x00000000 /* memtest works on */
+#define CFG_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */
+
+#define CFG_EUMB_ADDR 0xFC000000
+
+#define CFG_ISA_MEM 0xFD000000
+#define CFG_ISA_IO 0xFE000000
+
+#define FLASH_BASE0_PRELIM 0xFFF00000 /* sandpoint flash */
+#define FLASH_BASE1_PRELIM 0xFF000000 /* PMC onboard flash*/
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR CFG_SDRAM_BASE + CFG_MONITOR_LEN
+#define CFG_INIT_RAM_END 0x3000 /* End of used area in DPRAM */
+#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET
+
+
+#define CFG_WINBOND_83C553 1 /*has a winbond bridge */
+#define CFG_USE_WINBOND_IDE 0 /*use winbond 83c553 internal ide controller */
+#define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /*pci-isa bridge config addr */
+#define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /*ide config addr */
+#define CFG_NS87308_BADDR_10 1
+
+
+#define CFG_NS_PC87308UL 1 /* Nat Semi super-io controller on ISA bus */
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+
+#define CFG_ROMNAL 8 /*rom/flash next access time*/
+#define CFG_ROMFAL 16 /*rom/flash access time*/
+
+#define CFG_REFINT 430 /* no of clock cycles between CBR refresh cycles*/
+/* the following are for SDRAM only*/
+#define CFG_BSTOPRE 604 /* Burst To Precharge, sets open page interval */
+#define CFG_REFREC 8 /* Refresh to activate interval */
+#define CFG_RDLAT 4 /* data latancy from read command*/
+#define CFG_PRETOACT 3 /* Precharge to activate interval */
+#define CFG_ACTTOPRE 5 /* Activate to Precharge interval */
+#define CFG_SDMODE_CAS_LAT 3 /* SDMODE CAS latancy */
+#define CFG_SDMODE_WRAP 0 /* SDMODE wrap type */
+#define CFG_SDMODE_BURSTLEN 2 /* SDMODE Burst length 2=4, 3=8 */
+
+#define CFG_REGISTERD_TYPE_BUFFER 1
+
+/* memory bank settings*/
+/* only bits 20-29 are actually used from these vales to set the stare/end address
+ the upper two bits will be 0, and the lower 20 bits will be set to
+ 0x00000 for a start address, or 0xfffff for an end address*/
+
+#define CFG_BANK0_START 0x00000000
+
+#define CFG_BANK0_END 0x01ffffff
+#define CFG_BANK0_ENABLE 1
+#define CFG_BANK1_START 0x01000000
+#define CFG_BANK1_END 0x00ffffff
+#define CFG_BANK1_ENABLE 0
+#define CFG_BANK2_START 0x02000000
+#define CFG_BANK2_END 0x02ffffff
+#define CFG_BANK2_ENABLE 0
+#define CFG_BANK3_START 0x03000000
+#define CFG_BANK3_END 0x03ffffff
+#define CFG_BANK3_ENABLE 0
+#define CFG_BANK4_START 0x04000000
+#define CFG_BANK4_END 0x04ffffff
+#define CFG_BANK4_ENABLE 0
+#define CFG_BANK5_START 0x05000000
+#define CFG_BANK5_END 0x05ffffff
+#define CFG_BANK5_ENABLE 0
+#define CFG_BANK6_START 0x06000000
+#define CFG_BANK6_END 0x06ffffff
+#define CFG_BANK6_ENABLE 0
+#define CFG_BANK7_START 0x07000000
+#define CFG_BANK7_END 0x07ffffff
+#define CFG_BANK7_ENABLE 0
+
+#define CFG_ODCR 0xff /* configures line driver impedances,
+ see 8240 book for bit definitions */
+#define CFG_PGMAX 0x32 /* how long the 8240 reatins the currently accessed page in memory
+ see 8240 book for details*/
+#define CFG_IBAT0L FLASH_BASE0_PRELIM | BATL_CACHEINHIBIT | BATL_PP_10
+#define CFG_IBAT0U FLASH_BASE0_PRELIM | BATU_BL_16M | BATU_VS | BATU_VP
+#define CFG_IBAT1L 0x00000000 | BATL_CACHEINHIBIT | BATL_PP_10
+#define CFG_IBAT1U 0x00000000 | BATU_BL_128M | BATU_VS | BATU_VP
+#define CFG_IBAT2L CFG_ISA_MEM | BATL_MEMCOHERENCE | BATL_PP_10
+#define CFG_IBAT2U CFG_ISA_MEM | BATU_BL_16M | BATU_VS | BATU_VP
+#define CFG_IBAT3L CFG_ISA_IO | BATL_MEMCOHERENCE | BATL_PP_10
+#define CFG_IBAT3U CFG_ISA_IO | BATU_BL_16M | BATU_VS | BATU_VP
+#define CFG_DBAT0L FLASH_BASE0_PRELIM | BATL_MEMCOHERENCE | BATL_WRITETHROUGH | BATL_PP_10
+#define CFG_DBAT0U FLASH_BASE0_PRELIM | BATU_BL_16M | BATU_VS | BATU_VP
+#define CFG_DBAT1L 0x00000000 | BATL_MEMCOHERENCE | BATL_WRITETHROUGH | BATL_PP_10
+#define CFG_DBAT1U 0x00000000 | BATU_BL_128M | BATU_VS | BATU_VP
+#define CFG_DBAT2L CFG_ISA_MEM | BATL_MEMCOHERENCE | BATL_PP_10
+#define CFG_DBAT2U CFG_ISA_MEM | BATU_BL_16M | BATU_VS | BATU_VP
+#define CFG_DBAT3L CFG_ISA_IO | BATL_MEMCOHERENCE | BATL_PP_10
+#define CFG_DBAT3U CFG_ISA_IO | BATU_BL_16M | BATU_VS | BATU_VP
+
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 8 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+#define CFG_FLASH_ENV_ALIGN 15 /* Bitshift for Environment Sector */
+#define CFG_FLASH_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
+/* the other CS:s are determined by looking at parameters in BCSRx */
+
+/* values according to the manual */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
+
+
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+/* values according to the manual */
+
+#define CONFIG_DRAM_50MHZ 1
+#define CONFIG_SDRAM_50MHZ
+
+#undef NR_8259_INTS
+#define NR_8259_INTS 1
+
+
+#define CONFIG_DISK_SPINUP_TIME 1000000
+
+
+#endif /* __CONFIG_H */
#undef CONFIG_WATCHDOG /* watchdog disabled */
+#define CONFIG_STATUS_LED 1 /* Status LED enabled */
+
#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
--- /dev/null
+/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
+ * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
+ * derived from Data Sheet, Copyright Motorola 1984 (!).
+ * It was written to be part of the Linux operating system.
+ */
+/* permission is hereby granted to copy, modify and redistribute this code
+ * in terms of the GNU Library General Public License, Version 2 or later,
+ * at your option.
+ */
+
+#ifndef _MC146818RTC_H
+#define _MC146818RTC_H
+
+#include <asm/io.h>
+#include <linux/rtc.h> /* get the user-level API */
+#include <asm/mc146818rtc.h> /* register access macros */
+
+/**********************************************************************
+ * register summary
+ **********************************************************************/
+#define RTC_SECONDS 0
+#define RTC_SECONDS_ALARM 1
+#define RTC_MINUTES 2
+#define RTC_MINUTES_ALARM 3
+#define RTC_HOURS 4
+#define RTC_HOURS_ALARM 5
+/* RTC_*_alarm is always true if 2 MSBs are set */
+# define RTC_ALARM_DONT_CARE 0xC0
+
+#define RTC_DAY_OF_WEEK 6
+#define RTC_DAY_OF_MONTH 7
+#define RTC_MONTH 8
+#define RTC_YEAR 9
+
+/* control registers - Moto names
+ */
+#define RTC_REG_A 10
+#define RTC_REG_B 11
+#define RTC_REG_C 12
+#define RTC_REG_D 13
+
+/**********************************************************************
+ * register details
+ **********************************************************************/
+#define RTC_FREQ_SELECT RTC_REG_A
+
+/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus,
+ * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
+ * totalling to a max high interval of 2.228 ms.
+ */
+# define RTC_UIP 0x80
+# define RTC_DIV_CTL 0x70
+ /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
+# define RTC_REF_CLCK_4MHZ 0x00
+# define RTC_REF_CLCK_1MHZ 0x10
+# define RTC_REF_CLCK_32KHZ 0x20
+ /* 2 values for divider stage reset, others for "testing purposes only" */
+# define RTC_DIV_RESET1 0x60
+# define RTC_DIV_RESET2 0x70
+ /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
+# define RTC_RATE_SELECT 0x0F
+
+/**********************************************************************/
+#define RTC_CONTROL RTC_REG_B
+# define RTC_SET 0x80 /* disable updates for clock setting */
+# define RTC_PIE 0x40 /* periodic interrupt enable */
+# define RTC_AIE 0x20 /* alarm interrupt enable */
+# define RTC_UIE 0x10 /* update-finished interrupt enable */
+# define RTC_SQWE 0x08 /* enable square-wave output */
+# define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
+# define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
+# define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
+
+/**********************************************************************/
+#define RTC_INTR_FLAGS RTC_REG_C
+/* caution - cleared by read */
+# define RTC_IRQF 0x80 /* any of the following 3 is active */
+# define RTC_PF 0x40
+# define RTC_AF 0x20
+# define RTC_UF 0x10
+
+/**********************************************************************/
+#define RTC_VALID RTC_REG_D
+# define RTC_VRT 0x80 /* valid RAM and time */
+/**********************************************************************/
+
+/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
+ * determines if the following two #defines are needed
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+#endif /* _MC146818RTC_H */
--- /dev/null
+/*
+ * Copyright Rob Taylor, Flying Pig Systems Ltd. 2000.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MPC8240_H__
+#define __MPC8240_H__
+
+/*-----------------------------------------------------------------------
+ * Exception offsets (PowerPC standard)
+ */
+#define EXC_OFF_RESERVED0 0x0000 /* Reserved */
+#define EXC_OFF_SYS_RESET 0x0100 /* System reset */
+#define EXC_OFF_MACH_CHCK 0x0200 /* Machine Check */
+#define EXC_OFF_DATA_STOR 0x0300 /* Data Storage */
+#define EXC_OFF_INS_STOR 0x0400 /* Instruction Storage */
+#define EXC_OFF_EXTERNAL 0x0500 /* External */
+#define EXC_OFF_ALIGN 0x0600 /* Alignment */
+#define EXC_OFF_PROGRAM 0x0700 /* Program */
+#define EXC_OFF_FPUNAVAIL 0x0800 /* Floating-point Unavailable */
+#define EXC_OFF_DECR 0x0900 /* Decrementer */
+#define EXC_OFF_RESERVED1 0x0A00 /* Reserved */
+#define EXC_OFF_RESERVED2 0x0B00 /* Reserved */
+#define EXC_OFF_SYS_CALL 0x0C00 /* System Call */
+#define EXC_OFF_TRACE 0x0D00 /* Trace */
+#define EXC_OFF_FPUNASSIST 0x0E00 /* Floating-point Assist */
+
+ /* 0x0E10 - 0x0FFF are marked reserved in The PowerPC Architecture book */
+ /* these found in DINK code - may not apply to 8240*/
+#define EXC_OFF_PMI 0x0F00 /* Performance Monitoring Interrupt */
+#define EXC_OFF_VMXUI 0x0F20 /* VMX (AltiVec) Unavailable Interrupt */
+
+ /* 0x1000 - 0x2FFF are implementation specific */
+ /* these found in DINK code - may not apply to 8240 */
+#define EXC_OFF_ITME 0x1000 /* Instruction Translation Miss Exception */
+#define EXC_OFF_DLTME 0x1100 /* Data Load Translation Miss Exception */
+#define EXC_OFF_DSTME 0x1200 /* Data Store Translation Miss Exception */
+#define EXC_OFF_IABE 0x1300 /* Instruction Address Breakpoint Exception */
+#define EXC_OFF_SMIE 0x1400 /* System Management Interrupt Exception */
+#define EXC_OFF_JMDDI 0x1600 /* Java Mode denorm detection Interrupt -- WTF??*/
+#define EXC_OFF_RMTE 0x2000 /* Run Mode or Trace Exception */
+
+#define MAP_A_CONFIG_ADDR_HIGH 0x8000 /* Upper half of CONFIG_ADDR for Map A */
+#define MAP_A_CONFIG_ADDR_LOW 0x0CF8 /* Lower half of CONFIG_ADDR for Map A */
+#define MAP_A_CONFIG_DATA_HIGH 0x8000 /* Upper half of CONFIG_DAT for Map A */
+#define MAP_A_CONFIG_DATA_LOW 0x0CFC /* Lower half of CONFIG_DAT for Map A */
+#define MAP_B_CONFIG_ADDR_HIGH 0xfec0 /* Upper half of CONFIG_ADDR for Map B */
+#define MAP_B_CONFIG_ADDR_LOW 0x0000 /* Lower half of CONFIG_ADDR for Map B */
+#define MAP_B_CONFIG_DATA_HIGH 0xfee0 /* Upper half of CONFIG_DAT for Map B */
+#define MAP_B_CONFIG_DATA_LOW 0x0000 /* Lower half of CONFIG_DAT for Map B */
+
+
+#if defined(CFG_ADDR_MAP_A)
+#define CONFIG_ADDR_HIGH MAP_A_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */
+#define CONFIG_ADDR_LOW MAP_A_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */
+#define CONFIG_DATA_HIGH MAP_A_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */
+#define CONFIG_DATA_LOW MAP_A_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */
+#else /* Assume Map B, default */
+#define CONFIG_ADDR_HIGH MAP_B_CONFIG_ADDR_HIGH /* Upper half of CONFIG_ADDR */
+#define CONFIG_ADDR_LOW MAP_B_CONFIG_ADDR_LOW /* Lower half of CONFIG_ADDR */
+#define CONFIG_DATA_HIGH MAP_B_CONFIG_DATA_HIGH /* Upper half of CONFIG_DAT */
+#define CONFIG_DATA_LOW MAP_B_CONFIG_DATA_LOW /* Lower half of CONFIG_DAT */
+#endif
+
+#define CONFIG_ADDR (CONFIG_ADDR_HIGH << 16 | CONFIG_ADDR_LOW)
+
+#define CONFIG_DATA (CONFIG_DATA_HIGH << 16 | CONFIG_DATA_LOW)
+
+/*macros to wite to conif registers. addr should be a constant in all cases */
+
+#define CONFIG_WRITE_BYTE( addr, data ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %0\n \
+ sync\n \
+ stb %3, %4(%2)\n \
+ sync " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" ((addr) & ~3), \
+ "r" (CONFIG_DATA), "r" (data), \
+ "n" ((addr) & 3));
+
+#define CONFIG_WRITE_HALFWORD( addr, data ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %0\n \
+ sync\n \
+ stwbrx %3, %4, %2\n \
+ sync " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" (addr), \
+ "r" (CONFIG_DATA), "r" (data), \
+ "n" ((addr) & 3));
+
+/* this assumes it's writeing on word boundaries*/
+#define CONFIG_WRITE_WORD( addr, data ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %0\n \
+ sync\n \
+ stwbrx %3, 0, %2\n \
+ sync " \
+ : /* no output */ \
+ : "r" (CONFIG_ADDR), "r" (addr), \
+ "r" (CONFIG_DATA), "r" (data));
+
+/* Configuration register reads*/
+
+#define CONFIG_READ_BYTE( addr , reg ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %2\n \
+ sync\n \
+ lbz %0, %4(%3)\n \
+ sync " \
+ : "=r" (reg) \
+ : "r" ((addr) & ~3), "r" (CONFIG_ADDR), \
+ "r" (CONFIG_DATA), "n" ((addr) & 3));
+
+
+#define CONFIG_READ_HALFWORD( addr , reg ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %2\n \
+ sync\n \
+ lhbrx %0, %4, %3\n \
+ sync " \
+ : "=r" (reg) \
+ : "r" (addr), "r" (CONFIG_ADDR), \
+ "r" (CONFIG_DATA), \
+ "n" ((addr)&3));
+
+/* this assumes it's reading on word boundaries*/
+#define CONFIG_READ_WORD( addr , reg ) \
+ __asm__ ( \
+ " stwbrx %1, 0, %2\n \
+ sync\n \
+ lwbrx %0, 0, %3\n \
+ sync " \
+ : "=r" (reg) \
+ : "r" (addr), "r" (CONFIG_ADDR),\
+ "r" (CONFIG_DATA));
+
+/*
+ configuration register 'addresses'.
+ These are described in chaper 5 of the 8240 users manual.
+ Where the register has an abreviation in the manual, this has been usaed here,
+ otherwise a name in keeping with the norm has been invented,
+ Note that some of these registers aren't documented in the manual
+*/
+
+#define PCICR 0x80000004 /* PCI Command Register */
+#define PCISR 0x80000006 /* PCI Status Register */
+#define PIR 0x80000009 /* PCI Programming Interface Register */
+#define PBCCR 0x8000000b /* PCI Base Class Code Register */
+#define PCLSR 0x8000000c /* Processor Cache Line Size Register */
+#define PLTR 0x8000000d /* PCI Latancy Timer Register */
+#define PHTR 0x8000000e /* PCI Header Type Register */
+#define BISTCTRL 0x8000000f /* BIST Control */
+#define LMBAR 0x80000010 /* Local Base Addres Register */
+#define PCSRBAR 0x80000014 /* PCSR Base Address Register */
+#define ILR 0x8000003c /* PCI Interrupt Line Register */
+#define IPR 0x8000003d /* Interrupt Pin Register */
+#define MINGNT 0x8000003e /* MIN GNI */
+#define MAXLAT 0x8000003f /* MAX LAT */
+#define PCIACR 0x80000046 /* PCI Arbiter Control Register */
+#define PMCR1 0x80000070 /* Power management config. 1 */
+#define PMCR2 0x80000072 /* Power management config. 2 */
+#define ODCR 0x80000073 /* Output Driver Control Register */
+#define CLKDCR 0x80000074 /* CLK Driver Control Register */
+#define EUMBBAR 0x80000078 /* Embedded Utilities Memory Block Base Address Register */
+#define MSAR1 0x80000080 /* Memory Starting Address Register 1 */
+#define MSAR2 0x80000084 /* Memory Starting Address Register 2 */
+#define EMSAR1 0x80000088 /* Extended Memory Starting Address Register 1*/
+#define EMSAR2 0x8000008c /* Extended Memory Starting Address Register 2*/
+#define MEAR1 0x80000090 /* Memory Ending Address Register 1 */
+#define MEAR2 0x80000094 /* Memory Ending Address Register 2 */
+#define EMEAR1 0x80000098 /* Extended Memory Ending Address Register 1 */
+#define EMEAR2 0x8000009c /* Extended Memory Ending Address Register 2 */
+#define MBER 0x800000a0 /* Memory bank Enable Register*/
+#define MPMR 0x800000a3 /* Memory Page Mode Register (stores PGMAX) */
+#define PICR1 0x800000a8 /* Processor Interface Configuration Register 1 */
+#define PICR2 0x800000ac /* Processor Interface Configuration Register 2 */
+#define ECCSBECR 0x800000b8 /* ECC Single-Bit Error Counter Register */
+#define ECCSBETR 0x800000b8 /* ECC Single-Bit Error Trigger Register */
+#define ERRENR1 0x800000c0 /* Error Enableing Register 1 */
+#define ERRENR2 0x800000c0 /* Error Enableing Register 2 */
+#define ERRDR1 0x800000c1 /* Error Detection Register 1 */
+#define IPBESR 0x800000c3 /* Internal Processor Error Status Register */
+#define ERRDR2 0x800000c5 /* Error Detection Register 2 */
+#define PBESR 0x800000c7 /* PCI Bus Error Status Register */
+#define PBEAR 0x800000c8 /* Processor/PCI Bus Error Status Register */
+#define AMBOR 0x800000e0 /* Address Map B Options Register */
+#define MCCR1 0x800000f0 /* Memory Control Configuration Register 1 */
+#define MCCR2 0x800000f4 /* Memory Control Configuration Register 2 */
+#define MCCR3 0x800000f8 /* Memory Control Configuration Register 3 */
+#define MCCR4 0x800000fc /* Memory Control Configuration Register 4 */
+
+/* some values for soem of the above */
+
+#define PICR1_CF_APARK 0x00000008
+#define PICR1_LE_MODE 0x00000020
+#define PICR1_ST_GATH_EN 0x00000040
+#define PICR1_EN_PCS 0x00000080 /* according to dink code, sets the 8240 to handle pci config space */
+#define PICR1_CF_DPARK 0x00000200
+#define PICR1_MCP_EN 0x00000800
+#define PICR1_FLASH_WR_EN 0x00001000
+#define PICR1_ADDRESS_NAP 0x00010000
+#define PICR1_PROC_TYPE_MSK 0x00060000
+#define PICR1_PROC_TYPE_603E 0x00040000
+#define PICR1_RCS0 0x00100000
+#define PIRC1_MSK 0xff000000
+
+#define PICR2_CF_SNOOP_WS_MASK 0x000c0000
+#define PICR2_CF_SNOOP_WS_0WS 0x00000000
+#define PICR2_CF_SNOOP_WS_1WS 0x00040000
+#define PICR2_CF_SNOOP_WS_2WS 0x00080000
+#define PICR2_CF_SNOOP_WS_3WS 0x000c0000
+#define PICR2_CF_APHASE_WS_MASK 0x0000000c
+#define PICR2_CF_APHASE_WS_0WS 0x00000000
+#define PICR2_CF_APHASE_WS_1WS 0x00000004
+#define PICR2_CF_APHASE_WS_2WS 0x00000008
+#define PICR2_CF_APHASE_WS_3WS 0x0000000c
+
+#define MCCR1_ROMNAL_SHIFT 28
+#define MCCR1_ROMNAL_MSK 0xf0000000
+#define MCCR1_ROMFAL_SHIFT 23
+#define MCCR1_ROMFAL_MSK 0x0f800000
+#define MCCR1_BURST 0x00100000
+#define MCCR1_MEMGO 0x00080000
+#define MCCR1_SREN 0x00040000
+#define MCCR1_RAM_TYPE 0x00020000
+#define MCCR1_PCKEN 0x00010000
+
+#define MCCR2_TS_WAIT_TIMER_MSK 0xe0000000
+#define MCCR2_TS_WAIT_TIMER_SHIFT 29
+#define MCCR2_ASRISE_MSK 0x1e000000
+#define MCCR2_ASRISE_SHIFT 25
+#define MCCR2_ASFALL_MSK 0x01e00000
+#define MCCR2_ASFALL_SHIFT 21
+
+#define MCCR2_INLINE_PAR_NOT_ECC 0x00100000
+#define MCCR2_WRITE_PARITY_CHK 0x00080000
+#define MCCR2_INLFRD_PARECC_CHK_EN 0x00040000
+#define MCCR2_ECC_EN 0x00020000
+#define MCCR2_EDO 0x00010000
+#define MCCR2_REFINT_MSK 0x0000fffc
+#define MCCR2_REFINT_SHIFT 2
+#define MCCR2_RSV_PG 0x00000002
+#define MCCR2_PMW_PAR 0x00000001
+
+#define MCCR3_BSTOPRE2TO5_MSK 0xf0000000 /*BSTOPRE[2-5]*/
+#define MCCR3_BSTOPRE2TO5_SHIFT 28
+#define MCCR3_REFREC_MSK 0x0f000000
+#define MCCR3_REFREC_SHIFT 24
+#define MCCR3_RDLAT_MSK 0x00f00000
+#define MCCR3_RDLAT_SHIFT 20
+#define MCCR3_CPX 0x00010000
+#define MCCR3_RAS6P_MSK 0x00078000
+#define MCCR3_RAS6P_SHIFT 15
+#define MCCR3_CAS5_MSK 0x00007000
+#define MCCR3_CAS5_SHIFT 12
+#define MCCR3_CP4_MSK 0x00000e00
+#define MCCR3_CP4_SHIFT 9
+#define MCCR3_CAS3_MSK 0x000001c0
+#define MCCR3_CAS3_SHIFT 6
+#define MCCR3_RCD2_MSK 0x00000038
+#define MCCR3_RCD2_SHIFT 3
+#define MCCR3_RP1_MSK 0x00000007
+#define MCCR3_RP1_SHIFT 0
+
+#define MCCR4_PRETOACT_MSK 0xf0000000
+#define MCCR4_PRETOACT_SHIFT 28
+#define MCCR4_ACTTOPRE_MSK 0x0f000000
+#define MCCR4_ACTTOPRE_SHIFT 24
+#define MCCR4_WMODE 0x00800000
+#define MCCR4_INLINE 0x00400000
+#define MCCR4_BIT21 0x00200000 /* this include cos DINK code sets it- unknown function*/
+#define MCCR4_REGISTERED 0x00100000
+#define MCCR4_BSTOPRE0TO1_MSK 0x000c0000 /*BSTOPRE[0-1]*/
+#define MCCR4_BSTOPRE0TO1_SHIFT 18
+#define MCCR4_REGDIMM 0x00008000
+#define MCCR4_SDMODE_MSK 0x00007f00
+#define MCCR4_SDMODE_SHIFT 8
+#define MCCR4_ACTTORW_MSK 0x000000f0
+#define MCCR4_ACTTORW_SHIFT 4
+#define MCCR4_BSTOPRE6TO9_MSK 0x0000000f /*BSTOPRE[0-1]*/
+#define MCCR4_BSTOPRE6TO9_SHIFT 0
+
+#define MICR_ADDR_MASK 0x0ff00000
+#define MICR_EADDR_MASK 0x30000000
+
+#define BATU_BEPI_MSK 0xfffe0000
+#define BATU_BL_MSK 0x00001ffc
+
+#define BATU_BL_128K 0x00000000
+#define BATU_BL_256K 0x00000004
+#define BATU_BL_512K 0x0000000c
+#define BATU_BL_1M 0x0000001c
+#define BATU_BL_2M 0x0000003c
+#define BATU_BL_4M 0x0000007c
+#define BATU_BL_8M 0x000000fc
+#define BATU_BL_16M 0x000001fc
+#define BATU_BL_32M 0x000003fc
+#define BATU_BL_64M 0x000007fc
+#define BATU_BL_128M 0x00000ffc
+#define BATU_BL_256M 0x00001ffc
+
+#define BATU_VS 0x00000002
+#define BATU_VP 0x00000001
+
+#define BATL_BRPN_MSK 0xfffe0000
+#define BATL_WIMG_MSK 0x00000078
+#define BATL_WRITETHROUGH 0x00000008
+#define BATL_CACHEINHIBIT 0x00000010
+#define BATL_MEMCOHERENCE 0x00000020
+#define BATL_GUARDEDSTORAGE 0x00000040
+#define BATL_PP_MSK 0x00000003
+#define BATL_PP_00 0x00000000
+#define BATL_PP_01 0x00000001
+#define BATL_PP_10 0x00000002
+#define BATL_PP_11 0x00000003
+
+/* I'd attempt to do defines for the PP bits, but it's use is a bit too complex,
+ * see the PowerPC Operating Environment Architecture section in the PowerPc arch book.
+ * chapter 4
+ */
+
+/*eumb and epic config*/
+
+#define EPIC_FPR 0x00041000
+#define EPIC_GCR 0x00041020
+#define EPIC_EICR 0x00041030
+#define EPIC_EVI 0x00041080
+#define EPIC_PI 0x00041090
+#define EPIC_SVR 0x000410E0
+#define EPIC_TFRR 0x000410F0
+
+/*note the information for these is rather mangled in the 8240 manual. these are guesses*/
+#define EPIC_GTCCR0 0x00041100
+#define EPIC_GTCCR1 0x00041140
+#define EPIC_GTCCR2 0x00041180
+#define EPIC_GTCCR3 0x000411C0
+#define EPIC_GTBCR0 0x00041110
+#define EPIC_GTBCR1 0x00041150
+#define EPIC_GTBCR2 0x00041190
+#define EPIC_GTBCR3 0x000411D0
+#define EPIC_GTVPR0 0x00041120
+#define EPIC_GTVPR1 0x00041160
+#define EPIC_GTVPR2 0x000411a0
+#define EPIC_GTVPR3 0x000411e0
+#define EPIC_GTDR0 0x00041130
+#define EPIC_GTDR1 0x00041170
+#define EPIC_GTDR2 0x000411b0
+#define EPIC_GTDR3 0x000411f0
+
+#define EPIC_IVPR0 0x00050200
+#define EPIC_IVPR1 0x00050220
+#define EPIC_IVPR2 0x00050240
+#define EPIC_IVPR3 0x00050260
+#define EPIC_IVPR4 0x00050280
+
+#define EPIC_SVPR0 0x00050200
+#define EPIC_SVPR1 0x00050220
+#define EPIC_SVPR2 0x00050240
+#define EPIC_SVPR3 0x00050260
+#define EPIC_SVPR4 0x00050280
+#define EPIC_SVPR5 0x000502A0
+#define EPIC_SVPR6 0x000502C0
+#define EPIC_SVPR7 0x000502E0
+#define EPIC_SVPR8 0x00050300
+#define EPIC_SVPR9 0x00050320
+#define EPIC_SVPRa 0x00050340
+#define EPIC_SVPRb 0x00050360
+#define EPIC_SVPRc 0x00050380
+#define EPIC_SVPRd 0x000503A0
+#define EPIC_SVPRe 0x000503C0
+#define EPIC_SVPRf 0x000503E0
+
+#endif /* __MPC8240_H__ */
#ifndef _PCMCIA_H
#define _PCMCIA_H
+#include <ppcboot.h>
+#include <config.h>
+
+#ifdef CONFIG_IDE_PCMCIA
+/*
+ * Allow configuration to select PCMCIA slot,
+ * or try to generate a useful default
+ */
+#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
+
+ /* The RPX series use SLOT_B */
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+# define CONFIG_PCMCIA_SLOT_B
+#elif defined(CONFIG_ADS) /* The ADS board use SLOT_A */
+# define CONFIG_PCMCIA_SLOT_A
+#elif defined(CONFIG_FADS) /* The FADS series are a mess */
+# if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
+# define CONFIG_PCMCIA_SLOT_A
+# else
+# define CONFIG_PCMCIA_SLOT_B
+# endif
+#elif defined(CONFIG_TQM860L) || defined(CONFIG_TQM855L) /* The TQM8xxL modules */
+# define CONFIG_PCMCIA_SLOT_A /* ... use SLOT_A on MPC860/855 */
+#elif defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
+# define CONFIG_PCMCIA_SLOT_B /* ... and SLOT_B else */
+#elif defined(CONFIG_SPD823TS) /* The SPD8xx use SLOT_B */
+# define CONFIG_PCMCIA_SLOT_B
+#elif defined(CONFIG_IVMS8) /* The IVMS8 use SLOT_A */
+# define CONFIG_PCMCIA_SLOT_A
+#else
+# error "PCMCIA Slot not configured"
+#endif
+
+#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
+
+/* Make sure exactly one slot is defined - we support only one for now */
+#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
+#error Neither CONFIG_PCMCIA_SLOT_A nor CONFIG_PCMCIA_SLOT_B configured
+#endif
+#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
+#error Both CONFIG_PCMCIA_SLOT_A and CONFIG_PCMCIA_SLOT_B configured
+#endif
+
+#define PCMCIA_SOCKETS_NO 1
+#define PCMCIA_MEM_WIN_NO 4
+#define PCMCIA_IO_WIN_NO 2
+
+/* define _slot_ to be able to optimize macros */
+#ifdef CONFIG_PCMCIA_SLOT_A
+# define _slot_ 0
+# define PCMCIA_SLOT_MSG "SLOT_A"
+# define PCMCIA_SLOT_x PCMCIA_PSLOT_A
+#else
+# define _slot_ 1
+# define PCMCIA_SLOT_MSG "SLOT_B"
+# define PCMCIA_SLOT_x PCMCIA_PSLOT_B
+#endif
+
+/*
+ * The TQM850L hardware has two pins swapped! Grrrrgh!
+ */
+#ifdef CONFIG_TQM850L
+#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXOE
+#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXRESET
+#else
+#define __MY_PCMCIA_GCRX_CXRESET PCMCIA_GCRX_CXRESET
+#define __MY_PCMCIA_GCRX_CXOE PCMCIA_GCRX_CXOE
+#endif
+
+/* look up table for pgcrx registers */
+
+#if 0
+static u_int *pcmcia_pgcrx[2] = {
+ &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
+ &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
+};
+
+#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
+#endif
+
+/*
+ * This structure is used to address each window in the PCMCIA controller.
+ *
+ * Keep in mind that we assume that pcmcia_win_t[n+1] is mapped directly
+ * after pcmcia_win_t[n]...
+ */
+
+typedef struct {
+ ulong br;
+ ulong or;
+} pcmcia_win_t;
+
+#endif /* CONFIG_IDE_PCMCIA */
+
/*
* Definitions for PCMCIA control registers to operate in IDE mode
*
*/
/* Window 0:
- * Base: 0x04100000 CS1
+ * Base: 0xFE100000 CS1
* Port Size: 2 Bytes
* Port Size: 16 Bit
* Common Memory Space
#define CFG_PCMCIA_POR0 ( PCMCIA_BSIZE_2 \
| PCMCIA_PPS_16 \
| PCMCIA_PRS_MEM \
- | PCMCIA_PSLOT_B \
+ | PCMCIA_SLOT_x \
| PCMCIA_PV \
)
/* Window 1:
- * Base: 0x04100080 CS1
+ * Base: 0xFE100080 CS1
* Port Size: 8 Bytes
* Port Size: 8 Bit
* Common Memory Space
#define CFG_PCMCIA_POR1 ( PCMCIA_BSIZE_8 \
| PCMCIA_PPS_8 \
| PCMCIA_PRS_MEM \
- | PCMCIA_PSLOT_B \
+ | PCMCIA_SLOT_x \
| PCMCIA_PV \
)
/* Window 2:
- * Base: 0x04100100 CS2
+ * Base: 0xFE100100 CS2
* Port Size: 8 Bytes
* Port Size: 8 Bit
* Common Memory Space
#define CFG_PCMCIA_POR2 ( PCMCIA_BSIZE_8 \
| PCMCIA_PPS_8 \
| PCMCIA_PRS_MEM \
- | PCMCIA_PSLOT_B \
+ | PCMCIA_SLOT_x \
| PCMCIA_PV \
)
#define CFG_PCMCIA_POR3 0
/* Window 4:
- * Base: 0x041000C00 CS1
+ * Base: 0xFE100C00 CS1
* Port Size: 2 Bytes
* Port Size: 16 Bit
* Common Memory Space
#define CFG_PCMCIA_POR4 ( PCMCIA_BSIZE_2 \
| PCMCIA_PPS_16 \
| PCMCIA_PRS_MEM \
- | PCMCIA_PSLOT_B \
+ | PCMCIA_SLOT_x \
| PCMCIA_PV \
)
/* Window 5:
- * Base: 0x04100C80 CS1
+ * Base: 0xFE100C80 CS1
* Port Size: 8 Bytes
* Port Size: 8 Bit
* Common Memory Space
#define CFG_PCMCIA_POR5 ( PCMCIA_BSIZE_8 \
| PCMCIA_PPS_8 \
| PCMCIA_PRS_MEM \
- | PCMCIA_PSLOT_B \
+ | PCMCIA_SLOT_x \
| PCMCIA_PV \
)
/* Window 6:
- * Base: 0x04100D00 CS2
+ * Base: 0xFE100D00 CS2
* Port Size: 8 Bytes
* Port Size: 8 Bit
* Common Memory Space
#define CFG_PCMCIA_POR6 ( PCMCIA_BSIZE_8 \
| PCMCIA_PPS_8 \
| PCMCIA_PRS_MEM \
- | PCMCIA_PSLOT_B \
+ | PCMCIA_SLOT_x \
| PCMCIA_PV \
)
#define r31 31
-#if defined(CONFIG_8xx)
+#if defined(CONFIG_8xx) || defined(CONFIG_MPC8240)
/* Some special registers */
#define LCTRL2 157 /* Load/Store Support (37-41) */
#define ICTRL 158
+#endif /* CONFIG_8xx, CONFIG_MPC8240 */
+
+#if defined(CONFIG_8xx)
/* Registers in the processor's internal memory map that we use.
*/
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * The purpose of this code is to signal the operational status of a
+ * target which usually boots over the network; while running in
+ * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
+ * message has been received, the LED is turned off. The Linux
+ * kernel, once it is running, will start blinking the LED again,
+ * with another frequency.
+ */
+
+#ifndef _STATUS_LED_H_
+#define _STATUS_LED_H_
+
+#ifdef CONFIG_STATUS_LED
+
+
+#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L) || \
+ defined(CONFIG_TQM855L) || defined(CONFIG_TQM860L)
+
+# define STATUS_LED_PAR im_cpm.cp_pbpar
+# define STATUS_LED_DIR im_cpm.cp_pbdir
+# define STATUS_LED_ODR im_cpm.cp_pbodr
+# define STATUS_LED_DAT im_cpm.cp_pbdat
+
+# define STATUS_LED_BIT 0x00000001
+
+# define STATUS_LED_PERIOD 500
+
+#elif defined(CONFIG_ETX094)
+
+# define STATUS_LED_PAR im_ioport.iop_pdpar
+# define STATUS_LED_DIR im_ioport.iop_pddir
+# undef STATUS_LED_ODR
+# define STATUS_LED_DAT im_ioport.iop_pddat
+
+# define STATUS_LED_BIT 0x00000001
+
+# define STATUS_LED_PERIOD 500
+
+#else
+# error Status LED configuration missing
+#endif
+
+#define STATUS_LED_OFF 0
+#define STATUS_LED_BLINKING 1
+#define STATUS_LED_ON 2
+
+void status_led_tick (unsigned long timestamp);
+void status_led_set (int state);
+
+
+#endif /* CONFIG_STATUS_LED */
+#endif /* _STATUS_LED_H_ */
memctl->memc_br2 = CFG_BR2;
#endif
+#if 0
/*
* Map controller bank 4 to the PER8 bank.
*/
memctl->memc_or4 = CFG_OR4;
memctl->memc_br4 = CFG_BR4;
+#endif
#if 0
/* Configure SHARC at UMA */
--- /dev/null
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(CPU).a
+
+START = start.S
+OBJS = traps.o cpu.o cpu_init.o interrupts.o \
+ drivers/epic/epic1.o
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -ffixed-r14
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC8240 -ffixed-r2 -mstring -mcpu=603e -msoft-float
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <mpc8240.h>
+#include <ppcboot.h>
+#include <command.h>
+
+int checkcpu(long clock)
+{
+ unsigned int pvr = get_pvr();
+ unsigned int version = pvr >>16;
+ unsigned int revision = pvr &0xffff;
+
+ switch(version)
+ {
+ case 0x0081:
+ printf("MPC8240");
+ break;
+ default:
+ return -1; /*not valid for this source*/
+ }
+
+ switch(revision)
+ {
+ default: /*currently no info on revision numbers*/
+ printf(" Revsion %d.%d",revision>>8, revision & 0xff);
+ }
+
+ printf(" at %lu MHz:", clock);
+
+ printf(" %u kB I-Cache", checkicache() >> 10);
+ printf(" %u kB D-Cache", checkdcache() >> 10);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+/* L1 i-cache */
+
+int checkicache(void)
+{
+ /*TODO*/
+ return 128*4*32;
+};
+/* ------------------------------------------------------------------------- */
+/* L1 d-cache */
+
+int checkdcache(void)
+{
+ /*TODO*/
+ return 128*4*32;
+
+};
+
+/*------------------------------------------------------------------- */
+
+void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ ulong msr, addr;
+
+
+ /* Interrupts and MMU off */
+ __asm__ ("mtspr 81, 0
+ mfmsr %0": "=r"(msr) : );
+ msr &= ~0x1030;
+ __asm__ ("mtmsr %0"::"r"(msr) );
+
+ /* jump to reset vector*/
+ addr = 0xfff0100;
+ ((void (*)(void ))addr)();
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Get timebase clock frequency (like cpu_clk in Hz)
+ *
+ */
+unsigned long get_tbclk (void)
+{
+ ulong tbclk;
+ /* Pointer to initial global data area */
+ init_data_t *idata =
+ (init_data_t *)(CFG_INIT_RAM_ADDR+CFG_INIT_DATA_OFFSET);
+
+ tbclk = (idata->cpu_clk + 3L) / 4L;
+
+ return (tbclk);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor. Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include <mpc8240.h>
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers,
+ */
+void
+cpu_init_f (void)
+{
+ register unsigned long val;
+ CONFIG_WRITE_WORD( PCICR, 0x06); /* Bus Master, respond to PCI memory space acesses*/
+/* CONFIG_WRITE_HALFWORD(PCISR, 0xffff); *//*reset PCISR*/
+
+ CONFIG_READ_WORD(PICR1, val);
+ CONFIG_WRITE_WORD( PICR1,
+ (val & (PICR1_ADDRESS_NAP | PICR1_RCS0)) |
+ PIRC1_MSK | PICR1_PROC_TYPE_603E |
+ PICR1_FLASH_WR_EN | PICR1_MCP_EN |
+ PICR1_CF_DPARK | PICR1_EN_PCS |
+ PICR1_CF_APARK );
+ CONFIG_READ_WORD(PICR2, val);
+ val= val & ~ (PICR2_CF_SNOOP_WS_MASK | PICR2_CF_APHASE_WS_MASK); /*mask off waitstate bits*/
+ CONFIG_WRITE_WORD(PICR2, val | PICR2_CF_SNOOP_WS_1WS | PICR2_CF_APHASE_WS_1WS); /*1 wait state*/
+ CONFIG_WRITE_WORD(EUMBBAR, CFG_EUMB_ADDR);
+#ifndef DEBUG
+ CONFIG_WRITE_WORD(MCCR1, (CFG_ROMNAL << MCCR1_ROMNAL_SHIFT) |
+ (CFG_ROMFAL << MCCR1_ROMFAL_SHIFT));
+
+ CONFIG_WRITE_WORD(MCCR2, CFG_REFINT << MCCR2_REFINT_SHIFT);
+
+ CONFIG_WRITE_WORD(MCCR3,
+ (((CFG_BSTOPRE & 0x003c) >> 2) << MCCR3_BSTOPRE2TO5_SHIFT) |
+ (CFG_REFREC << MCCR3_REFREC_SHIFT) |
+ (CFG_RDLAT << MCCR3_RDLAT_SHIFT));
+
+ CONFIG_WRITE_WORD(MCCR4,
+ (CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) |
+ (CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) |
+ MCCR4_BIT21 |
+ (CFG_REGISTERD_TYPE_BUFFER ? MCCR4_REGISTERED: 0) |
+ ((CFG_BSTOPRE & 0x0003) <<MCCR4_BSTOPRE0TO1_SHIFT ) |
+ ((CFG_SDMODE_CAS_LAT <<4) | (CFG_SDMODE_WRAP <<3) | (CFG_SDMODE_BURSTLEN) <<MCCR4_SDMODE_SHIFT) |
+ ((CFG_BSTOPRE & 0x03c0) <<MCCR4_BSTOPRE6TO9_SHIFT ));
+
+ CONFIG_WRITE_WORD(MSAR1,
+ ( CFG_BANK0_START & MICR_ADDR_MASK) |
+ ((CFG_BANK1_START & MICR_ADDR_MASK) << 8) |
+ ((CFG_BANK2_START & MICR_ADDR_MASK) << 16) |
+ ((CFG_BANK3_START & MICR_ADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(EMSAR1,
+ ( CFG_BANK0_START & MICR_EADDR_MASK) |
+ ((CFG_BANK1_START & MICR_EADDR_MASK) << 8) |
+ ((CFG_BANK2_START & MICR_EADDR_MASK) << 16) |
+ ((CFG_BANK3_START & MICR_EADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(MSAR2,
+ ( CFG_BANK4_START & MICR_ADDR_MASK) |
+ ((CFG_BANK5_START & MICR_ADDR_MASK) << 8) |
+ ((CFG_BANK6_START & MICR_ADDR_MASK) << 16) |
+ ((CFG_BANK7_START & MICR_ADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(EMSAR2,
+ ( CFG_BANK4_START & MICR_EADDR_MASK) |
+ ((CFG_BANK5_START & MICR_EADDR_MASK) << 8) |
+ ((CFG_BANK6_START & MICR_EADDR_MASK) << 16) |
+ ((CFG_BANK7_START & MICR_EADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(MEAR1,
+ ( CFG_BANK0_END & MICR_ADDR_MASK) |
+ ((CFG_BANK1_END & MICR_ADDR_MASK) << 8) |
+ ((CFG_BANK2_END & MICR_ADDR_MASK) << 16) |
+ ((CFG_BANK3_END & MICR_ADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(EMEAR1,
+ ( CFG_BANK0_END & MICR_EADDR_MASK) |
+ ((CFG_BANK1_END & MICR_EADDR_MASK) << 8) |
+ ((CFG_BANK2_END & MICR_EADDR_MASK) << 16) |
+ ((CFG_BANK3_END & MICR_EADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(MEAR2,
+ ( CFG_BANK4_END & MICR_ADDR_MASK) |
+ ((CFG_BANK5_END & MICR_ADDR_MASK) << 8) |
+ ((CFG_BANK6_END & MICR_ADDR_MASK) << 16) |
+ ((CFG_BANK7_END & MICR_ADDR_MASK) << 24));
+ CONFIG_WRITE_WORD(EMEAR2,
+ ( CFG_BANK4_END & MICR_EADDR_MASK) |
+ ((CFG_BANK5_END & MICR_EADDR_MASK) << 8) |
+ ((CFG_BANK6_END & MICR_EADDR_MASK) << 16) |
+ ((CFG_BANK7_END & MICR_EADDR_MASK) << 24));
+
+ CONFIG_WRITE_BYTE(ODCR, CFG_ODCR);
+ CONFIG_WRITE_BYTE(MBER,
+ CFG_BANK0_ENABLE |
+ (CFG_BANK1_ENABLE << 1) |
+ (CFG_BANK2_ENABLE << 2) |
+ (CFG_BANK3_ENABLE << 3) |
+ (CFG_BANK4_ENABLE << 4) |
+ (CFG_BANK5_ENABLE << 5) |
+ (CFG_BANK6_ENABLE << 6) |
+ (CFG_BANK7_ENABLE << 7));
+
+ //! Wait 200us before initialize other registers
+ /*FIXME: write a decent udelay wait */
+ __asm__ __volatile__(
+ " mtctr %0 \n \
+ 0: bdnz 0b\n"
+ :
+ : "r" (0x10000));
+
+ CONFIG_READ_WORD(MCCR1, val);
+ CONFIG_WRITE_WORD(MCCR1, val | MCCR1_MEMGO); //set memory access going
+ __asm__ __volatile__("eieio");
+#endif
+
+ /*map BAT areas - I think this should go somewhere else,
+ *but it'll be fine here for now
+ */
+ mtspr (IBAT0L, CFG_IBAT0L);
+ mtspr (IBAT0U, CFG_IBAT0U);
+ mtspr (IBAT1L, CFG_IBAT1L);
+ mtspr (IBAT1U, CFG_IBAT1U);
+ mtspr (IBAT2L, CFG_IBAT2L);
+ mtspr (IBAT2U, CFG_IBAT2U);
+ mtspr (IBAT3L, CFG_IBAT3L);
+ mtspr (IBAT3U, CFG_IBAT3U);
+ mtspr (DBAT0L, CFG_DBAT0L);
+ mtspr (DBAT0U, CFG_DBAT0U);
+ mtspr (DBAT1L, CFG_DBAT1L);
+ mtspr (DBAT1U, CFG_DBAT1U);
+ mtspr (DBAT2L, CFG_DBAT2L);
+ mtspr (DBAT2U, CFG_DBAT2U);
+ mtspr (DBAT3L, CFG_DBAT3L);
+ mtspr (DBAT3U, CFG_DBAT3U);
+
+ /*initialise TLB
+ */
+ for (val = 0; val < 0x20000; val+=0x1000)
+ tlbie(val);
+
+}
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+void
+cpu_init_r (bd_t *bd)
+{
+
+}
--- /dev/null
+##########################################################################
+#
+# $Id: Makefile,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+#
+# Copyright Motorola, Inc. 1997
+# ALL RIGHTS RESERVED
+#
+# You are hereby granted a copyright license to use, modify, and
+# distribute the SOFTWARE so long as this entire notice is retained
+# without alteration in any modified and/or redistributed versions,
+# and that such modified versions are clearly identified as such.
+# No licenses are granted by implication, estoppel or otherwise under
+# any patents or trademarks of Motorola, Inc.
+#
+# The SOFTWARE is provided on an "AS IS" basis and without warranty.
+# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+#
+# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+# INABILITY TO USE THE SOFTWARE.
+#
+# $Log: Makefile,v $
+# Revision 1.1 2000/11/20 17:22:32 wdenk
+#
+# * Added support for MBX860T (thanks to Rob Taylor)
+#
+# * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+# Work In Progress (TM); current status: boots to command line input.
+# EPIC code non-functional (interrupts disabled), No net, No IDE.
+#
+# * Add support for Status LED
+#
+# * Optionally panic() to reboot instead of hanging
+#
+# * Misc bug fixes
+#
+# * All frequencies in HZ now (internally)
+#
+# * Add support for BOOTP Domain Name Server Option
+#
+# Revision 1.1.1.1 2000/11/14 16:54:07 robt
+# no message
+#
+# Revision 1.1.1.1 2000/11/14 14:49:39 robt
+# no message
+#
+# Revision 1.4 1999/05/28 21:23:18 charliem
+# First pass at cleaning up DMA interface. This version is verified with
+# transfers from and to local memory (M2M).
+#
+# Revision 1.3 1999/02/13 02:21:02 wyin
+# Added DMAStatus enum type for better information exchange.
+#
+# Revision 1.2 1999/02/05 01:54:51 wyin
+# modified to set up soft line for hearder files
+#
+# Revision 1.1 1999/02/03 18:56:13 wyin
+# Base line
+#
+# Revision 1.12 1998/11/20 01:34:55 wyin
+# Added INTMEM function and data structure.
+# Enabled DCACHE.
+# There is a minor problem with DCACHE, the cache policy had to be write-through.
+# Otherwise, when power-on-reset, BlackBox cannot measure the scan chain length.
+# But consequence measurement is fine.
+#
+#
+############################################################################
+TARGET = libdma.a
+
+DEBUG = -DDMADBG
+LST = -Hanno -S
+OPTIM =
+CC = /risc/tools/pkgs/metaware/bin/hcppc
+CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
+CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
+PREP = $(CC) $(CFLAGS) -P
+
+# Assembler used to build the .s files (for the board version)
+
+ASOPT = -big_si -c
+ASDEBUG = -l -fm
+AS = /risc/tools/pkgs/metaware/bin/asppc
+
+# Linker to bring .o files together into an executable.
+
+LKOPT = -Bbase=0 -q -r -Qn
+LKCMD =
+LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
+
+# DOS Utilities
+
+DEL = rm
+COPY = cp
+LIST = ls
+
+OBJECTS = dma1.o dma2.o
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ $(LINK) $(OBJECTS) -o $@
+
+objects: dma1.o
+
+clean:
+ $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
+
+.s.o:
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
+# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
+
+.c.o:
+ $(CCobj) $<
+
+.c.s:
+ $(CCobj) $(LST) $<
+
+dma1.o: dma_export.h dma.h dma1.c
+
+dma2.o: dma.h dma2.s
--- /dev/null
+##########################################################################
+#
+# makefile_pc for use with mksnt tools drivers/dma
+# $Id: Makefile_pc,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+# Copyright Motorola, Inc. 1997
+# ALL RIGHTS RESERVED
+#
+# You are hereby granted a copyright license to use, modify, and
+# distribute the SOFTWARE so long as this entire notice is retained
+# without alteration in any modified and/or redistributed versions,
+# and that such modified versions are clearly identified as such.
+# No licenses are granted by implication, estoppel or otherwise under
+# any patents or trademarks of Motorola, Inc.
+#
+# The SOFTWARE is provided on an "AS IS" basis and without warranty.
+# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+#
+# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+# INABILITY TO USE THE SOFTWARE.
+#
+# $Log: Makefile_pc,v $
+# Revision 1.1 2000/11/20 17:22:32 wdenk
+#
+# * Added support for MBX860T (thanks to Rob Taylor)
+#
+# * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+# Work In Progress (TM); current status: boots to command line input.
+# EPIC code non-functional (interrupts disabled), No net, No IDE.
+#
+# * Add support for Status LED
+#
+# * Optionally panic() to reboot instead of hanging
+#
+# * Misc bug fixes
+#
+# * All frequencies in HZ now (internally)
+#
+# * Add support for BOOTP Domain Name Server Option
+#
+# Revision 1.1.1.1 2000/11/14 16:54:07 robt
+# no message
+#
+# Revision 1.1.1.1 2000/11/14 14:49:39 robt
+# no message
+#
+# Revision 1.1 1999/06/11 20:04:36 maurie
+# support for compiling dink on PC
+#
+# Revision 1.4 1999/05/28 21:23:18 charliem
+# First pass at cleaning up DMA interface. This version is verified with
+# transfers from and to local memory (M2M).
+#
+# Revision 1.3 1999/02/13 02:21:02 wyin
+# Added DMAStatus enum type for better information exchange.
+#
+# Revision 1.2 1999/02/05 01:54:51 wyin
+# modified to set up soft line for hearder files
+#
+# Revision 1.1 1999/02/03 18:56:13 wyin
+# Base line
+#
+# Revision 1.12 1998/11/20 01:34:55 wyin
+# Added INTMEM function and data structure.
+# Enabled DCACHE.
+# There is a minor problem with DCACHE, the cache policy had to be write-through.
+# Otherwise, when power-on-reset, BlackBox cannot measure the scan chain length.
+# But consequence measurement is fine.
+#
+#
+############################################################################
+TARGET = libdma.a
+
+DEBUG = -DDMADBG
+LST = -Hanno -S
+OPTIM =
+CC = m:/old_tools/tools/hcppc/bin/hcppc
+CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
+CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
+PREP = $(CC) $(CFLAGS) -P
+
+# Assembler used to build the .s files (for the board version)
+
+ASOPT = -big_si -c
+ASDEBUG = -l -fm
+AS = m:/old_tools/tools/hcppc/bin/asppc
+
+# Linker to bring .o files together into an executable.
+
+LKOPT = -Bbase=0 -q -r -Qn
+LKCMD =
+LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
+
+# DOS Utilities
+
+DEL = rm
+COPY = cp
+LIST = ls
+
+OBJECTS = dma1.o dma2.o
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ $(LINK) $(OBJECTS) -o $@
+
+objects: dma1.o
+
+clean:
+ $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
+
+.s.o:
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
+# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
+
+.c.o:
+ $(CCobj) $<
+
+.c.s:
+ $(CCobj) $(LST) $<
+
+dma1.o: dma_export.h dma.h dma1.c
+ $(CCobj) $<
+
+dma2.o: dma.h dma2.s
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
--- /dev/null
+CONTENT:
+
+ dma.h
+ dma1.c
+ dma2.s
+
+WHAT ARE THESE FILES:
+
+These files contain MPC8240 (Kahlua) DMA controller
+driver routines. The driver routines are not
+written for any specific operating system.
+They serves the purpose of code sample, and
+jump-start for using the MPC8240 DMA controller.
+
+For the reason of correctness of C language
+syntax, these files are compiled by Metaware
+C compiler and assembler.
+
+ENDIAN NOTATION:
+
+The algorithm is designed for big-endian mode,
+software is responsible for byte swapping.
+
+USAGE:
+
+1. The host system that is running on MPC8240
+ or using MPC8240 as I/O device shall link
+ the files listed here. The memory location
+ of driver routines shall take into account of
+ that driver routines need to run in supervisor
+ mode and they process DMA controller interrupt.
+
+2. The host system is responsible for configuring
+ the MPC8240 including Embedded Utilities Memory
+ Block. Since the DMA controller on MPC8240 can
+ be accessed by either local 603e core or the host
+ that MPC8240 serves as I/O processor through host
+ PCI configuration, it is important that the local
+ processor uses EUMBBAR to access its local DMA
+ controller while the PCI master uses I/O
+ processor's PCSRBAR to access the DMA controller
+ on I/O device.
+
+ To qualify whether is EUMBBAR or PCSRBAR, one
+ additional parameter is requied from the host
+ system, LOCAL or REMOTE so that the base value
+ can be correctly interpreted.
+
+3. If the host system is also using the EPIC unit
+ on MPC8240, the system can register the
+ DMA_ISR with the EPIC including other
+ desired resources.
+
+ If the host system does not using the EPIC unit
+ on MPC8240, DMA_ISR function can be called for
+ each desired time interval.
+
+ In both cases, the host system is free to
+ provide its own interrupt service routine.
+
+4. To start a direct mode DMA transaction,
+ use DMA_Bld_Curr with the start parameter
+ set to 1.
+
+ To start a chaining mode DMA transaction,
+ the application shall build descriptors
+ in memory first, next, use DMA_Bld_Desp
+ with the start parameter set to 1.
+
+5. DMA_Start function clears, then sets the CS
+ bit of DMA mode register.
+
+ DMA_Halt function clears the CS bit of DMA
+ mode register.
+
+ These functions can be used to start and
+ halt the DMA transaction.
+
+ If the chaining descriptors has been
+ modified since the last time a DMA
+ transaction started, use DMA_Chn_Cnt
+ function to let DMA controller process
+ the modified descriptor chain without
+ stopping or disturbing the current DMA
+ transaction.
+
+ It is the host system's responsibility of
+ setting up the correct DMA transfer mode
+ and pass the correct memory address parameters.
+
+6. It is the host system's responsibility of
+ queueing the DMA I/O request. The host
+ system can call the DMA_ISR with its own
+ desired interrupt service subroutines to
+ handle each individual interrupt and queued
+ DMA I/O requests.
+
+7. The DMA driver routines contains a set
+ of utilities, Set and Get, for host system
+ to query and modify the desired DMA registers.
+
+
--- /dev/null
+#ifndef DMA_H
+#define DMA_H
+/*******************************************************
+ * $Id: dma.h,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+ *
+ * copyright @ Motorola 1999
+ *
+ *******************************************************/
+#define NUM_DMA_REG 7
+#define DMA_MR_REG 0
+#define DMA_SR_REG 1
+#define DMA_CDAR_REG 2
+#define DMA_SAR_REG 3
+#define DMA_DAR_REG 4
+#define DMA_BCR_REG 5
+#define DMA_NDAR_REG 6
+
+typedef enum _dmastatus
+{
+ DMASUCCESS = 0x1000,
+ DMALMERROR,
+ DMAPERROR,
+ DMACHNBUSY,
+ DMAEOSINT,
+ DMAEOCAINT,
+ DMAINVALID,
+ DMANOEVENT,
+} DMAStatus;
+
+typedef enum _location
+{
+ LOCAL = 0, /* local processor accesses on board DMA,
+ local processor's eumbbar is required */
+ REMOTE = 1, /* PCI master accesses DMA on I/O board,
+ I/O processor's pcsrbar is required */
+} LOCATION;
+
+typedef enum dma_mr_bit
+{
+ IRQS = 0x00080000,
+ PDE = 0x00040000,
+ DAHTS = 0x00030000,
+ SAHTS = 0x0000c000,
+ DAHE = 0x00002000,
+ SAHE = 0x00001000,
+ PRC = 0x00000c00,
+ EIE = 0x00000080,
+ EOTIE = 0x00000040,
+ DL = 0x00000008,
+ CTM = 0x00000004,
+ CC = 0x00000002,
+ CS = 0x00000001,
+} DMA_MR_BIT;
+
+typedef enum dma_sr_bit
+{
+ LME = 0x00000080,
+ PE = 0x00000010,
+ CB = 0x00000004,
+ EOSI = 0x00000002,
+ EOCAI = 0x00000001,
+} DMA_SR_BIT;
+
+/* structure for DMA Mode Register */
+typedef struct _dma_mr
+{
+ unsigned int reserved0 : 12;
+ unsigned int irqs : 1;
+ unsigned int pde : 1;
+ unsigned int dahts : 2;
+ unsigned int sahts : 2;
+ unsigned int dahe : 1;
+ unsigned int sahe : 1;
+ unsigned int prc : 2;
+ unsigned int reserved1 : 1;
+ unsigned int eie : 1;
+ unsigned int eotie : 1;
+ unsigned int reserved2 : 3;
+ unsigned int dl : 1;
+ unsigned int ctm : 1;
+ /* if chaining mode is enabled, any time, user can modify the
+ * descriptor and does not need to halt the current DMA transaction.
+ * Set CC bit, enable DMA to process the modified descriptors
+ * Hardware will clear this bit each time, DMA starts.
+ */
+ unsigned int cc : 1;
+ /* cs bit has dua role, halt the current DMA transaction and
+ * (re)start DMA transaction. In chaining mode, if the descriptor
+ * needs modification, cs bit shall be used not the cc bit.
+ * Hardware will not set/clear this bit each time DMA transaction
+ * stops or starts. Software shall do it.
+ *
+ * cs bit shall not be used to halt chaining DMA transaction for
+ * modifying the descriptor. That is the role of CC bit.
+ */
+ unsigned int cs : 1;
+} DMA_MR;
+
+/* structure for DMA Status register */
+typedef struct _dma_sr
+{
+ unsigned int reserved0 : 24;
+ unsigned int lme : 1;
+ unsigned int reserved1 : 2;
+ unsigned int pe : 1;
+ unsigned int reserved2 : 1;
+ unsigned int cb : 1;
+ unsigned int eosi : 1;
+ unsigned int eocai : 1;
+} DMA_SR;
+
+/* structure for DMA current descriptor address register */
+typedef struct _dma_cdar
+{
+ unsigned int cda : 27;
+ unsigned int snen : 1;
+ unsigned int eosie : 1;
+ unsigned int ctt : 2;
+ unsigned int eotd : 1;
+} DMA_CDAR;
+
+/* structure for DMA byte count register */
+typedef struct _dma_bcr
+{
+ unsigned int reserved : 6;
+ unsigned int bcr : 26;
+} DMA_BCR;
+
+/* structure for DMA Next Descriptor Address register */
+typedef struct _dma_ndar
+{
+ unsigned int nda : 27;
+ unsigned int ndsnen : 1;
+ unsigned int ndeosie: 1;
+ unsigned int ndctt : 2;
+ unsigned int eotd : 1;
+} DMA_NDAR;
+
+/* structure for DMA current transaction info */
+typedef struct _dma_curr
+{
+ unsigned int src_addr;
+ unsigned int dest_addr;
+ unsigned int byte_cnt;
+} DMA_CURR;
+
+/************************* Kernel API********************
+ * Kernel APIs are used to interface with O.S. kernel.
+ * They are the functions required by O.S. kernel to
+ * provide I/O service.
+ ********************************************************/
+
+/**************DMA Device Control Functions ********/
+
+/**
+ * Note:
+ *
+ * In all following functions, the host (KAHLUA) processor has a
+ * choice of accessing on board local DMA (LOCAL),
+ * or DMA on a distributed KAHLUA (REMOTE). In either case,
+ * the caller shall pass the configured embedded utility memory
+ * block base address relative to the DMA. If LOCAL DMA is used,
+ * this parameter shall be EUMBBAR, if REMOTE is used, the
+ * parameter shall be the corresponding PCSRBAR.
+ **/
+
+/**************************************************************
+ * function: DMA_Get_Stat
+ *
+ * description: return the content of status register of
+ * the given DMA channel
+ * if error, return DMAINVALID. Otherwise return
+ * DMASUCCESS.
+ *
+ **************************************************************/
+static DMAStatus DMA_Get_Stat( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_SR * );
+
+/**************************************************************
+ * function: DMA_Get_Mode
+ *
+ * description: return the content of mode register of the
+ * given DMA channel
+ * if error, return DMAINVALID. Otherwise return DMASUCCESS.
+ *
+ **************************************************************/
+static DMAStatus DMA_Get_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR * );
+
+/**************************************************************
+ * function: DMA_Set_Mode
+ *
+ * description: Set a new mode to a given DMA channel
+ * return DMASUCCESS if success, otherwise return DMACHNINVALID
+ *
+ * note: It is not a good idea of changing the DMA mode during
+ * the middle of a transaction.
+ **************************************************************/
+static DMAStatus DMA_Set_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR mode );
+
+/*************************************************************
+ * function: DMA_ISR
+ *
+ * description: DMA interrupt service routine
+ * return DMAStatus based on the status
+ *
+ *************************************************************/
+static DMAStatus DMA_ISR( unsigned int eumbbar,
+ unsigned int channel,
+ DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
+ DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
+ DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
+ DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ));
+
+static DMAStatus dma_error_func( unsigned int, unsigned int, DMAStatus );
+
+/********************* DMA I/O function ********************/
+
+/************************************************************
+ * function: DMA_Start
+ *
+ * description: start a given DMA channel transaction
+ * return DMASUCCESS if success, otherwise return DMACHNINVALID
+ *
+ * note: this function will clear DMA_MR(CC) first, then
+ * set DMA_MR(CC).
+ ***********************************************************/
+static DMAStatus DMA_Start( LOCATION, unsigned int eumbbar,unsigned int channel );
+
+/***********************************************************
+ * function: DMA_Halt
+ *
+ * description: halt the current dma transaction on the specified
+ * channel.
+ * return DMASUCCESS if success, otherwise return DMACHNINVALID
+ *
+ * note: if the specified DMA channel is idle, nothing happens
+ *************************************************************/
+static DMAStatus DMA_Halt( LOCATION, unsigned int eumbbar,unsigned int channel );
+
+/*************************************************************
+ * function: DMA_Chn_Cnt
+ *
+ * description: set the DMA_MR(CC) bit for a given channel
+ * that is in chaining mode.
+ * return DMASUCCESS if successfule, otherwise return DMACHNINVALID
+ *
+ * note: if the given channel is not in chaining mode, nothing
+ * happen.
+ *
+ *************************************************************/
+static DMAStatus DMA_Chn_Cnt( LOCATION, unsigned int eumbbar,unsigned int channel );
+
+/*********************** App. API ***************************
+ * App. API are the APIs Kernel provides for the application
+ * level program
+ ************************************************************/
+/**************************************************************
+ * function: DMA_Bld_Curr
+ *
+ * description: set current src, dest, byte count registers
+ * according to the desp for a given channel
+ *
+ * if the given channel is busy, no change made,
+ * return DMACHNBUSY.
+ *
+ * otherwise return DMASUCCESS.
+ *
+ * note:
+ **************************************************************/
+static DMAStatus DMA_Bld_Curr( LOCATION,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CURR desp );
+
+/**************************************************************
+ * function: DMA_Poke_Curr
+ *
+ * description: poke the current src, dest, byte count registers
+ * for a given channel.
+ *
+ * return DMASUCCESS if no error otherwise return DMACHNERROR
+ *
+ * note: Due to the undeterministic parallelism, in chaining
+ * mode, the value returned by this function shall
+ * be taken as reference when the query is made rather
+ * than the absolute snapshot when the value is returned.
+ **************************************************************/
+static DMAStatus DMA_Poke_Curr( LOCATION,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CURR* desp );
+
+/**************************************************************
+ * function: DMA_Bld_Desp
+ *
+ * description: set current descriptor address register
+ * according to the desp for a given channel
+ *
+ * if the given channel is busy return DMACHNBUSY
+ * and no change made, otherwise return DMASUCCESS.
+ *
+ * note:
+ **************************************************************/
+static DMAStatus DMA_Bld_Desp( LOCATION host,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CDAR desp );
+
+/**************************************************************
+ * function: DMA_Poke_Desp
+ *
+ * description: poke the current descriptor address register
+ * for a given channel
+ *
+ * return DMASUCCESS if no error otherwise return
+ * DMAINVALID
+ *
+ * note: Due to the undeterministic parallellism of DMA operation,
+ * the value returned by this function shall be taken as
+ * the most recently used descriptor when the last time
+ * DMA starts a chaining mode operation.
+ **************************************************************/
+static DMAStatus DMA_Poke_Desp( LOCATION,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CDAR *desp );
+
+#endif
--- /dev/null
+/************************************************************
+ * $Id: dma1.c,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *
+ * App. API
+ *
+ * App. API are the APIs Kernel provides for the application
+ * level program
+ *
+ ************************************************************/
+#include "dma_export.h"
+#include "dma.h"
+
+/* Define a macro to use an optional application-layer print function, if
+ * one was passed to the library during initialization. If there was no
+ * function pointer passed, this protects against referencing a NULL pointer.
+ * Also define The global variable that holds the passed pointer.
+ */
+#define PRINT if ( app_print ) app_print
+static int (*app_print)(char *,...);
+
+/* Set by call to get_eumbbar during DMA_Initialize.
+ * This could be globally available to the library, but there is
+ * an advantage to passing it as a parameter: it is already in a register
+ * and doesn't have to be loaded from memory. Also, that is the way the
+ * library was already implemented and I don't want to change it without
+ * a more detailed analysis.
+ * It is being set as a global variable during initialization to hide it from
+ * the DINK application layer, because it is Kahlua-specific. I think that
+ * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
+ * a Kahlua-specific library dealing with the embedded utilities memory block.
+ * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
+ * defined in dink32/drivers/i2c/i2c2.s, drivers/dma/dma2.s, etc.
+ */
+static unsigned int Global_eumbbar = 0;
+extern unsigned int get_eumbbar();
+
+
+extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
+#pragma Alias( load_runtime_reg, "load_runtime_reg" );
+
+extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
+#pragma Alias( store_runtime_reg, "store_runtime_reg" );
+
+unsigned int dma_reg_tb[][14] = {
+ /* local DMA registers */
+ {
+ /* DMA_0_MR */ 0x00001100,
+ /* DMA_0_SR */ 0x00001104,
+ /* DMA_0_CDAR */ 0x00001108,
+ /* DMA_0_SAR */ 0x00001110,
+ /* DMA_0_DAR */ 0x00001118,
+ /* DMA_0_BCR */ 0x00001120,
+ /* DMA_0_NDAR */ 0x00001124,
+ /* DMA_1_MR */ 0x00001200,
+ /* DMA_1_SR */ 0x00001204,
+ /* DMA_1_CDAR */ 0x00001208,
+ /* DMA_1_SAR */ 0x00001210,
+ /* DMA_1_DAR */ 0x00001218,
+ /* DMA_1_BCR */ 0x00001220,
+ /* DMA_1_NDAR */ 0x00001224,
+ },
+ /* remote DMA registers */
+ {
+ /* DMA_0_MR */ 0x00000100,
+ /* DMA_0_SR */ 0x00000104,
+ /* DMA_0_CDAR */ 0x00000108,
+ /* DMA_0_SAR */ 0x00000110,
+ /* DMA_0_DAR */ 0x00000118,
+ /* DMA_0_BCR */ 0x00000120,
+ /* DMA_0_NDAR */ 0x00000124,
+ /* DMA_1_MR */ 0x00000200,
+ /* DMA_1_SR */ 0x00000204,
+ /* DMA_1_CDAR */ 0x00000208,
+ /* DMA_1_SAR */ 0x00000210,
+ /* DMA_1_DAR */ 0x00000218,
+ /* DMA_1_BCR */ 0x00000220,
+ /* DMA_1_NDAR */ 0x00000224,
+ },
+};
+
+/* API functions */
+
+/* Initialize DMA unit with the following:
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * ???
+ * Interrupt enables, modes, etc. are set for each transfer.
+ *
+ * This function must be called before DMA unit can be used.
+ */
+extern
+DMA_Status DMA_Initialize( int (*p)(char *,...))
+{
+ DMAStatus status;
+ /* establish the pointer, if there is one, to the application's "printf" */
+ app_print = p;
+
+ /* If this is the first call, get the embedded utilities memory block
+ * base address. I'm not sure what to do about error handling here:
+ * if a non-zero value is returned, accept it.
+ */
+ if ( Global_eumbbar == 0)
+ Global_eumbbar = get_eumbbar();
+ if ( Global_eumbbar == 0)
+ {
+ PRINT( "DMA_Initialize: can't find EUMBBAR\n" );
+ return DMA_ERROR;
+ }
+
+ return DMA_SUCCESS;
+}
+
+
+/* Perform the DMA transfer, only direct mode is currently implemented.
+ * At this point, I think it would be better to define a different
+ * function for chaining mode.
+ * Also, I'm not sure if it is appropriate to have the "generic" API
+ * accept snoop and int_steer parameters. The DINK user interface allows
+ * them, so for now I'll leave them.
+ *
+ * int_steer controls DMA interrupt steering to PCI or local processor
+ * type is the type of transfer: M2M, M2P, P2M, P2P
+ * source is the source address of the data
+ * dest is the destination address of the data
+ * len is the length of data to transfer
+ * channel is the DMA channel to use for the transfer
+ * snoop is the snoop enable control
+ */
+extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
+ DMA_TRANSFER_TYPE type,
+ unsigned int source,
+ unsigned int dest,
+ unsigned int len,
+ DMA_CHANNEL channel,
+ DMA_SNOOP_MODE snoop)
+{
+ DMA_MR md;
+ DMA_CDAR cdar;
+ /* it's inappropriate for curr to be a struct, but I'll leave it */
+ DMA_CURR curr;
+
+ DMAStatus stat;
+
+ /* The rest of this code was moved from device.c test_dma to here.
+ * It needs to be cleaned up and validated, but at least it is removed
+ * from the application and API. Most of the mode is left hard coded.
+ * This should be changed after the final API is defined and the user
+ * application has a way to control the transfer.
+ *
+ */
+
+ if ( DMA_Get_Mode( LOCAL, Global_eumbbar, channel, &md ) != DMASUCCESS )
+ {
+ return DMA_ERROR;
+ }
+
+ md.irqs = int_steer;
+ md.pde = 0;
+ md.dahts = 3; /* 8 - byte */
+ md.sahts = 3; /* 8 - byte */
+ md.dahe = 0;
+ md.sahe = 0;
+ md.prc = 0;
+ /* if steering interrupts to local processor, use polling mode */
+ if ( int_steer == DMA_INT_STEER_PCI )
+ {
+ md.eie = 1;
+ md.eotie = 1;
+ } else {
+ md.eie = 0;
+ md.eotie = 0;
+ }
+ md.dl = 0;
+ md.ctm = 1; /* direct mode */
+ md.cc = 0;
+
+ /* validate the length range */
+ if (len > 0x3ffffff )
+ {
+ PRINT( "dev DMA: length of transfer too large: %d\n", len );
+ return DMA_ERROR;
+ }
+
+ /* inappropriate to use a struct, but leave as is for now */
+ curr.src_addr = source;
+ curr.dest_addr = dest;
+ curr.byte_cnt = len;
+
+ (void)DMA_Poke_Desp( LOCAL, Global_eumbbar, channel, &cdar );
+ cdar.snen = snoop;
+ cdar.ctt = type;
+
+ if ( ( stat = DMA_Bld_Desp( LOCAL, Global_eumbbar, channel, cdar ))
+ != DMASUCCESS ||
+ ( stat = DMA_Bld_Curr( LOCAL, Global_eumbbar, channel, curr ))
+ != DMASUCCESS ||
+ ( stat = DMA_Set_Mode( LOCAL, Global_eumbbar, channel, md ))
+ != DMASUCCESS ||
+ ( stat = DMA_Start( LOCAL, Global_eumbbar, channel ))
+ != DMASUCCESS )
+ {
+ if ( stat == DMACHNBUSY )
+ {
+ PRINT( "dev DMA: channel %d busy.\n", channel );
+ }
+ else
+ {
+ PRINT( "dev DMA: invalid channel request.\n", channel );
+ }
+
+ return DMA_ERROR;
+ }
+
+/* Since we are interested at the DMA performace right now,
+ we are going to do as less as possible to burden the
+ 603e core.
+
+ if you have epic enabled or don't care the return from
+ DMA operation, you can just return SUCCESS.
+
+ if you don't have epic enabled and care the DMA result,
+ you can use the polling method below.
+
+ Note: I'll attempt to activate the code for handling polling.
+ */
+
+#if 0
+ /* if steering interrupt to local processor, let it handle results */
+ if ( int_steer == DMA_INT_STEER_LOCAL )
+ {
+ return DMA_SUCCESS;
+ }
+
+ /* polling since interrupt goes to PCI */
+ do
+ {
+ stat = DMA_ISR( Global_eumbbar, channel, dma_error_func,
+ dma_error_func, dma_error_func, dma_error_func );
+ }
+ while ( stat == DMANOEVENT );
+#endif
+
+ return DMA_SUCCESS;
+}
+
+/* DMA library internal functions */
+
+/**
+ * Note:
+ *
+ * In all following functions, the host (KAHLUA) processor has a
+ * choice of accessing on board local DMA (LOCAL),
+ * or DMA on a distributed KAHLUA (REMOTE). In either case,
+ * the caller shall pass the configured embedded utility memory
+ * block base address relative to the DMA. If LOCAL DMA is used,
+ * this parameter shall be EUMBBAR, if REMOTE is used, the
+ * parameter shall be the corresponding PCSRBAR.
+ **/
+
+/**************************************************************
+ * function: DMA_Get_Stat
+ *
+ * description: return the content of status register of
+ * the given DMA channel
+ *
+ * if error, reserved0 field all 1s.
+ **************************************************************/
+static
+DMAStatus DMA_Get_Stat( LOCATION host, unsigned int eumbbar, unsigned int channel, DMA_SR *stat )
+{
+ unsigned int tmp;
+
+ if ( channel != 0 && channel != 1 || stat == 0 )
+ {
+ return DMAINVALID;
+ }
+
+ tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG] );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) stat = 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG], tmp );
+#endif
+
+ stat->reserved0 = ( tmp & 0xffffff00 ) >> 8;
+ stat->lme = ( tmp & 0x00000080 ) >> 7;
+ stat->reserved1 = ( tmp & 0x00000060 ) >> 5;
+ stat->pe = ( tmp & 0x00000010 ) >> 4;
+ stat->reserved2 = ( tmp & 0x00000008 ) >> 3;
+ stat->cb = ( tmp & 0x00000004 ) >> 2;
+ stat->eosi = ( tmp & 0x00000002 ) >> 1;
+ stat->eocai = ( tmp & 0x00000001 );
+
+ return DMASUCCESS;
+}
+
+/**************************************************************
+ * function: DMA_Get_Mode
+ *
+ * description: return the content of mode register of the
+ * given DMA channel
+ *
+ * if error, return DMAINVALID, otherwise return
+ * DMASUCCESS
+ **************************************************************/
+static
+DMAStatus DMA_Get_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR *mode )
+{
+ unsigned int tmp;
+ if ( channel != 0 && channel != 1 || mode == 0 )
+ {
+ return DMAINVALID;
+ }
+
+ tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG] );
+
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) mode = 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG], tmp );
+#endif
+
+ mode->reserved0 = (tmp & 0xfff00000) >> 20;
+ mode->irqs = (tmp & 0x00080000) >> 19;
+ mode->pde = (tmp & 0x00040000) >> 18;
+ mode->dahts = (tmp & 0x00030000) >> 16;
+ mode->sahts = (tmp & 0x0000c000) >> 14;
+ mode->dahe = (tmp & 0x00002000) >> 13;
+ mode->sahe = (tmp & 0x00001000) >> 12;
+ mode->prc = (tmp & 0x00000c00) >> 10;
+ mode->reserved1 = (tmp & 0x00000200) >> 9;
+ mode->eie = (tmp & 0x00000100) >> 8;
+ mode->eotie = (tmp & 0x00000080) >> 7;
+ mode->reserved2 = (tmp & 0x00000070) >> 4;
+ mode->dl = (tmp & 0x00000008) >> 3;
+ mode->ctm = (tmp & 0x00000004) >> 2;
+ mode->cc = (tmp & 0x00000002) >> 1;
+ mode->cs = (tmp & 0x00000001);
+
+ return DMASUCCESS;
+}
+
+/**************************************************************
+ * function: DMA_Set_Mode
+ *
+ * description: Set a new mode to a given DMA channel
+ *
+ * note: It is not a good idea of changing the DMA mode during
+ * the middle of a transaction.
+ **************************************************************/
+static
+DMAStatus DMA_Set_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR mode )
+{
+ unsigned int tmp;
+ if ( channel != 0 && channel != 1 )
+ {
+ return DMAINVALID;
+ }
+
+ tmp = ( mode.reserved0 & 0xfff ) << 20;
+ tmp |= ( ( mode.irqs & 0x1 ) << 19);
+ tmp |= ( ( mode.pde & 0x1 ) << 18 );
+ tmp |= ( ( mode.dahts & 0x3 ) << 16 );
+ tmp |= ( ( mode.sahts & 0x3 ) << 14 );
+ tmp |= ( ( mode.dahe & 0x1 ) << 13 );
+ tmp |= ( ( mode.sahe & 0x1 ) << 12 );
+ tmp |= ( ( mode.prc & 0x3 ) << 10 );
+ tmp |= ( ( mode.reserved1 & 0x1 ) << 9 );
+ tmp |= ( ( mode.eie & 0x1 ) << 8 );
+ tmp |= ( ( mode.eotie & 0x1 ) << 7 );
+ tmp |= ( ( mode.reserved2 & 0x7 ) << 4 );
+ tmp |= ( ( mode.dl & 0x1 ) << 3 );
+ tmp |= ( ( mode.ctm & 0x1 ) << 2 );
+ tmp |= ( ( mode.cc & 0x1 ) << 1 ) ;
+ tmp |= ( mode.cs & 0x1 );
+
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], tmp );
+ return DMASUCCESS;
+}
+
+/************************************************************
+ * function: DMA_Start
+ *
+ * description: start a given DMA channel transaction
+ * return DMASUCCESS if success otherwise return
+ * DMAStatus value
+ *
+ * note: this function will clear DMA_MR(CC) first, then
+ * set DMA_MR(CC).
+ ***********************************************************/
+static
+DMAStatus DMA_Start( LOCATION host, unsigned int eumbbar, unsigned int channel )
+{
+ DMA_SR stat;
+ unsigned int mode;
+
+ if ( channel != 0 && channel != 1 )
+ {
+ return DMAINVALID;
+ }
+
+ if ( DMA_Get_Stat( host, eumbbar, channel, &stat ) != DMASUCCESS )
+ {
+ return DMAINVALID;
+ }
+
+ if ( stat.cb == 1 )
+ {
+ /* DMA is not free */
+ return DMACHNBUSY;
+ }
+
+ mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG] );
+ /* clear DMA_MR(CS) */
+ mode &= 0xfffffffe;
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
+
+ /* set DMA_MR(CS) */
+ mode |= CS;
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
+ return DMASUCCESS;
+}
+
+/***********************************************************
+ * function: DMA_Halt
+ *
+ * description: halt the current dma transaction on the specified
+ * channel.
+ * return DMASUCCESS if success otherwise return DMAINVALID
+ *
+ * note: if the specified DMA channel is idle, nothing happens
+ *************************************************************/
+static
+DMAStatus DMA_Halt( LOCATION host, unsigned int eumbbar, unsigned int channel )
+{
+ unsigned int mode;
+ if ( channel != 0 && channel != 1 )
+ {
+ return DMAINVALID;
+ }
+
+ mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG]);
+
+ /* clear DMA_MR(CS) */
+ mode &= 0xfffffffe;
+ store_runtime_reg(eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
+ return DMASUCCESS;
+}
+
+/*************************************************************
+ * function: DMA_Chn_Cnt
+ *
+ * description: set the DMA_MR(CC) bit for a given channel
+ * that is in chaining mode.
+ * return DMASUCCESS if successfule, otherwise return
+ * DMAINVALID.
+ *
+ * note: if the given channel is not in chaining mode, nothing
+ * happen.
+ *
+ *************************************************************/
+static
+DMAStatus DMA_Chn_Cnt( LOCATION host, unsigned int eumbbar, unsigned int channel )
+{
+ DMA_MR mode;
+ if ( channel != 0 && channel != 1 )
+ {
+ return DMAINVALID;
+ }
+
+ if ( DMA_Get_Mode( host, eumbbar, channel, &mode ) != DMASUCCESS )
+ {
+ return DMAINVALID;
+ }
+
+ if ( mode.ctm == 0 )
+ {
+ /* either illegal mode or not chaining mode */
+ return DMAINVALID;
+ }
+
+ mode.cc = 1;
+ return DMA_Set_Mode( host, eumbbar, channel, mode );
+}
+
+/**************************************************************
+ * function: DMA_Bld_Desp
+ *
+ * description: set current descriptor address register
+ * according to the desp for a given channel
+ *
+ * if the given channel is busy return DMACHNBUSY
+ * and no change made, otherwise return DMASUCCESS.
+ *
+ * note:
+ **************************************************************/
+static
+DMAStatus DMA_Bld_Desp( LOCATION host,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CDAR desp )
+{
+ DMA_SR status;
+ unsigned int temp;
+
+ if ( channel != 0 && channel != 1 )
+ {
+ /* channel number out of range */
+ return DMAINVALID;
+ }
+
+ if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
+ {
+ return DMAINVALID;
+ }
+
+ if ( status.cb == 1 )
+ {
+ /* channel busy */
+ return DMACHNBUSY;
+ }
+
+ temp = ( desp.cda & 0x7ffffff ) << 5;
+ temp |= (( desp.snen & 0x1 ) << 4 );
+ temp |= (( desp.eosie & 0x1 ) << 3 );
+ temp |= (( desp.ctt & 0x3 ) << 1 );
+ temp |= ( desp.eotd & 0x1 );
+
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
+
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) cdar := 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
+#endif
+
+ return DMASUCCESS;
+}
+
+/**************************************************************
+ * function: DMA_Poke_Desp
+ *
+ * description: poke the current descriptor address register
+ * for a given channel
+ *
+ * return DMASUCCESS if no error
+ *
+ * note: Due to the undeterministic parallellism of DMA operation,
+ * the value returned by this function shall be taken as
+ * the most recently used descriptor when the last time
+ * DMA starts a chaining mode operation.
+ **************************************************************/
+static
+DMAStatus DMA_Poke_Desp( LOCATION host,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CDAR *desp )
+{
+ unsigned int cdar;
+ if ( channel != 0 && channel != 1 || desp == 0 )
+ {
+ return DMAINVALID;
+ }
+
+ cdar = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG] );
+
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) cdar : 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], cdar );
+#endif
+
+
+ desp->cda = ( cdar & 0xffffffe0 ) >> 5;
+ desp->snen = ( cdar & 0x00000010 ) >> 4;
+ desp->eosie = ( cdar & 0x00000008 ) >> 3;
+ desp->ctt = ( cdar & 0x00000006 ) >> 1;
+ desp->eotd = ( cdar & 0x00000001 );
+
+ return DMASUCCESS;
+}
+
+/**************************************************************
+ * function: DMA_Bld_Curr
+ *
+ * description: set current src, dest, byte count registers
+ * according to the desp for a given channel
+ * return DMASUCCESS if no error.
+ *
+ * note:
+ **************************************************************/
+static
+DMAStatus DMA_Bld_Curr( LOCATION host,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CURR desp )
+{
+ DMA_SR status;
+ if ( channel != 0 && channel != 1 )
+ {
+ /* channel number out of range */
+ return DMAINVALID;
+ }
+
+ if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
+ {
+ return DMAINVALID;
+ }
+
+ if ( status.cb == 1 )
+ {
+ /* channel busy */
+ return DMACHNBUSY;
+ }
+
+ desp.byte_cnt &= 0x03ffffff; /* upper 6-bits are 0s */
+
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG], desp.src_addr );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) src := 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.src_addr );
+#endif
+
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG], desp.dest_addr );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) dest := 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.dest_addr );
+#endif
+
+ store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG], desp.byte_cnt );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) count := 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.byte_cnt );
+#endif
+
+
+ return DMASUCCESS;
+
+}
+
+/**************************************************************
+ * function: DMA_Poke_Curr
+ *
+ * description: poke the current src, dest, byte count registers
+ * for a given channel.
+ *
+ * return DMASUCCESS if no error
+ *
+ * note: Due to the undeterministic parallelism, in chaining
+ * mode, the value returned by this function shall
+ * be taken as reference when the query is made rather
+ * than the absolute snapshot when the value is returned.
+ **************************************************************/
+static
+DMAStatus DMA_Poke_Curr( LOCATION host,
+ unsigned int eumbbar,
+ unsigned int channel,
+ DMA_CURR* desp )
+{
+ if ( channel != 0 && channel != 1 || desp == 0 )
+ {
+ return DMAINVALID;
+ }
+
+ desp->src_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG] );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) src : 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->src_addr );
+#endif
+
+ desp->dest_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG] );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) dest : 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->dest_addr );
+#endif
+
+ desp->byte_cnt = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG] );
+#ifdef DMADBG0
+ PRINT( "%s(%d): %s DMA %d (0x%08x) count : 0x%08x\n", __FILE__, __LINE__,
+ ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->byte_cnt );
+#endif
+
+
+ return DMASUCCESS;
+}
+
+/*****************************************************************
+ * function: dma_error_func
+ *
+ * description: display the error information
+ *
+ * note: This seems like a highly convoluted way to handle messages,
+ * but I'll leave it as it was in device.c when I moved it into the
+ * DMA library source.
+ ****************************************************************/
+static
+DMAStatus dma_error_func( unsigned int eumbbar, unsigned int chn, DMAStatus err)
+{
+ unsigned char *msg[] =
+ {
+ "Local Memory Error",
+ "PCI Error",
+ "Channel Busy",
+ "End-of-Segment Interrupt",
+ "End-of-Chain/Direct Interrupt",
+ };
+
+ if ( err >= DMALMERROR && err <= DMAEOCAINT )
+ {
+ PRINT( "DMA Status: channel %d %s\n", chn, msg[err-DMASUCCESS-1] );
+ }
+
+ return err;
+
+}
+
+/*************************************************************
+ * function: DMA_ISR
+ *
+ * description: DMA interrupt service routine
+ * return DMAStatus value based on
+ * the status
+ *
+ *************************************************************/
+static
+DMAStatus DMA_ISR( unsigned int eumbbar,
+ unsigned int channel,
+ DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
+ DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
+ DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
+ DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ))
+{
+
+ DMA_SR stat;
+ DMAStatus rval = DMANOEVENT;
+ unsigned int temp;
+
+ if ( channel != 0 && channel != 1 )
+ {
+ return DMAINVALID;
+ }
+
+ if ( DMA_Get_Stat( LOCAL, eumbbar, channel, &stat ) != DMASUCCESS )
+ {
+ return DMAINVALID;
+ }
+
+ if ( stat.lme == 1 )
+ {
+ /* local memory error */
+ rval = DMALMERROR;
+ if ( lme_func != 0 )
+ {
+ rval = (*lme_func)(eumbbar, channel, DMALMERROR );
+ }
+
+ }
+ else if ( stat.pe == 1 )
+ {
+ /* PCI error */
+ rval = DMAPERROR;
+ if ( pe_func != 0 )
+ {
+ rval = (*pe_func)(eumbbar, channel, DMAPERROR );
+ }
+
+ }
+ else if ( stat.eosi == 1 )
+ {
+ /* end-of-segment interrupt */
+ rval = DMAEOSINT;
+ if ( eosi_func != 0 )
+ {
+ rval = (*eosi_func)(eumbbar, channel, DMAEOSINT );
+ }
+ }
+ else
+ {
+ /* End-of-chain/direct interrupt */
+ rval = DMAEOCAINT;
+ if ( eocai_func != 0 )
+ {
+ rval = (*eocai_func)(eumbbar, channel, DMAEOCAINT );
+ }
+ }
+
+ temp = ( stat.reserved0 & 0xffffff ) << 8;
+ temp |= ( ( stat.lme & 0x1 ) << 7 ); /* write one to clear */
+ temp |= ( ( stat.reserved1 & 0x3 ) << 5 );
+ temp |= ( ( stat.pe & 0x1 ) << 4 ); /* write one to clear */
+ temp |= ( ( stat.reserved2 & 0x1 ) << 3 );
+ temp |= ( ( stat.cb & 0x1 ) << 2 ); /* write one to clear */
+ temp |= ( ( stat.eosi & 0x1 ) << 1 ); /* write one to clear */
+ temp |= ( stat.eocai & 0x1 ); /* write one to clear */
+
+ store_runtime_reg( eumbbar, dma_reg_tb[LOCAL][channel*NUM_DMA_REG + DMA_SR_REG], temp );
+
+#ifdef DMADBG0
+ PRINT( "%s(%d): DMA channel %d SR := 0x%08x\n", __FILE__, __LINE__, channel, temp );
+#endif
+
+ return rval;
+}
--- /dev/null
+/**************************************
+ * $Id: dma2.S,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *
+ **************************************/
+
+/**********************************************************
+ * function: load_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ *
+ * output: r3 - register content
+ **********************************************************/
+ .text
+ .align 2
+ .global load_runtime_reg
+
+load_runtime_reg:
+
+ lwbrx r3,r4,r3
+ sync
+
+ bclr 20, 0
+
+/****************************************************************
+ * function: store_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ * r5 - new value to be stored
+ *
+ ****************************************************************/
+ .text
+ .align 2
+ .global store_runtime_reg
+store_runtime_reg:
+
+ stwbrx r5, r4, r3
+ sync
+
+ bclr 20,0
+
+
+
--- /dev/null
+#ifndef DMA_EXPORT_H
+#define DMA_EXPORT_H
+
+/****************************************************
+ * $Id:
+ *
+ * Copyright Motorola 1999
+ *
+ * $Log:
+ *
+ ****************************************************/
+
+/* These are the defined return values for the DMA_* functions.
+ * Any non-zero value indicates failure. Failure modes can be added for
+ * more detailed error reporting.
+ */
+typedef enum _dma_status
+{
+ DMA_SUCCESS = 0,
+ DMA_ERROR,
+} DMA_Status;
+
+/* These are the defined channel transfer types. */
+typedef enum _dma_transfer_types
+{
+ DMA_M2M = 0, /* local memory to local memory */
+ DMA_M2P = 1, /* local memory to PCI */
+ DMA_P2M = 2, /* PCI to local memory */
+ DMA_P2P = 3, /* PCI to PCI */
+} DMA_TRANSFER_TYPE;
+
+typedef enum _dma_interrupt_steer
+{
+ DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
+ DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
+} DMA_INTERRUPT_STEER;
+
+typedef enum _dma_channel
+{
+ DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
+ DMA_CHN_1 = 1,
+} DMA_CHANNEL;
+
+typedef enum _dma_snoop_mode
+{
+ DMA_SNOOP_DISABLE = 0,
+ DMA_SNOOP_ENABLE = 1,
+} DMA_SNOOP_MODE;
+
+/******************** App. API ********************
+ * The application API is for user level application
+ * to use the functionality provided by DMA driver.
+ * This is a "generic" DMA interface, it should contain
+ * nothing specific to the Kahlua implementation.
+ * Only the generic functions are exported by the library.
+ *
+ * Note: Its App.s responsibility to swap the data
+ * byte. In our API, we currently transfer whatever
+ * we are given - Big/Little Endian. This could
+ * become part of the DMA config, though.
+ **************************************************/
+
+
+/* Initialize DMA unit with the following:
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * ???
+ * Interrupt enables, modes, etc. are set for each transfer.
+ *
+ * This function must be called before DMA unit can be used.
+ */
+extern DMA_Status DMA_Initialize(
+ int (*app_print_function)(char *,...)); /* pointer to optional "printf"
+ * provided by application
+ */
+
+/* Perform the DMA transfer, only direct mode is currently implemented.
+ * At this point, I think it would be better to define a different
+ * function for chaining mode.
+ * Also, I'm not sure if it is appropriate to have the "generic" API
+ * accept snoop and int_steer parameters. The DINK user interface allows
+ * them, so for now I'll leave them.
+ *
+ * int_steer controls DMA interrupt steering to PCI or local processor
+ * type is the type of transfer: M2M, M2P, P2M, P2P
+ * source is the source address of the data
+ * dest is the destination address of the data
+ * len is the length of data to transfer
+ * channel is the DMA channel to use for the transfer
+ * snoop is the snoop enable control
+ */
+extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
+ DMA_TRANSFER_TYPE type,
+ unsigned int source,
+ unsigned int dest,
+ unsigned int len,
+ DMA_CHANNEL channel,
+ DMA_SNOOP_MODE snoop);
+#endif
--- /dev/null
+#ifndef DMA_EXPORT_H
+#define DMA_EXPORT_H
+
+/****************************************************
+ * $Id:
+ *
+ * Copyright Motorola 1999
+ *
+ * $Log:
+ *
+ ****************************************************/
+
+/* These are the defined return values for the DMA_* functions.
+ * Any non-zero value indicates failure. Failure modes can be added for
+ * more detailed error reporting.
+ */
+typedef enum _dma_status
+{
+ DMA_SUCCESS = 0,
+ DMA_ERROR,
+} DMA_Status;
+
+/* These are the defined channel transfer types. */
+typedef enum _dma_transfer_types
+{
+ DMA_M2M = 0, /* local memory to local memory */
+ DMA_M2P = 1, /* local memory to PCI */
+ DMA_P2M = 2, /* PCI to local memory */
+ DMA_P2P = 3, /* PCI to PCI */
+} DMA_TRANSFER_TYPE;
+
+typedef enum _dma_interrupt_steer
+{
+ DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
+ DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
+} DMA_INTERRUPT_STEER;
+
+typedef enum _dma_channel
+{
+ DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
+ DMA_CHN_1 = 1,
+} DMA_CHANNEL;
+
+typedef enum _dma_snoop_mode
+{
+ DMA_SNOOP_DISABLE = 0,
+ DMA_SNOOP_ENABLE = 1,
+} DMA_SNOOP_MODE;
+
+/******************** App. API ********************
+ * The application API is for user level application
+ * to use the functionality provided by DMA driver.
+ * This is a "generic" DMA interface, it should contain
+ * nothing specific to the Kahlua implementation.
+ * Only the generic functions are exported by the library.
+ *
+ * Note: Its App.s responsibility to swap the data
+ * byte. In our API, we currently transfer whatever
+ * we are given - Big/Little Endian. This could
+ * become part of the DMA config, though.
+ **************************************************/
+
+
+/* Initialize DMA unit with the following:
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * ???
+ * Interrupt enables, modes, etc. are set for each transfer.
+ *
+ * This function must be called before DMA unit can be used.
+ */
+extern DMA_Status DMA_Initialize(
+ int (*app_print_function)(char *,...)); /* pointer to optional "printf"
+ * provided by application
+ */
+
+/* Perform the DMA transfer, only direct mode is currently implemented.
+ * At this point, I think it would be better to define a different
+ * function for chaining mode.
+ * Also, I'm not sure if it is appropriate to have the "generic" API
+ * accept snoop and int_steer parameters. The DINK user interface allows
+ * them, so for now I'll leave them.
+ *
+ * int_steer controls DMA interrupt steering to PCI or local processor
+ * type is the type of transfer: M2M, M2P, P2M, P2P
+ * source is the source address of the data
+ * dest is the destination address of the data
+ * len is the length of data to transfer
+ * channel is the DMA channel to use for the transfer
+ * snoop is the snoop enable control
+ */
+extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
+ DMA_TRANSFER_TYPE type,
+ unsigned int source,
+ unsigned int dest,
+ unsigned int len,
+ DMA_CHANNEL channel,
+ DMA_SNOOP_MODE snoop);
+#endif
--- /dev/null
+#include "epic/epic.h"
--- /dev/null
+CONTENT:
+
+ epic.h
+ epic1.c
+ epic2.s
+
+WHAT ARE THESE FILES:
+
+These files contain MPC8240 (Kahlua) EPIC
+driver routines. The driver routines are not
+written for any specific operating system.
+They serves the purpose of code sample, and
+jump-start for using the MPC8240 EPIC unit.
+
+For the reason of correctness of C language
+syntax, these files are compiled by Metaware
+C compiler and assembler.
+
+ENDIAN NOTATION:
+
+The algorithm is designed for big-endian mode,
+software is responsible for byte swapping.
+
+USAGE:
+
+1. The host system that is running on MPC8240
+ shall link the files listed here. The memory
+ location of driver routines shall take into
+ account of that driver routines need to run
+ in supervisor mode and they process external
+ interrupts.
+
+ The routine epic_exception shall be called by
+ exception vector at location 0x500, i.e.,
+ 603e core external exception vector.
+
+2. The host system is responsible for configuring
+ the MPC8240 including Embedded Utilities Memory
+ Block. All EPIC driver functions require the
+ content of Embedded Utilities Memory Block
+ Base Address Register, EUMBBAR, as the first
+ parameter.
+
+3. Before EPIC unit of MPC8240 can be used,
+ initialize EPIC unit by calling epicInit
+ with the corresponding parameters.
+
+ The initialization shall disable the 603e
+ core External Exception by calling CoreExtIntDisable( ).
+ Next, call epicInit( ). Last, enable the 603e core
+ External Exception by calling CoreExtIntEnable( ).
+
+4. After EPIC unit has been successfully initialized,
+ epicIntSourceSet( ) shall be used to register each
+ external interrupt source. Anytime, an external
+ interrupt source can be disabled or enabled by
+ calling corresponding function, epicIntDisable( ),
+ or epicIntEnable( ).
+
+ Global Timers' resource, base count and frequency,
+ can be changed by calling epicTmFrequencySet( )
+ and epicTmBaseSet( ).
+
+ To stop counting a specific global timer, use
+ the function, epicTmInhibit while epicTmEnable
+ can be used to start counting a timer.
+
+5. To mask a set of external interrupts that are
+ are certain level below, epicIntPrioritySet( )
+ can be used. For example, if the processor's
+ current task priority register is set to 0x7,
+ only interrupts of priority 0x8 or higher will
+ be passed to the processor.
+
+ Be careful when using this function. It may
+ corrupt the current interrupt pending, selector,
+ and request registers, resulting an invalid vetor.
+
+ After enabling an interrupt, disable it may also
+ cause an invalid vector. User may consider using
+ the spurious vector interrupt service routine to
+ handle this case.
+
+6. The EPIC driver routines contains a set
+ of utilities, Set and Get, for host system
+ to query and modify the desired EPIC source
+ registers.
+
+7. Each external interrupt source shall register
+ its interrupt service routine. The routine
+ shall contain all interrupt source specific
+ processes and keep as short as possible.
+
+ Special customized end of interrupt routine
+ is optional. If it is needed, it shall contain
+ the external interrupt source specific end of
+ interrupt process.
+
+ External interrupt exception vector at 0x500
+ shall always call the epicEOI just before
+ rfi instruction. Refer to the routine,
+ epic_exception, for a code sample.
+
+
--- /dev/null
+/*********************************************************************
+ * mpc8240epic.h - EPIC module of the MPC8240 micro-controller
+ *
+ * Copyrigh 1999 Motorola Inc.
+ *
+ * Modification History:
+ * =====================
+ * 01a,04Feb99,My Created.
+ * 15Nov200, robt -modified to use in ppcboot
+ *
+*/
+
+#ifndef __INCEPICh
+#define __INCEPICh
+
+#define ULONG unsigned long
+#define MAXVEC 20
+#define MAXIRQ 5 /* IRQs */
+#define EPIC_DIRECT_IRQ 0 /* Direct interrupt type */
+
+/* EPIC register addresses */
+
+#define EPIC_EUMBBAR 0x40000 /* EUMBBAR of EPIC */
+#define EPIC_FEATURES_REG (EPIC_EUMBBAR + 0x01000)/* Feature reporting */
+#define EPIC_GLOBAL_REG (EPIC_EUMBBAR + 0x01020)/* Global config. */
+#define EPIC_INT_CONF_REG (EPIC_EUMBBAR + 0x01030)/* Interrupt config. */
+#define EPIC_VENDOR_ID_REG (EPIC_EUMBBAR + 0x01080)/* Vendor id */
+#define EPIC_PROC_INIT_REG (EPIC_EUMBBAR + 0x01090)/* Processor init. */
+#define EPIC_SPUR_VEC_REG (EPIC_EUMBBAR + 0x010e0)/* Spurious vector */
+#define EPIC_TM_FREQ_REG (EPIC_EUMBBAR + 0x010f0)/* Timer Frequency */
+
+#define EPIC_TM0_CUR_COUNT_REG (EPIC_EUMBBAR + 0x01100)/* Gbl TM0 Cur. Count*/
+#define EPIC_TM0_BASE_COUNT_REG (EPIC_EUMBBAR + 0x01110)/* Gbl TM0 Base Count*/
+#define EPIC_TM0_VEC_REG (EPIC_EUMBBAR + 0x01120)/* Gbl TM0 Vector Pri*/
+#define EPIC_TM0_DES_REG (EPIC_EUMBBAR + 0x01130)/* Gbl TM0 Dest. */
+
+#define EPIC_TM1_CUR_COUNT_REG (EPIC_EUMBBAR + 0x01140)/* Gbl TM1 Cur. Count*/
+#define EPIC_TM1_BASE_COUNT_REG (EPIC_EUMBBAR + 0x01150)/* Gbl TM1 Base Count*/
+#define EPIC_TM1_VEC_REG (EPIC_EUMBBAR + 0x01160)/* Gbl TM1 Vector Pri*/
+#define EPIC_TM1_DES_REG (EPIC_EUMBBAR + 0x01170)/* Gbl TM1 Dest. */
+
+#define EPIC_TM2_CUR_COUNT_REG (EPIC_EUMBBAR + 0x01180)/* Gbl TM2 Cur. Count*/
+#define EPIC_TM2_BASE_COUNT_REG (EPIC_EUMBBAR + 0x01190)/* Gbl TM2 Base Count*/
+#define EPIC_TM2_VEC_REG (EPIC_EUMBBAR + 0x011a0)/* Gbl TM2 Vector Pri*/
+#define EPIC_TM2_DES_REG (EPIC_EUMBBAR + 0x011b0)/* Gbl TM2 Dest */
+
+#define EPIC_TM3_CUR_COUNT_REG (EPIC_EUMBBAR + 0x011c0)/* Gbl TM3 Cur. Count*/
+#define EPIC_TM3_BASE_COUNT_REG (EPIC_EUMBBAR + 0x011d0)/* Gbl TM3 Base Count*/
+#define EPIC_TM3_VEC_REG (EPIC_EUMBBAR + 0x011e0)/* Gbl TM3 Vector Pri*/
+#define EPIC_TM3_DES_REG (EPIC_EUMBBAR + 0x011f0)/* Gbl TM3 Dest. */
+
+#define EPIC_EX_INT0_VEC_REG (EPIC_EUMBBAR + 0x10200)/* Ext. Int. Sr0 Des */
+#define EPIC_EX_INT0_DES_REG (EPIC_EUMBBAR + 0x10210)/* Ext. Int. Sr0 Vect*/
+#define EPIC_EX_INT1_VEC_REG (EPIC_EUMBBAR + 0x10220)/* Ext. Int. Sr1 Des */
+#define EPIC_EX_INT1_DES_REG (EPIC_EUMBBAR + 0x10230)/* Ext. Int. Sr1 Vect*/
+#define EPIC_EX_INT2_VEC_REG (EPIC_EUMBBAR + 0x10240)/* Ext. Int. Sr2 Des */
+#define EPIC_EX_INT2_DES_REG (EPIC_EUMBBAR + 0x10250)/* Ext. Int. Sr2 Vect*/
+#define EPIC_EX_INT3_VEC_REG (EPIC_EUMBBAR + 0x10260)/* Ext. Int. Sr3 Des */
+#define EPIC_EX_INT3_DES_REG (EPIC_EUMBBAR + 0x10270)/* Ext. Int. Sr3 Vect*/
+#define EPIC_EX_INT4_VEC_REG (EPIC_EUMBBAR + 0x10280)/* Ext. Int. Sr4 Des */
+#define EPIC_EX_INT4_DES_REG (EPIC_EUMBBAR + 0x10290)/* Ext. Int. Sr4 Vect*/
+
+#define EPIC_SR_INT0_VEC_REG (EPIC_EUMBBAR + 0x10200)/* Sr. Int. Sr0 Des */
+#define EPIC_SR_INT0_DES_REG (EPIC_EUMBBAR + 0x10210)/* Sr. Int. Sr0 Vect */
+#define EPIC_SR_INT1_VEC_REG (EPIC_EUMBBAR + 0x10220)/* Sr. Int. Sr1 Des */
+#define EPIC_SR_INT1_DES_REG (EPIC_EUMBBAR + 0x10230)/* Sr. Int. Sr1 Vect.*/
+#define EPIC_SR_INT2_VEC_REG (EPIC_EUMBBAR + 0x10240)/* Sr. Int. Sr2 Des */
+#define EPIC_SR_INT2_DES_REG (EPIC_EUMBBAR + 0x10250)/* Sr. Int. Sr2 Vect.*/
+#define EPIC_SR_INT3_VEC_REG (EPIC_EUMBBAR + 0x10260)/* Sr. Int. Sr3 Des */
+#define EPIC_SR_INT3_DES_REG (EPIC_EUMBBAR + 0x10270)/* Sr. Int. Sr3 Vect.*/
+#define EPIC_SR_INT4_VEC_REG (EPIC_EUMBBAR + 0x10280)/* Sr. Int. Sr4 Des */
+#define EPIC_SR_INT4_DES_REG (EPIC_EUMBBAR + 0x10290)/* Sr. Int. Sr4 Vect.*/
+
+#define EPIC_SR_INT5_VEC_REG (EPIC_EUMBBAR + 0x102a0)/* Sr. Int. Sr5 Des */
+#define EPIC_SR_INT5_DES_REG (EPIC_EUMBBAR + 0x102b0)/* Sr. Int. Sr5 Vect.*/
+#define EPIC_SR_INT6_VEC_REG (EPIC_EUMBBAR + 0x102c0)/* Sr. Int. Sr6 Des */
+#define EPIC_SR_INT6_DES_REG (EPIC_EUMBBAR + 0x102d0)/* Sr. Int. Sr6 Vect.*/
+#define EPIC_SR_INT7_VEC_REG (EPIC_EUMBBAR + 0x102e0)/* Sr. Int. Sr7 Des */
+#define EPIC_SR_INT7_DES_REG (EPIC_EUMBBAR + 0x102f0)/* Sr. Int. Sr7 Vect.*/
+#define EPIC_SR_INT8_VEC_REG (EPIC_EUMBBAR + 0x10300)/* Sr. Int. Sr8 Des */
+#define EPIC_SR_INT8_DES_REG (EPIC_EUMBBAR + 0x10310)/* Sr. Int. Sr8 Vect.*/
+#define EPIC_SR_INT9_VEC_REG (EPIC_EUMBBAR + 0x10320)/* Sr. Int. Sr9 Des */
+#define EPIC_SR_INT9_DES_REG (EPIC_EUMBBAR + 0x10330)/* Sr. Int. Sr9 Vect.*/
+
+#define EPIC_SR_INT10_VEC_REG (EPIC_EUMBBAR + 0x10340)/* Sr. Int. Sr10 Des */
+#define EPIC_SR_INT10_DES_REG (EPIC_EUMBBAR + 0x10350)/* Sr. Int. Sr10 Vect*/
+#define EPIC_SR_INT11_VEC_REG (EPIC_EUMBBAR + 0x10360)/* Sr. Int. Sr11 Des */
+#define EPIC_SR_INT11_DES_REG (EPIC_EUMBBAR + 0x10370)/* Sr. Int. Sr11 Vect*/
+#define EPIC_SR_INT12_VEC_REG (EPIC_EUMBBAR + 0x10380)/* Sr. Int. Sr12 Des */
+#define EPIC_SR_INT12_DES_REG (EPIC_EUMBBAR + 0x10390)/* Sr. Int. Sr12 Vect*/
+#define EPIC_SR_INT13_VEC_REG (EPIC_EUMBBAR + 0x103a0)/* Sr. Int. Sr13 Des */
+#define EPIC_SR_INT13_DES_REG (EPIC_EUMBBAR + 0x103b0)/* Sr. Int. Sr13 Vect*/
+#define EPIC_SR_INT14_VEC_REG (EPIC_EUMBBAR + 0x103c0)/* Sr. Int. Sr14 Des */
+#define EPIC_SR_INT14_DES_REG (EPIC_EUMBBAR + 0x103d0)/* Sr. Int. Sr14 Vect*/
+#define EPIC_SR_INT15_VEC_REG (EPIC_EUMBBAR + 0x103e0)/* Sr. Int. Sr15 Des */
+#define EPIC_SR_INT15_DES_REG (EPIC_EUMBBAR + 0x103f0)/* Sr. Int. Sr15 Vect*/
+
+#define EPIC_I2C_INT_VEC_REG (EPIC_EUMBBAR + 0x11020)/* I2C Int. Vect Pri.*/
+#define EPIC_I2C_INT_DES_REG (EPIC_EUMBBAR + 0x11030)/* I2C Int. Dest */
+#define EPIC_DMA0_INT_VEC_REG (EPIC_EUMBBAR + 0x11040)/* DMA0 Int. Vect Pri*/
+#define EPIC_DMA0_INT_DES_REG (EPIC_EUMBBAR + 0x11050)/* DMA0 Int. Dest */
+#define EPIC_DMA1_INT_VEC_REG (EPIC_EUMBBAR + 0x11060)/* DMA1 Int. Vect Pri*/
+#define EPIC_DMA1_INT_DES_REG (EPIC_EUMBBAR + 0x11070)/* DMA1 Int. Dest */
+#define EPIC_MSG_INT_VEC_REG (EPIC_EUMBBAR + 0x110c0)/* Msg Int. Vect Pri*/
+#define EPIC_MSG_INT_DES_REG (EPIC_EUMBBAR + 0x110d0)/* Msg Int. Dest */
+
+#define EPIC_PROC_CTASK_PRI_REG (EPIC_EUMBBAR + 0x20080)/* Proc. current task*/
+#define EPIC_PROC_INT_ACK_REG (EPIC_EUMBBAR + 0x200a0)/* Int. acknowledge */
+#define EPIC_PROC_EOI_REG (EPIC_EUMBBAR + 0x200b0)/* End of interrupt */
+
+/* Error code */
+
+#define OK 0
+#define ERROR -1
+
+/* function prototypes */
+
+void epicVendorId( unsigned int *step,
+ unsigned int *devId,
+ unsigned int *venId
+ );
+void epicFeatures( unsigned int *noIRQs,
+ unsigned int *noCPUs,
+ unsigned int *VerId );
+extern void epicInit( unsigned int IRQType, unsigned int clkRatio);
+ULONG sysEUMBBARRead ( ULONG regNum );
+void sysEUMBBARWrite ( ULONG regNum, ULONG regVal);
+extern void epicTmFrequencySet( unsigned int frq );
+extern unsigned int epicTmFrequencyGet(void);
+extern unsigned int epicTmBaseSet( ULONG srcAddr,
+ unsigned int cnt,
+ unsigned int inhibit );
+extern unsigned int epicTmBaseGet ( ULONG srcAddr, unsigned int *val );
+extern unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val );
+extern unsigned int epicTmInhibit( unsigned int timer );
+extern unsigned int epicTmEnable( ULONG srcAdr );
+extern void CoreExtIntEnable(void); /* Enable 603e external interrupts */
+extern void CoreExtIntDisable(void); /* Disable 603e external interrupts */
+extern unsigned char epicIntTaskGet(void);
+extern void epicIntTaskSet( unsigned char val );
+extern unsigned int epicIntAck(void);
+extern void epicSprSet( unsigned int eumbbar, unsigned char );
+extern void epicConfigGet( unsigned int *clkRatio,
+ unsigned int *serEnable );
+extern void SrcVecTableInit(void);
+extern unsigned int epicModeGet(void);
+extern void epicIntEnable(int Vect);
+extern void epicIntDisable(int Vect);
+extern int epicIntSourceConfig(int Vect, int Polarity, int Sense, int Prio);
+extern unsigned int epicIntAck(void);
+extern void epicEOI(void);
+extern int epicCurTaskPrioSet(int Vect);
+
+struct SrcVecTable
+ {
+ ULONG srcAddr;
+ char srcName[40];
+ };
+
+#endif /* EPIC_H */
--- /dev/null
+/**************************************************
+ * $Id: epic1.c,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * copyright @ motorola, 1999
+ *
+ *************************************************/
+#include <mpc8240.h>
+#include <ppcboot.h>
+#include "epic.h"
+
+
+#define PRINT(format, args...) printf(format , ## args)
+
+#define LONGSWAP(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+ (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) )
+
+typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */
+struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */
+ {
+ { EPIC_EX_INT0_VEC_REG, "External Direct/Serial Source 0"},
+ { EPIC_EX_INT1_VEC_REG, "External Direct/Serial Source 1"},
+ { EPIC_EX_INT2_VEC_REG, "External Direct/Serial Source 2"},
+ { EPIC_EX_INT3_VEC_REG, "External Direct/Serial Source 3"},
+ { EPIC_EX_INT4_VEC_REG, "External Direct/Serial Source 4"},
+
+ { EPIC_SR_INT5_VEC_REG, "External Serial Source 5"},
+ { EPIC_SR_INT6_VEC_REG, "External Serial Source 6"},
+ { EPIC_SR_INT7_VEC_REG, "External Serial Source 7"},
+ { EPIC_SR_INT8_VEC_REG, "External Serial Source 8"},
+ { EPIC_SR_INT9_VEC_REG, "External Serial Source 9"},
+ { EPIC_SR_INT10_VEC_REG, "External Serial Source 10"},
+ { EPIC_SR_INT11_VEC_REG, "External Serial Source 11"},
+ { EPIC_SR_INT12_VEC_REG, "External Serial Source 12"},
+ { EPIC_SR_INT13_VEC_REG, "External Serial Source 13"},
+ { EPIC_SR_INT14_VEC_REG, "External Serial Source 14"},
+ { EPIC_SR_INT15_VEC_REG, "External Serial Source 15"},
+
+ { EPIC_I2C_INT_VEC_REG, "Internal I2C Source"},
+ { EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"},
+ { EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"},
+ { EPIC_MSG_INT_VEC_REG, "Internal Message Source"},
+ };
+
+VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */
+
+
+/****************************************************************************
+* epicInit - Initialize the EPIC registers
+*
+* This routine resets the Global Configuration Register, thus it:
+* - Disables all interrupts
+* - Sets epic registers to reset values
+* - Sets the value of the Processor Current Task Priority to the
+* highest priority (0xF).
+* epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass
+* Through or 8259 compatible mode).
+*
+* If IRQType (input) is Direct IRQs:
+* - IRQType is written to the SIE bit of the EPIC Interrupt
+* Configuration register (ICR).
+* - clkRatio is ignored.
+* If IRQType is Serial IRQs:
+* - both IRQType and clkRatio will be written to the ICR register
+*/
+
+void epicInit
+ (
+ unsigned int IRQType, /* Direct or Serial */
+ unsigned int clkRatio /* Clk Ratio for Serial IRQs */
+ )
+ {
+ ULONG tmp;
+
+ tmp = sysEUMBBARRead(EPIC_GLOBAL_REG);
+ tmp |= 0xa0000000; /* Set the Global Conf. register */
+ sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp);
+ sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000);
+ tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */
+
+ if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */
+ sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff);
+ else /* Serial mode */
+ {
+ tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */
+ sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp);
+ }
+
+ while (epicIntAck() != 0xff); /* Clear all pending interrupts */
+}
+
+/****************************************************************************
+ * epicIntEnable - Enable an interrupt source
+ *
+ * This routine clears the mask bit of an external, an internal or
+ * a Timer register to enable the interrupt.
+ *
+ * RETURNS: None
+ */
+void epicIntEnable
+ (
+ int intVec /* Interrupt Vector Number */
+ )
+ {
+ ULONG tmp;
+ ULONG srAddr;
+
+ srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */
+ tmp = sysEUMBBARRead(srAddr);
+ tmp &= 0x7fffffff; /* Clear the mask bit */
+ sysEUMBBARWrite(srAddr, tmp);
+ return;
+ }
+
+/****************************************************************************
+ * epicIntDisable - Disable an interrupt source
+ *
+ * This routine sets the mask bit of an external, an internal or
+ * a Timer register to disable the interrupt.
+ *
+ * RETURNS: OK or ERROR
+ *
+ */
+
+void epicIntDisable
+ (
+ int intVec /* Interrupt vector number */
+ )
+ {
+
+ ULONG tmp, srAddr;
+
+ srAddr = SrcVecTable[intVec].srcAddr;
+ tmp = sysEUMBBARRead(srAddr);
+ tmp |= 0x80000000; /* Set the mask bit */
+ sysEUMBBARWrite(srAddr, tmp);
+ return;
+ }
+
+/****************************************************************************
+ * epicIntSourceConfig - Set properties of an interrupt source
+ *
+ * This function sets interrupt properites (Polarity, Sense, Interrupt
+ * Prority, and Interrupt Vector) of an Interrupt Source. The properties
+ * can be set when the current source is not in-request or in-service,
+ * which is determined by the Activity bit. This routine return ERROR
+ * if the the Activity bit is 1 (in-request or in-service).
+ *
+ * This function assumes that the Source Vector/Priority register (input)
+ * is a valid address.
+ *
+ * RETURNS: OK or ERROR
+ */
+
+int epicIntSourceConfig
+ (
+ int Vect, /* interrupt source vector number */
+ int Polarity, /* interrupt source polarity */
+ int Sense, /* interrupt source Sense */
+ int Prio /* interrupt source priority */
+ )
+
+ {
+ ULONG tmp, newVal;
+ ULONG actBit, srAddr;
+
+ srAddr = SrcVecTable[Vect].srcAddr;
+ tmp = sysEUMBBARRead(srAddr);
+ actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */
+ if (actBit == 1)
+ return ERROR;
+
+ tmp &= 0xff30ff00; /* Erase previously set P,S,Prio,Vector bits */
+ newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect;
+ sysEUMBBARWrite(srAddr, tmp | newVal );
+ return (OK);
+ }
+
+/****************************************************************************
+ * epicIntAck - acknowledge an interrupt
+ *
+ * This function reads the Interrupt acknowldge register and return
+ * the vector number of the highest pending interrupt.
+ *
+ * RETURNS: Interrupt Vector number.
+ */
+
+unsigned int epicIntAck(void)
+{
+ return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG ));
+}
+
+/****************************************************************************
+ * epicEOI - signal an end of interrupt
+ *
+ * This function writes 0x0 to the EOI register to signal end of interrupt.
+ * It is usually called after an interrupt routine is served.
+ *
+ * RETURNS: None
+ */
+
+void epicEOI(void)
+ {
+ sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0);
+ }
+
+/****************************************************************************
+ * epicCurTaskPrioSet - sets the priority of the Processor Current Task
+ *
+ * This function should be called after epicInit() to lower the priority
+ * of the processor current task.
+ *
+ * RETURNS: OK or ERROR
+ */
+
+int epicCurTaskPrioSet
+ (
+ int prioNum /* New priority value */
+ )
+ {
+
+ if ( (prioNum < 0) || (prioNum > 0xF))
+ return ERROR;
+ sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum);
+ return OK;
+ }
+
+
+/************************************************************************
+ * function: epicIntTaskGet
+ *
+ * description: Get value of processor current interrupt task priority register
+ *
+ * note:
+ ***********************************************************************/
+unsigned char epicIntTaskGet()
+{
+ /* get the interrupt task priority register */
+ ULONG reg;
+ unsigned char rec;
+
+ reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG );
+ rec = ( reg & 0x0F );
+ return rec;
+}
+
+
+/**************************************************************
+ * function: epicISR
+ *
+ * description: EPIC service routine called by the core exception
+ * at 0x500
+ *
+ * note:
+ **************************************************************/
+unsigned int epicISR(void)
+{
+ return 0;
+}
+
+
+/************************************************************
+ * function: epicModeGet
+ *
+ * description: query EPIC mode, return 0 if pass through mode
+ * return 1 if mixed mode
+ *
+ * note:
+ *************************************************************/
+unsigned int epicModeGet(void)
+{
+ ULONG val;
+
+ val = sysEUMBBARRead( EPIC_GLOBAL_REG );
+ return (( val & 0x20000000 ) >> 29);
+}
+
+
+/*********************************************
+ * function: epicConfigGet
+ *
+ * description: Get the EPIC interrupt Configuration
+ * return 0 if not error, otherwise return 1
+ *
+ * note:
+ ********************************************/
+void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable)
+{
+ ULONG val;
+
+ val = sysEUMBBARRead( EPIC_INT_CONF_REG );
+ *clkRatio = ( val & 0x70000000 ) >> 28;
+ *serEnable = ( val & 0x8000000 ) >> 27;
+}
+
+
+/*******************************************************************
+ * sysEUMBBARRead - Read a 32-bit EUMBBAR register
+ *
+ * This routine reads the content of a register in the Embedded
+ * Utilities Memory Block, and swaps to big endian before returning
+ * the value.
+ *
+ * RETURNS: The content of the specified EUMBBAR register.
+ */
+
+ULONG sysEUMBBARRead
+ (
+ ULONG regNum
+ )
+ {
+ ULONG temp;
+
+ temp = *(ULONG *) (CFG_EUMB_ADDR + regNum);
+ return ( LONGSWAP(temp));
+ }
+
+/*******************************************************************
+ * sysEUMBBARWrite - Write a 32-bit EUMBBAR register
+ *
+ * This routine swaps the value to little endian then writes it to
+ * a register in the Embedded Utilities Memory Block address space.
+ *
+ * RETURNS: N/A
+ */
+
+void sysEUMBBARWrite
+ (
+ ULONG regNum, /* EUMBBAR register address */
+ ULONG regVal /* Value to be written */
+ )
+ {
+
+ *(ULONG *) (EUMBBAR + regNum) = LONGSWAP(regVal);
+ return ;
+ }
+
+
+/********************************************************
+ * function: epicVendorId
+ *
+ * description: return the EPIC Vendor Identification
+ * register:
+ *
+ * siliccon version, device id, and vendor id
+ *
+ * note:
+ ********************************************************/
+void epicVendorId
+ (
+ unsigned int *step,
+ unsigned int *devId,
+ unsigned int *venId
+ )
+ {
+ ULONG val;
+ val = sysEUMBBARRead( EPIC_VENDOR_ID_REG );
+ *step = ( val & 0x00FF0000 ) >> 16;
+ *devId = ( val & 0x0000FF00 ) >> 8;
+ *venId = ( val & 0x000000FF );
+ }
+
+/**************************************************
+ * function: epicFeatures
+ *
+ * description: return the number of IRQ supported,
+ * number of CPU, and the version of the
+ * OpenEPIC
+ *
+ * note:
+ *************************************************/
+void epicFeatures
+ (
+ unsigned int *noIRQs,
+ unsigned int *noCPUs,
+ unsigned int *verId
+ )
+ {
+ ULONG val;
+
+ val = sysEUMBBARRead( EPIC_FEATURES_REG );
+ *noIRQs = ( val & 0x07FF0000 ) >> 16;
+ *noCPUs = ( val & 0x00001F00 ) >> 8;
+ *verId = ( val & 0x000000FF );
+}
+
+
+/*********************************************************
+ * function: epciTmFrequncySet
+ *
+ * description: Set the timer frequency reporting register
+ ********************************************************/
+void epicTmFrequencySet( unsigned int frq )
+{
+ sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq);
+}
+
+/*******************************************************
+ * function: epicTmFrequncyGet
+ *
+ * description: Get the current value of the Timer Frequency
+ * Reporting register
+ *
+ ******************************************************/
+unsigned int epicTmFrequencyGet(void)
+{
+ return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ;
+}
+
+
+/****************************************************
+ * function: epicTmBaseSet
+ *
+ * description: Set the #n global timer base count register
+ * return 0 if no error, otherwise return 1.
+ *
+ * note:
+ ****************************************************/
+unsigned int epicTmBaseSet
+ (
+ ULONG srcAddr, /* Address of the Timer Base register */
+ unsigned int cnt, /* Base count */
+ unsigned int inhibit /* 1 - count inhibit */
+ )
+{
+
+ unsigned int val = 0x80000000;
+ /* First inhibit counting the timer */
+ sysEUMBBARWrite(srcAddr, val) ;
+
+ /* set the new value */
+ val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31);
+ sysEUMBBARWrite(srcAddr, val) ;
+ return 0;
+}
+
+/***********************************************************************
+ * function: epicTmBaseGet
+ *
+ * description: Get the current value of the global timer base count register
+ * return 0 if no error, otherwise return 1.
+ *
+ * note:
+ ***********************************************************************/
+unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val )
+{
+ *val = sysEUMBBARRead( srcAddr );
+ *val = *val & 0x7fffffff;
+ return 0;
+}
+
+/***********************************************************
+ * function: epicTmCountGet
+ *
+ * description: Get the value of a given global timer
+ * current count register
+ * return 0 if no error, otherwise return 1
+ * note:
+ **********************************************************/
+unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val )
+{
+ *val = sysEUMBBARRead( srcAddr );
+ *val = *val & 0x7fffffff;
+ return 0;
+}
+
+
+
+/***********************************************************
+ * function: epicTmInhibit
+ *
+ * description: Stop counting of a given global timer
+ * return 0 if no error, otherwise return 1
+ *
+ * note:
+ ***********************************************************/
+unsigned int epicTmInhibit( unsigned int srcAddr )
+{
+ ULONG val;
+
+ val = sysEUMBBARRead( srcAddr );
+ val |= 0x80000000;
+ sysEUMBBARWrite( srcAddr, val );
+ return 0;
+}
+
+/******************************************************************
+ * function: epicTmEnable
+ *
+ * description: Enable counting of a given global timer
+ * return 0 if no error, otherwise return 1
+ *
+ * note:
+ *****************************************************************/
+unsigned int epicTmEnable( ULONG srcAddr )
+{
+ ULONG val;
+
+ val = sysEUMBBARRead( srcAddr );
+ val &= 0x7fffffff;
+ sysEUMBBARWrite( srcAddr, val );
+ return 0;
+}
+
+void epicSourcePrint(int Vect)
+ {
+ ULONG srcVal;
+
+ srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr);
+ PRINT("%s\n", SrcVecTable[Vect].srcName);
+ PRINT("Address = 0x%lx\n", SrcVecTable[Vect].srcAddr);
+ PRINT("Vector = %ld\n", (srcVal & 0x000000FF) );
+ PRINT("Mask = %ld\n", srcVal >> 31);
+ PRINT("Activitiy = %ld\n", (srcVal & 40000000) >> 30);
+ PRINT("Polarity = %ld\n", (srcVal & 0x00800000) >> 23);
+ PRINT("Sense = %ld\n", (srcVal & 0x00400000) >> 22);
+ PRINT("Priority = %ld\n", (srcVal & 0x000F0000) >> 16);
+ }
--- /dev/null
+/**************************************
+ * $Id: epic2.S,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *
+ **************************************/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+#include <asm/processor.h>
+
+/*********************************************
+ * function: CoreExtIntEnable
+ *
+ * description: Enable 603e core external interrupt
+ *
+ * note: mtmsr is context-synchronization
+ **********************************************/
+ .text
+ .align 2
+ .global CoreExtIntEnable
+CoreExtIntEnable:
+ mfmsr r3
+
+ ori r3,r3,0x8000 /* enable external interrupt */
+ mtmsr r3
+
+ bclr 20, 0
+
+/*******************************************
+ * function: CoreExtIntDisable
+ *
+ * description: Disable 603e core external interrupt
+ *
+ * note:
+ *******************************************/
+ .text
+ .align 2
+ .global CoreExtIntDisable
+CoreExtIntDisable:
+ mfmsr r4
+
+ xor r3,r3,r3
+ or r3,r3,r4
+
+ andis. r4,r4,0xffff
+ andi. r3,r3,0x7fff /* disable external interrupt */
+
+ or r3,r3,r4
+ mtmsr r3
+
+ bclr 20, 0
+
+/*********************************************************
+ * function: epicEOI
+ *
+ * description: signal the EOI and restore machine status
+ * Input: r3 - value of eumbbar
+ * Output: r3 - value of eumbbar
+ * r4 - ISR vector value
+ * note:
+ ********************************************************/
+ .text
+ .align 2
+ .global epicEOI
+epicEOI:
+ lis r5,0x0006 /* Build End Of Interrupt Register offset */
+ ori r5,r5,0x00b0
+ xor r7,r7,r7 /* Clear r7 */
+ stwbrx r7,r5,r3 /* Save r7, writing to this register will
+ * intidate the end of processing the
+ * highest interrupt.
+ */
+ sync
+
+ /* ---RESTORE MACHINE STATE */
+ mfmsr r13 /* Clear Recoverable Interrupt bit in MSR */
+ or r7,r7,r13
+
+ andis. r7,r7,0xffff
+ andi. r13,r13,0x7ffd /* (and disable interrupts) */
+ or r13,r13,r7
+ mtmsr r13
+
+ lwz r13,0x1c(r1) /* pull ctr */
+ mtctr r13
+
+ lwz r13,0x18(r1) /* pull xer */
+ mtctr r13
+
+ lwz r13,0x14(r1) /* pull lr */
+ mtctr r13
+
+ lwz r13,0x10(r1) /* Pull SRR1 from stack */
+ mtspr SRR1,r13 /* Restore SRR1 */
+
+ lwz r13,0xc(r1) /* Pull SRR0 from stack */
+ mtspr SRR0,r13 /* Restore SRR0 */
+
+ lwz r13,0x8(r1) /* Pull User stack pointer from stack */
+ mtspr SPRG1,r13 /* Restore SPRG1 */
+
+ lwz r4,0x4(r1) /* vector value */
+ lwz r3,0x0(r1) /* eumbbar */
+ sync
+
+ addi r1,r1,0x20 /* Deallocate stack */
+ mtspr SPRG0,r1 /* Save updated Supervisor stack pointer */
+ mfspr r1,SPRG1 /* Restore User stack pointer */
+
+ bclr 20,0
+
+/***********************************************************
+ * function: exception routine called by exception vector
+ * at 0x500, external interrupt
+ *
+ * description: Kahlua EPIC controller
+ *
+ * input: r3 - content of eumbbar
+ * output: r3 - ISR return value
+ * r4 - Interrupt vector number
+ * note:
+ ***********************************************************/
+
+ .text
+ .align 2
+ .global epic_exception
+
+epic_exception:
+
+ /*---SAVE MACHINE STATE TO A STACK */
+ mtspr SPRG1,r1 /* Save User stack pointer to SPRG1 */
+ mfspr r1,SPRG0 /* Load Supervisor stack pointer into r1 */
+
+ stwu r3,-0x20(r1) /* Push the value of eumbbar onto stack */
+
+ mfspr r3,SPRG1 /* Push User stack pointer onto stack */
+ stw r3,0x8(r1)
+ mfspr r3,SRR0 /* Push SRR0 onto stack */
+ stw r1,0xc(r1)
+ mfspr r3,SRR1 /* Push SRR1 onto stack */
+ stw r3,0x10(r1)
+ mflr r3
+ stw r3,0x14(r1) /* Push LR */
+ mfxer r3
+ stw r3,0x18(r1) /* Push Xer */
+ mfctr r3
+ stw r3,0x1c(r1) /* Push CTR */
+
+ mtspr SPRG0,r1 /* Save updated Supervisor stack pointer
+ * value to SPRG0
+ */
+ mfmsr r3
+ ori r3,r3,0x0002 /* Set Recoverable Interrupt bit in MSR */
+ mtmsr r3
+
+ /* ---READ IN THE EUMBAR REGISTER */
+ lwz r6,0(r1) /* this is eumbbar */
+ sync
+
+ /* ---READ EPIC REGISTER: PROCESSOR INTERRUPT ACKNOWLEDGE REGISTER */
+ lis r5,0x0006 /* Build Interrupt Acknowledge Register
+ * offset
+ */
+ ori r5,r5,0x00a0
+ lwbrx r7,r5,r6 /* Load interrupt vector into r7 */
+ sync
+
+ /* --MASK OFF ALL BITS EXCEPT THE VECTOR */
+ xor r3,r3,r3
+ xor r4,r4,r4
+ or r3, r3, r6 /* eumbbar in r3 */
+ andi. r4,r7,0x00ff /* Mask off bits, vector in r4 */
+
+ stw r4,0x04(r1) /* save the vector value */
+
+ lis r5,epicISR@ha
+ ori r5,r5,epicISR@l
+ mtlr r5
+ blrl
+
+ xor r30,r30,r30
+ or r30,r30,r3 /* save the r3 which containts the return value from epicISR */
+
+ /* ---READ IN THE EUMBAR REGISTER */
+ lwz r3,0(r1)
+ sync
+
+ lis r5,epicEOI@ha
+ ori r5,r5,epicEOI@l
+ mtlr r5
+ blrl
+
+ xor r3,r3,r3
+ or r3,r3,r30 /* restore the ISR return value */
+
+ bclr 20,0
--- /dev/null
+/**************************************
+ * $Id: epicutil.S,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *
+ *
+ * This file contains two commonly used
+ * lower level utility routines.
+ *
+ * The utility routines are also in other
+ * Kahlua device driver libraries. The
+ * need to be linked in only once.
+ **************************************/
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+/**********************************************************
+ * function: load_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ *
+ * output: r3 - register content
+ **********************************************************/
+ .text
+ .align 2
+ .global load_runtime_reg
+
+load_runtime_reg:
+
+ xor r5,r5,r5
+ or r5,r5,r3 /* save eumbbar */
+
+ lwbrx r3,r4,r5
+ sync
+
+ bclr 20, 0
+
+/****************************************************************
+ * function: store_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ * r5 - new value to be stored
+ *
+ ****************************************************************/
+ .text
+ .align 2
+ .global store_runtime_reg
+store_runtime_reg:
+
+ xor r0,r0,r0
+
+ stwbrx r5, r4, r3
+ sync
+
+ bclr 20,0
+
--- /dev/null
+/* Copyright Motorola, Inc. 1993, 1994
+ ALL RIGHTS RESERVED
+
+ You are hereby granted a copyright license to use, modify, and
+ distribute the SOFTWARE so long as this entire notice is retained
+ without alteration in any modified and/or redistributed versions,
+ and that such modified versions are clearly identified as such.
+ No licenses are granted by implication, estoppel or otherwise under
+ any patents or trademarks of Motorola, Inc.
+
+ The SOFTWARE is provided on an "AS IS" basis and without warranty.
+ To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+ ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+ REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+ THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+
+ To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+ MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+ BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+ INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+ INABILITY TO USE THE SOFTWARE. Motorola assumes no responsibility
+ for the maintenance and support of the SOFTWARE.
+
+*/
+
+
+#include "config.h"
+
+/*
+ 1 2 3 4 5 6 7 8
+01234567890123456789012345678901234567890123456789012345678901234567890123456789
+*/
+/* List define statements here */
+
+/* These are for all the toolboxes and functions to use. These will help
+to standardize the error handling in the current project */
+
+ /* this is the "data type" for the error
+ messages in the system */
+#define STATUS unsigned int
+
+ /* this is a success status code */
+#define SUCCESS 1
+
+ /* likewise this is failure */
+#define FAILURE 0
+
+#define NUM_ERRORS 47
+
+/* This first section of "defines" are for error codes ONLY. The called
+ routine will return one of these error codes to the caller. If the final
+ returned code is "VALID", then everything is a-okay. However, if one
+ of the functions returns a non-valid status, that error code should be
+ propogated back to all the callers. At the end, the last caller will
+ call an error_processing function, and send in the status which was
+ returned. It's up to the error_processing function to determine which
+ error occured (as indicated by the status), and print an appropriate
+ message back to the user.
+*/
+/*----------------------------------------------------------------------*/
+/* these are specifically for the parser routines */
+
+#define UNKNOWN_COMMAND 0xfb00 /* "unrecognized command " */
+#define UNKNOWN_REGISTER 0xfb01 /* "unknown register "*/
+#define ILLEGAL_RD_STAGE 0xfb02 /* cannot specify reg. family in range*/
+#define ILLEGAL_REG_FAMILY 0xfb03 /* "cannot specify a range of special
+ or miscellaneous registers"*/
+#define RANGE_CROSS_FAMILY 0xfb04 /* "cannot specify a range across
+ register families" */
+#define UNIMPLEMENTED_STAGE 0xfb05 /* invalid rd or rmm parameter format */
+#define REG_NOT_WRITEABLE 0xfb06 /* "unknown operator in arguements"*/
+#define INVALID_FILENAME 0xfb07 /* "invalid download filename" */
+#define INVALID_BAUD_RATE 0xfb08 /* invalid baud rate from sb command */
+#define UNSUPPORTED_REGISTER 0xfb09 /* Special register is not supported */
+#define FOR_BOARD_ONLY 0xfb0a /* "Not available for Unix." */
+
+
+
+/*----------------------------------------------------------------------*/
+/* these are for the error checking toolbox */
+
+#define INVALID 0xfd00 /* NOT valid */
+#define VALID 0xfd01 /* valid */
+
+ /* This error is found in the fcn:
+ is_right_size_input() to indicate
+ that the input was not 8 characters
+ long. */
+#define INVALID_SIZE 0xfd02
+
+ /* This error is found in the fcn:
+ is_valid_address_range() to indicate
+ that the address given falls outside
+ of valid memory defined by MEM_START
+ to MEM_END.
+ */
+#define OUT_OF_BOUNDS_ADDRESS 0xfd03
+
+ /* This error is found in the fcn:
+ is_valid_hex_input() to indicate that
+ one of more of the characters entered
+ are not valid hex characters. Valid
+ hex characters are 0-9, A-F, a-f.
+ */
+#define INVALID_HEX_INPUT 0xfd04
+
+ /* This error is found in the fcn:
+ is_valid_register_number() to indicate
+ that a given register does not exist.
+ */
+#define REG_NOT_READABLE 0xfd05
+
+ /* This error is found in the fcn:
+ is_word_aligned_address() to indicate
+ that the given address is not word-
+ aligned. A word-aligned address ends
+ in 0x0,0x4,0x8,0xc.
+ */
+#define NOT_WORD_ALIGNED 0xfd07
+
+ /* This error is found in the fcn:
+ is_valid_address_range() to indicate
+ that the starting address is greater
+ than the ending address.
+ */
+#define REVERSED_ADDRESS 0xfd08
+
+ /* this error tells us that the address
+ specified as the destination is within
+ the source addresses */
+#define RANGE_OVERLAP 0xfd09
+
+
+#define ERROR 0xfd0a /* An error occured */
+#define INVALID_PARAM 0xfd0b /* "invalid input parameter " */
+
+
+#define INVALID_FLAG 0xfd0c /* invalid flag */
+
+/*----------------------------------------------------------------------*/
+/* these are for the getarg toolbox */
+
+#define INVALID_NUMBER_ARGS 0xFE00 /* invalid number of commd arguements */
+#define UNKNOWN_PARAMETER 0xFE01 /* "unknown type of parameter "*/
+
+
+
+
+
+/*----------------------------------------------------------------------*/
+/* these are for the tokenizer toolbox */
+
+#define ILLEGAL_CHARACTER 0xFF00 /* unrecognized char. in input stream*/
+#define TTL_NOT_SORTED 0xFF01 /* token translation list not sorted */
+#define TTL_NOT_DEFINED 0xFF02 /* token translation list not assigned*/
+#define INVALID_STRING 0xFF03 /* unable to extract string from input */
+#define BUFFER_EMPTY 0xFF04 /* "input buffer is empty" */
+#define INVALID_MODE 0xFF05 /* input buf is in an unrecognized mode*/
+#define TOK_INTERNAL_ERROR 0xFF06 /* "internal tokenizer error" */
+#define TOO_MANY_IBS 0xFF07 /* "too many open input buffers" */
+#define NO_OPEN_IBS 0xFF08 /* "no open input buffers" */
+
+
+
+/* these are for the read from screen toolbox */
+
+#define RESERVED_WORD 0xFC00 /* used a reserved word as an arguement*/
+
+
+/* these are for the breakpoint routines */
+
+#define FULL_BPDS 0xFA00 /* breakpoint data structure is full */
+
+
+
+/* THESE are for the downloader */
+
+#define NOT_IN_S_RECORD_FORMAT 0xf900 /* "not in S-Record Format" */
+#define UNREC_RECORD_TYPE 0xf901 /* "unrecognized record type" */
+#define CONVERSION_ERROR 0xf902 /* "ascii to int conversion error" */
+#define INVALID_MEMORY 0xf903 /* "bad s-record memory address " */
+
+
+/* these are for the compression and decompression stuff */
+
+#define COMP_UNK_CHARACTER 0xf800 /* "unknown compressed character " */
+
+#define COMP_UNKNOWN_STATE 0xf801 /* "unknown binary state" */
+
+#define NOT_IN_COMPRESSED_FORMAT 0xf802 /* not in compressed S-Record format */
+
+
+/* these are for the DUART handling things */
+
+ /* "unrecognized serial port configuration" */
+#define UNKNOWN_PORT_STATE 0xf700
+
+
+/* these are for the register toolbox */
+
+ /* "cannot find register in special
+ purpose register file " */
+#define SPR_NOT_FOUND 0xf600
+
+
+/* these are for the duart specific stuff */
+
+ /* "transparent mode needs access to
+ two serial ports" */
+#define TM_NEEDS_BOTH_PORTS 0xf500
+
+
+/*----------------------------------------------------------------------*/
+/* these are specifically for the flash routines */
+#define FLASH_ERROR 0xf100 /* general flash error */
--- /dev/null
+##########################################################################
+#
+# $Id: Makefile,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+#
+# Copyright Motorola, Inc. 1997
+# ALL RIGHTS RESERVED
+#
+# You are hereby granted a copyright license to use, modify, and
+# distribute the SOFTWARE so long as this entire notice is retained
+# without alteration in any modified and/or redistributed versions,
+# and that such modified versions are clearly identified as such.
+# No licenses are granted by implication, estoppel or otherwise under
+# any patents or trademarks of Motorola, Inc.
+#
+# The SOFTWARE is provided on an "AS IS" basis and without warranty.
+# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+#
+# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+# INABILITY TO USE THE SOFTWARE.
+#
+# $Log: Makefile,v $
+# Revision 1.1 2000/11/20 17:22:33 wdenk
+#
+# * Added support for MBX860T (thanks to Rob Taylor)
+#
+# * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+# Work In Progress (TM); current status: boots to command line input.
+# EPIC code non-functional (interrupts disabled), No net, No IDE.
+#
+# * Add support for Status LED
+#
+# * Optionally panic() to reboot instead of hanging
+#
+# * Misc bug fixes
+#
+# * All frequencies in HZ now (internally)
+#
+# * Add support for BOOTP Domain Name Server Option
+#
+# Revision 1.1.1.1 2000/11/14 16:54:07 robt
+# no message
+#
+# Revision 1.1.1.1 2000/11/14 14:49:39 robt
+# no message
+#
+# Revision 1.4 1999/04/29 13:41:07 charliem
+# Capture first pass at modifications to the I2C interface. This version is
+# correct, but there are some additional modifications to be implemented.
+# Nothing but I2C should be affected.
+#
+# Revision 1.3 1999/02/11 23:14:58 wyin
+# Added MasterRcvAddress variable to handle master receiver address phase
+#
+# Revision 1.2 1999/02/05 01:55:47 wyin
+# modified to set up soft link for hearder files
+# compilable version with dink
+#
+# Revision 1.1 1999/02/03 18:58:32 wyin
+# Base line
+#
+# Revision 1.12 1998/11/20 01:34:55 wyin
+# Added INTMEM function and data structure.
+# Enabled DCACHE.
+# There is a minor problem with DCACHE, the cache policy had to be write-through.
+# Otherwise, when power-on-reset, BlackBox cannot measure the scan chain length.
+# But consequence measurement is fine.
+#
+#
+############################################################################
+TARGET = libi2c.a
+
+#DEBUG = -g
+DEBUG = -DI2CDBG
+LST = -Hanno -S
+OPTIM =
+CC = /risc/tools/pkgs/metaware/bin/hcppc
+CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
+CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
+PREP = $(CC) $(CFLAGS) -P
+
+# Assembler used to build the .s files (for the board version)
+
+ASOPT = -big_si -c
+ASDEBUG = -l -fm
+AS = /risc/tools/pkgs/metaware/bin/asppc
+
+# Linker to bring .o files together into an executable.
+
+LKOPT = -Bbase=0 -q -Qn -r
+LKCMD =
+LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
+
+# DOS Utilities
+
+DEL = rm
+COPY = cp
+LIST = ls
+
+OBJECTS = i2c1.o i2c2.o
+
+all: $(TARGET)
+
+objects: $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+ $(LINK) $(OBJECTS) -o $@
+
+clean:
+ $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
+
+.s.o:
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
+# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
+
+.c.o:
+ $(CCobj) $<
+
+.c.s:
+ $(CCobj) $(LST) $<
+
+i2c1.o: i2c_export.h i2c.h i2c1.c
+
+i2c2.o: i2c.h i2c2.s
--- /dev/null
+##########################################################################
+#
+# makefile_pc for use with PC mksnt tools dink32/drivers/i2c
+# $Id: Makefile_pc,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+#
+# Copyright Motorola, Inc. 1997
+# ALL RIGHTS RESERVED
+#
+# You are hereby granted a copyright license to use, modify, and
+# distribute the SOFTWARE so long as this entire notice is retained
+# without alteration in any modified and/or redistributed versions,
+# and that such modified versions are clearly identified as such.
+# No licenses are granted by implication, estoppel or otherwise under
+# any patents or trademarks of Motorola, Inc.
+#
+# The SOFTWARE is provided on an "AS IS" basis and without warranty.
+# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+#
+# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+# INABILITY TO USE THE SOFTWARE.
+#
+# $Log: Makefile_pc,v $
+# Revision 1.1 2000/11/20 17:22:33 wdenk
+#
+# * Added support for MBX860T (thanks to Rob Taylor)
+#
+# * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+# Work In Progress (TM); current status: boots to command line input.
+# EPIC code non-functional (interrupts disabled), No net, No IDE.
+#
+# * Add support for Status LED
+#
+# * Optionally panic() to reboot instead of hanging
+#
+# * Misc bug fixes
+#
+# * All frequencies in HZ now (internally)
+#
+# * Add support for BOOTP Domain Name Server Option
+#
+# Revision 1.1.1.1 2000/11/14 16:54:07 robt
+# no message
+#
+# Revision 1.1.1.1 2000/11/14 14:49:39 robt
+# no message
+#
+# Revision 1.1 1999/06/11 20:05:13 maurie
+# support for compiling dink on PC
+#
+# Revision 1.4 1999/04/29 13:41:07 charliem
+# Capture first pass at modifications to the I2C interface. This version is
+# correct, but there are some additional modifications to be implemented.
+# Nothing but I2C should be affected.
+#
+# Revision 1.3 1999/02/11 23:14:58 wyin
+# Added MasterRcvAddress variable to handle master receiver address phase
+#
+# Revision 1.2 1999/02/05 01:55:47 wyin
+# modified to set up soft link for hearder files
+# compilable version with dink
+#
+# Revision 1.1 1999/02/03 18:58:32 wyin
+# Base line
+#
+# Revision 1.12 1998/11/20 01:34:55 wyin
+# Added INTMEM function and data structure.
+# Enabled DCACHE.
+# There is a minor problem with DCACHE, the cache policy had to be write-through.
+# Otherwise, when power-on-reset, BlackBox cannot measure the scan chain length.
+# But consequence measurement is fine.
+#
+#
+############################################################################
+TARGET = libi2c.a
+
+#DEBUG = -g
+DEBUG = -DI2CDBG
+LST = -Hanno -S
+OPTIM =
+CC = m:/old_tools/tools/hcppc/bin/hcppc
+CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
+CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
+PREP = $(CC) $(CFLAGS) -P
+
+# Assembler used to build the .s files (for the board version)
+
+ASOPT = -big_si -c
+ASDEBUG = -l -fm
+AS = m:/old_tools/tools/hcppc/bin/asppc
+
+# Linker to bring .o files together into an executable.
+
+LKOPT = -Bbase=0 -q -Qn -r
+LKCMD =
+LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
+
+# DOS Utilities
+
+DEL = rm
+COPY = cp
+LIST = ls
+
+OBJECTS = i2c1.o i2c2.o
+
+all: $(TARGET)
+
+objects: $(OBJECTS)
+
+$(TARGET): $(OBJECTS)
+ $(LINK) $(OBJECTS) -o $@
+
+clean:
+ $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
+
+.s.o:
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
+# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
+
+.c.o:
+ $(CCobj) $<
+
+.c.s:
+ $(CCobj) $(LST) $<
+
+i2c1.o: i2c_export.h i2c.h i2c1.c
+ $(CCobj) $<
+
+
+i2c2.o: i2c.h i2c2.s
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
--- /dev/null
+CONTENT:
+
+ i2c.h
+ i2c1.c
+ i2c2.s
+
+WHAT ARE THESE FILES:
+
+These files contain MPC8240 (Kahlua) I2C
+driver routines. The driver routines are not
+written for any specific operating system.
+They serves the purpose of code sample, and
+jump-start for using the MPC8240 I2C unit.
+
+For the reason of correctness of C language
+syntax, these files are compiled by Metaware
+C compiler and assembler.
+
+ENDIAN NOTATION:
+
+The algorithm is designed for big-endian mode,
+software is responsible for byte swapping.
+
+USAGE:
+
+1. The host system that is running on MPC8240
+ shall link the files listed here. The memory
+ location of driver routines shall take into
+ account of that driver routines need to run
+ in supervisor mode and they process I2C
+ interrupt.
+
+2. The host system is responsible for configuring
+ the MPC8240 including Embedded Utilities Memory
+ Block. All I2C driver functions require the
+ content of Embedded Utilities Memory Block
+ Base Address Register, EUMBBAR, as the first
+ parameter.
+
+3. Before I2C unit of MPC8240 can be used,
+ initialize I2C unit by calling I2C_Init
+ with the corresponding parameters.
+
+ Note that the I2CFDR register shall be written
+ once during the initialization. If it is written
+ in the midst of transers, or after I2C STOPs or
+ REPEAT STATRs, depending on the data written,
+ a long reset time may be encountered.
+
+4. After I2C unit has been successfully initialized,
+ use the Application level API to send data or
+ receive data upon the desired mode, Master or
+ Slave.
+
+5. If the host system is also using the EPIC unit
+ on MPC8240, the system can register the
+ I2C_ISR with the EPIC including other
+ desired resources.
+
+ If the host system does not using the EPIC unit
+ on MPC8240, I2C_Timer_Event function can
+ be called for each desired time interval.
+
+ In both cases, the host system is free to provide
+ its own timer event handler and interrupt service
+ routine.
+
+6. The I2C driver routines contains a set
+ of utilities, Set and Get, for host system
+ to query and modify the desired I2C registers.
+
+7. It is the host system's responsibility of
+ queueing the I2C I/O request. The host
+ system shall check the I2C_ISR return code
+ for I2C I/O status. If I2C_ISR returns
+ I2CBUFFEMPTY or I2CBUFFFULL, it means
+ I2C unit has completed a I/O request
+ stated by the Application API.
+
+8. If the host system has more than one master
+ mode I2C unit I/O requests but doesn't want
+ to be intervented by being addressed as slave,
+ the host system can use the master mode
+ Application API with stop_flag set to 0 in
+ conjunction with is_cnt flag set to 1.
+ The first API call sets both stop_flag and
+ is_cnt to 0, indicating a START condition
+ shall be generated but when the end of
+ transaction is reached, do not generate a
+ STOP condition. Once the host system is
+ informed that the transaction has been
+ completed, the next Application API call
+ shall set is_cnt flag to 1, indicating a
+ repeated START condition shall be generated.
+ The last Application API call shall set
+ stop_flag
+ to 1.
+
+9. The I2C_Timer_Event function containes
+ a user defined function pointer. It
+ serves the purpose of providing the
+ host system a way to use its own event
+ handler instead of the I2C_ISR provided
+ here.
+
--- /dev/null
+#ifndef I2C_H
+#define I2C_H
+
+/****************************************************
+ * $Id: i2c.h,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * Copyright Motrola 1999
+ *
+ * $Log: i2c.h,v $
+ * Revision 1.1 2000/11/20 17:22:33 wdenk
+ *
+ * * Added support for MBX860T (thanks to Rob Taylor)
+ *
+ * * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+ * Work In Progress (TM); current status: boots to command line input.
+ * EPIC code non-functional (interrupts disabled), No net, No IDE.
+ *
+ * * Add support for Status LED
+ *
+ * * Optionally panic() to reboot instead of hanging
+ *
+ * * Misc bug fixes
+ *
+ * * All frequencies in HZ now (internally)
+ *
+ * * Add support for BOOTP Domain Name Server Option
+ *
+ * Revision 1.1.1.1 2000/11/14 16:54:07 robt
+ * no message
+ *
+ * Revision 1.1.1.1 2000/11/14 14:49:39 robt
+ * no message
+ *
+ * Revision 1.7 1999/04/30 16:25:50 charliem
+ * Change the DINK to I2C_do_transaction interface to allow the application
+ * to specify the data address as a parameter to I2C_do_transaction, rather
+ * than putting the data address into the first byte of the buffer.
+ * There is a work-around in I2C_do_transaction in this version, see comments
+ * in the i2c1.c code.
+ *
+ * Revision 1.6 1999/04/29 13:41:03 charliem
+ * Capture first pass at modifications to the I2C interface. This version is
+ * correct, but there are some additional modifications to be implemented.
+ * Nothing but I2C should be affected.
+ *
+ * Revision 1.5 1999/02/12 20:08:28 wyin
+ * Use I2C's offset as the I2CStatus base value
+ *
+ * Revision 1.4 1999/02/12 15:02:23 wyin
+ * Added I2CADDRESS constant for better information
+ * exchange to apps.
+ *
+ * Revision 1.3 1999/02/10 01:48:27 wyin
+ * Modified the way of Master Rcv generating STOP. Setting TXAK bit to 1 will
+ * not automatically generat STOP. BOOK VI is wrong.
+ *
+ * Revision 1.2 1999/02/05 01:55:44 wyin
+ * modified to set up soft link for hearder files
+ * compilable version with dink
+ *
+ * Revision 1.1 1999/02/03 18:58:30 wyin
+ * Base line
+ *
+ ****************************************************/
+
+#define I2CADR 0x00003000
+#define I2CFDR 0x00003004
+#define I2CCR 0x00003008
+#define I2CSR 0x0000300C
+#define I2CDR 0x00003010
+
+typedef enum _i2cstatus
+{
+ I2CSUCCESS = 0x3000,
+ I2CADDRESS,
+ I2CERROR,
+ I2CBUFFFULL,
+ I2CBUFFEMPTY,
+ I2CXMITERROR,
+ I2CRCVERROR,
+ I2CBUSBUSY,
+ I2CALOSS,
+ I2CNOEVENT,
+} I2CStatus;
+
+typedef enum i2c_control
+{
+ MEN = 0x00000080,
+ MIEN = 0x00000040,
+ MSTA = 0x00000020,
+ MTX = 0x00000010,
+ TXAK = 0x00000008,
+ RSTA = 0x00000004,
+} I2C_CONTROL;
+
+typedef enum i2c_status
+{
+ MCF = 0x00000080,
+ MAAS = 0x00000040,
+ MBB = 0x00000020,
+ MAL = 0x00000010,
+ SRW = 0x00000004,
+ MIF = 0x00000002,
+ RXAK = 0x00000001,
+} I2C_STATUS;
+
+typedef struct _i2c_ctrl
+{
+ unsigned int reserved0 : 24;
+ unsigned int men : 1;
+ unsigned int mien : 1;
+ unsigned int msta : 1;
+ unsigned int mtx : 1;
+ unsigned int txak : 1;
+ unsigned int rsta : 1;
+ unsigned int reserved1 : 2;
+} I2C_CTRL;
+
+typedef struct _i2c_stat
+{
+ unsigned int rsrv0 : 24;
+ unsigned int mcf : 1;
+ unsigned int maas : 1;
+ unsigned int mbb : 1;
+ unsigned int mal : 1;
+ unsigned int rsrv1 : 1;
+ unsigned int srw : 1;
+ unsigned int mif : 1;
+ unsigned int rxak : 1;
+} I2C_STAT;
+
+typedef enum _i2c_mode
+{
+ RCV = 0,
+ XMIT = 1,
+} I2C_MODE;
+
+/******************** App. API ********************
+ * The application API is for user level application
+ * to use the funcitonality provided by I2C driver
+ *
+ * Note: Its App.s responsibility to swap the data
+ * byte. In our API, we just transfer whatever
+ * we are given
+ **************************************************/
+/**
+ * Note:
+ *
+ * In all following functions,
+ * the caller shall pass the configured embedded utility memory
+ * block base, EUMBBAR.
+ **/
+
+/* Send a buffer of data to the intended rcv_addr.
+ * If stop_flag is set, after the whole buffer
+ * is sent, generate a STOP signal provided that the
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the master performing transmitting. If
+ * no STOP signal is generated at the end of current
+ * transaction, the master can generate a START signal
+ * to another slave addr.
+ *
+ * return I2CSUCCESS if no error.
+ */
+static I2CStatus I2C_put( unsigned int eumbbar,
+ unsigned char rcv_addr, /* receiver's address */
+ unsigned char *buffer_ptr, /* pointer of data to be sent */
+ unsigned int length, /* number of byte of in the buffer */
+ unsigned int stop_flag, /* 1 - signal STOP when buffer is empty
+ * 0 - no STOP signal when buffer is empty
+ */
+ unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+
+/* Receive a buffer of data from the desired sender_addr
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the master performing receiving. If no STOP signal
+ * is generated, the master can generate a START signal
+ * to another slave addr.
+ *
+ * return I2CSUCCESS if no error.
+ */
+static I2CStatus I2C_get( unsigned int eumbbar,
+ unsigned char sender_addr, /* sender's address */
+ unsigned char *buffer_ptr, /* pointer of receiving buffer */
+ unsigned int length, /* length of the receiving buffer */
+ unsigned int stop_flag, /* 1 - signal STOP when buffer is full
+ * 0 - no STOP signal when buffer is full
+ */
+ unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+
+#if 0 /* the I2C_write and I2C_read functions are not active */
+/* Send a buffer of data to the requiring master.
+ * If stop_flag is set, after the whole buffer is sent,
+ * generate a STOP signal provided that the requiring
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the slave performing transmitting.
+ *
+ * return I2CSUCCESS if no error.
+ *
+ * Note: due to the Kahlua design, slave transmitter
+ * shall not signal STOP since there is no way
+ * for master to detect it, causing I2C bus hung.
+ *
+ * For the above reason, the stop_flag is always
+ * set, i.e., 1.
+ *
+ * programmer shall use the timer on Kahlua to
+ * control the interval of data byte at the
+ * master side.
+ */
+static I2CStatus I2C_write( unsigned int eumbbar,
+ unsigned char *buffer_ptr, /* pointer of data to be sent */
+ unsigned int length, /* number of byte of in the buffer */
+ unsigned int stop_flag ); /* 1 - signal STOP when buffer is empty
+ * 0 - no STOP signal when buffer is empty
+ */
+
+ /* Receive a buffer of data from the sending master.
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the slave performing receiving.
+ *
+ * return I2CSUCCESS if no error.
+ */
+static I2CStatus I2C_read(unsigned int eumbbar,
+ unsigned char *buffer_ptr, /* pointer of receiving buffer */
+ unsigned int length, /* length of the receiving buffer */
+ unsigned int stop_flag ); /* 1 - signal STOP when buffer is full
+ * 0 - no STOP signal when buffer is full
+ */
+#endif /* of if0 for turning off I2C_read & I2C_write */
+
+/* if interrupt is not used, this is the timer event handler.
+ * After each fixed time interval, this function can be called
+ * to check the I2C status and call appropriate function to
+ * handle the status event.
+ */
+static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) );
+
+/********************* Kernel API ************************
+ * Kernel APIs are functions I2C driver provides to the
+ * O.S.
+ *********************************************************/
+
+/******************* device I/O function ***************/
+
+/* Generate a START signal in the desired mode.
+ * I2C is the master.
+ *
+ * return I2CSUCCESS if no error.
+ * I2CERROR if i2c unit is not enabled.
+ * I2CBUSBUSY if bus cannot be granted
+ */
+static I2CStatus I2C_Start( unsigned int eumbbar,
+ unsigned char slave_addr, /* address of the receiver */
+ I2C_MODE mode, /* XMIT(1) - put (write)
+ * RCV(0) - get (read)
+ */
+ unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+
+/* Generate a STOP signal to terminate the transaction. */
+static I2CStatus I2C_Stop( unsigned int eumbbar );
+
+/* Do a one-byte master transmit.
+ *
+ * return I2CBUFFEMPTY if this is the last byte.
+ * Otherwise return I2CSUCCESS
+ */
+static I2CStatus I2C_Master_Xmit( unsigned int eumbbar );
+
+/* Do a one-byte master receive.
+ *
+ * return I2CBUFFFULL if this is the last byte.
+ * Otherwise return I2CSUCCESS
+ */
+static I2CStatus I2C_Master_Rcv( unsigned int eumbbar );
+
+/* Do a one-byte slave transmit.
+ *
+ * return I2CBUFFEMPTY if this is the last byte.
+ * Otherwise return I2CSUCCESS
+ *
+ */
+static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar );
+
+/* Do a one-byte slave receive.
+ *
+ * return I2CBUFFFULL if this is the last byte.
+ * Otherwise return I2CSUCCESS
+ */
+static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar );
+
+/* Process slave address phase.
+ *
+ * return I2CADDRESS if this is slave receiver's address phase
+ * Otherwise return the result of slave xmit one byte.
+ */
+static I2CStatus I2C_Slave_Addr( unsigned int eumbbar );
+
+/******************* Device Control Fucntion ****************/
+/* Initialize I2C unit with desired frequency divider,
+ * driver's slave address w/o interrupt enabled.
+ *
+ * This function must be called before I2C unit can
+ * be used.
+ */
+static I2CStatus I2C_Init( unsigned int eumbbar,
+ unsigned char fdr, /* frequency divider */
+ unsigned char addr, /* driver's address used for receiving */
+ unsigned int en_int); /* 1 - enable I2C interrupt
+ * 0 - disable I2C interrup
+ */
+
+/* I2C interrupt service routine.
+ *
+ * return I2CADDRESS if it is receiver's (either master or slave) address phase.
+ * return the result of xmit or receive one byte
+ */
+static I2CStatus I2C_ISR(unsigned int eumbbar );
+
+/* Set I2C Status, i.e., write to I2CSR */
+static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat );
+
+/* Query I2C Status, i.e., read I2CSR */
+static I2C_STAT I2C_Get_Stat( unsigned int eumbbar );
+
+/* Change I2C Control bits, i.e., write to I2CCR */
+static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */
+
+/* Query I2C Control bits, i.e., read I2CCR */
+static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar );
+
+/* This function performs the work for I2C_do_transaction. The work is
+ * split into this function to enable I2C_do_transaction to first transmit
+ * the data address to the I2C slave device without putting the data address
+ * into the first byte of the buffer.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ int len,
+ unsigned char *buffer,
+ I2C_STOP_MODE stop,
+ int retry,
+ I2C_RESTART_MODE rsta);
+#endif
--- /dev/null
+/*************************************************************
+ * $Id: i2c1.c,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * Copyright @ Motorola, 1999
+ *
+ ************************************************************/
+#include "i2c_export.h"
+#include "i2c.h"
+
+
+/* Define a macro to use an optional application-layer print function, if
+ * one was passed to the I2C library during initialization. If there was
+ * no function pointer passed, this protects against calling it. Also define
+ * the global variable that holds the passed pointer.
+ */
+#define PRINT if ( app_print ) app_print
+static int (*app_print)(char *,...);
+
+/******************* Internal to I2C Driver *****************/
+static unsigned int ByteToXmit = 0;
+static unsigned int XmitByte = 0;
+static unsigned char *XmitBuf = 0;
+static unsigned int XmitBufEmptyStop =0;
+static unsigned int ByteToRcv = 0;
+static unsigned int RcvByte = 0;
+static unsigned char *RcvBuf = 0;
+static unsigned int RcvBufFulStop = 0;
+static unsigned int MasterRcvAddress = 0;
+
+/* Set by call to get_eumbbar during I2C_Initialize.
+ * This could be globally available to the I2C library, but there is
+ * an advantage to passing it as a parameter: it is already in a register
+ * and doesn't have to be loaded from memory. Also, that is the way the
+ * I2C library was already implemented and I don't want to change it without
+ * a more detailed analysis.
+ * It is being set as a global variable in I2C_Initialize to hide it from
+ * the DINK application layer, because it is Kahlua-specific. I think that
+ * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
+ * a Kahlua-specific library dealing with the embedded utilities memory block.
+ * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
+ * defined in dink32/drivers/i2c/i2c2.s.
+ */
+static unsigned int Global_eumbbar = 0;
+extern unsigned int get_eumbbar();
+
+extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
+#pragma Alias( load_runtime_reg, "load_runtime_reg" )
+
+extern unsigned int store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
+#pragma Alias( store_runtime_reg, "store_runtime_reg" )
+
+/************************** API *****************/
+
+/* Application Program Interface (API) are the calls provided by the I2C
+ * library to upper layer applications (i.e., DINK) to access the Kahlua
+ * I2C bus interface. The functions and values that are part of this API
+ * are declared in i2c_export.h.
+ */
+
+/* Initialize I2C unit with the following:
+ * driver's slave address
+ * interrupt enabled
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * desired clock rate
+ * digital filter frequency sampling rate
+ *
+ * This function must be called before I2C unit can be used.
+ */
+I2C_Status I2C_Initialize(
+ unsigned char addr,
+ I2C_INTERRUPT_MODE en_int,
+ int (*p)(char *,...))
+{
+ I2CStatus status;
+ /* establish the pointer, if there is one, to the application's "printf" */
+ app_print = p;
+
+ /* If this is the first call, get the embedded utilities memory block
+ * base address. I'm not sure what to do about error handling here:
+ * if a non-zero value is returned, accept it.
+ */
+ if ( Global_eumbbar == 0)
+ Global_eumbbar = get_eumbbar();
+ if ( Global_eumbbar == 0)
+ {
+ PRINT( "I2C_Initialize: can't find EUMBBAR\n" );
+ return I2C_ERROR;
+ }
+
+ /* validate the I2C address */
+ if (addr & 0x80)
+ {
+ PRINT( "I2C_Initialize, I2C address invalid: %d 0x%x\n",
+ (unsigned int)addr, (unsigned int)addr );
+ return I2C_ERROR;
+ }
+
+ /* Call the internal I2C library function to perform work.
+ * Accept the default frequency sampling rate (no way to set it currently,
+ * via I2C_Init) and set the clock frequency to something reasonable.
+ */
+ status = I2C_Init( Global_eumbbar, (unsigned char)0x31, addr, en_int);
+ if (status != I2CSUCCESS)
+ {
+ PRINT( "I2C_Initialize: error in initiation\n" );
+ return I2C_ERROR;
+ }
+
+ /* all is well */
+ return I2C_SUCCESS;
+}
+
+
+/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
+ * are implemented. Both are only in polling mode.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * data_addr is the address of the data on the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ unsigned char data_addr,
+ int len,
+ char *buffer,
+ I2C_STOP_MODE stop,
+ int retry,
+ I2C_RESTART_MODE rsta)
+{
+ I2C_Status status;
+ unsigned char data_addr_buffer[1];
+
+#if 1
+/* This is a temporary work-around. The I2C library breaks the protocol
+ * if it attempts to handle a data transmission in more than one
+ * transaction, so the data address and the actual data bytes are put
+ * into a single buffer before sending it to the library internal functions.
+ * The problem is related to being able to restart a transaction without
+ * sending the I2C device address or repeating the data address. It may take
+ * a day or two to sort it all out, so I'll have to get back to it later.
+ * Look at I2C_Start to see about using some status flags (I'm not sure that
+ * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic
+ * in the library is insufficient) to control correct handling of the protocol.
+ */
+unsigned char dummy_buffer[257];
+if (act == I2C_MASTER_XMIT)
+{
+int i;
+for (i=1;i<=len;i++)dummy_buffer[i]=buffer[i-1];
+dummy_buffer[0]=data_addr;
+ status = I2C_do_buffer(en_int, act, i2c_addr, 1 + len,
+ dummy_buffer, stop, retry, rsta);
+ if (status != I2C_SUCCESS)
+ {
+ PRINT( "I2C_do_transaction: can't perform data transfer\n");
+ return I2C_ERROR;
+ }
+return I2C_SUCCESS;
+}
+#endif /* end of temp work-around */
+
+ /* validate requested transaction type */
+ if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV))
+ {
+ PRINT( "I2C_do_transaction, invalid transaction request: %d\n", act);
+ return I2C_ERROR;
+ }
+
+ /* range check the I2C address */
+ if (i2c_addr & 0x80)
+ {
+ PRINT( "I2C_do_transaction, I2C address out of range: %d 0x%x\n",
+ (unsigned int)i2c_addr, (unsigned int)i2c_addr );
+ return I2C_ERROR;
+ } else {
+ data_addr_buffer[0] = data_addr;
+ }
+
+ /* We first have to contact the slave device and transmit the data address.
+ * Be careful about the STOP and restart stuff. We don't want to signal STOP
+ * after sending the data address, but this could be a continuation if the
+ * application didn't release the bus after the previous transaction, by
+ * not sending a STOP after it.
+ */
+ status = I2C_do_buffer(en_int, I2C_MASTER_XMIT, i2c_addr, 1,
+ data_addr_buffer, I2C_NO_STOP, retry, rsta);
+ if (status != I2C_SUCCESS)
+ {
+ PRINT( "I2C_do_transaction: can't send data address for read\n");
+ return I2C_ERROR;
+ }
+
+ /* The data transfer will be a continuation. */
+ rsta = I2C_RESTART;
+
+ /* now handle the user data */
+ status = I2C_do_buffer(en_int, act, i2c_addr, len,
+ buffer, stop, retry, rsta);
+ if (status != I2C_SUCCESS)
+ {
+ PRINT( "I2C_do_transaction: can't perform data transfer\n");
+ return I2C_ERROR;
+ }
+
+ /* all is well */
+ return I2C_SUCCESS;
+}
+
+/* This function performs the work for I2C_do_transaction. The work is
+ * split into this function to enable I2C_do_transaction to first transmit
+ * the data address to the I2C slave device without putting the data address
+ * into the first byte of the buffer.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * i2c_addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ int len,
+ unsigned char *buffer,
+ I2C_STOP_MODE stop,
+ int retry,
+ I2C_RESTART_MODE rsta)
+{
+ I2CStatus rval;
+ unsigned int dev_stat;
+ if (act == I2C_MASTER_RCV)
+ {
+ /* set up for master-receive transaction */
+ rval = I2C_get(Global_eumbbar,i2c_addr,buffer,len,stop,rsta);
+ } else {
+ /* set up for master-transmit transaction */
+ rval = I2C_put(Global_eumbbar,i2c_addr,buffer,len,stop,rsta);
+ }
+
+ /* validate the setup */
+ if ( rval != I2CSUCCESS )
+ {
+ dev_stat = load_runtime_reg( Global_eumbbar, I2CSR );
+ PRINT( "Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat);
+ I2C_Stop( Global_eumbbar );
+ return I2C_ERROR;
+ }
+
+ if (en_int == 1)
+ {
+ /* this should not happen, no interrupt handling yet */
+ return I2C_SUCCESS;
+ }
+
+ /* this performs the polling action, when the transfer is completed,
+ * the status returned from I2C_Timer_Event will be I2CBUFFFULL or
+ * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the
+ * transaction is not yet complete, anything else is an error.
+ */
+ while ( rval == I2CSUCCESS || rval == I2CADDRESS )
+ {
+ /* poll the device until something happens */
+ do
+ {
+ rval = I2C_Timer_Event( Global_eumbbar, 0 );
+ }
+ while ( rval == I2CNOEVENT );
+
+ /* check for error condition */
+ if ( rval == I2CSUCCESS || rval == I2CBUFFFULL ||
+ rval == I2CBUFFEMPTY || rval == I2CADDRESS )
+ { ; /* do nothing */
+ } else {
+ /* report the error condition */
+ dev_stat = load_runtime_reg( Global_eumbbar, I2CSR );
+ PRINT( "Error(I2C_do_buffer): code(0x%08x), status(0x%08x)\n", rval, dev_stat );
+ return I2C_ERROR;
+ }
+ }
+
+ /* all is well */
+ return I2C_SUCCESS;
+}
+
+/**
+ * Note:
+ *
+ * In all following functions,
+ * the caller shall pass the configured embedded utility memory
+ * block base, EUMBBAR.
+ **/
+
+/***********************************************************
+ * function: I2C_put
+ *
+ * description:
+ Send a buffer of data to the intended rcv_addr.
+ * If stop_flag is set, after the whole buffer
+ * is sent, generate a STOP signal provided that the
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the master performing transmitting. If
+ * no STOP signal is generated at the end of current
+ * transaction, the master can generate a START signal
+ * to another slave addr.
+ *
+ * note: this is master xmit API
+ *********************************************************/
+static I2CStatus I2C_put( unsigned int eumbbar,
+ unsigned char rcv_addr, /* receiver's address */
+ unsigned char *buffer_ptr, /* pointer of data to be sent */
+ unsigned int length, /* number of byte of in the buffer */
+ unsigned int stop_flag, /* 1 - signal STOP when buffer is empty
+ * 0 - no STOP signal when buffer is empty
+ */
+ unsigned int is_cnt ) /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+
+{
+ if ( buffer_ptr == 0 || length == 0 )
+ {
+ return I2CERROR;
+ }
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_put\n", __FILE__, __LINE__ );
+#endif
+
+ XmitByte = 0;
+ ByteToXmit = length;
+ XmitBuf = buffer_ptr;
+ XmitBufEmptyStop = stop_flag;
+
+ RcvByte = 0;
+ ByteToRcv = 0;
+ RcvBuf = 0;
+
+ /* we are the master, start transaction */
+ return I2C_Start( eumbbar, rcv_addr, XMIT, is_cnt );
+}
+
+/***********************************************************
+ * function: I2C_get
+ *
+ * description:
+ * Receive a buffer of data from the desired sender_addr
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the master performing receiving. If no STOP signal
+ * is generated, the master can generate a START signal
+ * to another slave addr.
+ *
+ * note: this is master receive API
+ **********************************************************/
+static I2CStatus I2C_get( unsigned int eumbbar,
+ unsigned char rcv_from, /* sender's address */
+ unsigned char *buffer_ptr, /* pointer of receiving buffer */
+ unsigned int length, /* length of the receiving buffer */
+ unsigned int stop_flag, /* 1 - signal STOP when buffer is full
+ * 0 - no STOP signal when buffer is full
+ */
+ unsigned int is_cnt ) /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start, check MBB
+ */
+{
+ if ( buffer_ptr == 0 || length == 0 )
+ {
+ return I2CERROR;
+ }
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_get\n", __FILE__, __LINE__ );
+#endif
+
+ RcvByte = 0;
+ ByteToRcv = length;
+ RcvBuf = buffer_ptr;
+ RcvBufFulStop = stop_flag;
+
+ XmitByte = 0;
+ ByteToXmit = 0;
+ XmitBuf = 0;
+
+ /* we are the master, start the transaction */
+ return I2C_Start( eumbbar, rcv_from, RCV, is_cnt );
+
+}
+
+#if 0 /* turn off dead code */
+/*********************************************************
+ * function: I2C_write
+ *
+ * description:
+ * Send a buffer of data to the requiring master.
+ * If stop_flag is set, after the whole buffer is sent,
+ * generate a STOP signal provided that the requiring
+ * receiver doesn't signal the STOP in the middle.
+ * I2C is the slave performing transmitting.
+ *
+ * Note: this is slave xmit API.
+ *
+ * due to the current Kahlua design, slave transmitter
+ * shall not signal STOP since there is no way
+ * for master to detect it, causing I2C bus hung.
+ *
+ * For the above reason, the stop_flag is always
+ * set, i.e., 0.
+ *
+ * programmer shall use the timer on Kahlua to
+ * control the interval of data byte at the
+ * master side.
+ *******************************************************/
+static I2CStatus I2C_write( unsigned int eumbbar,
+ unsigned char *buffer_ptr, /* pointer of data to be sent */
+ unsigned int length, /* number of byte of in the buffer */
+ unsigned int stop_flag ) /* 1 - signal STOP when buffer is empty
+ * 0 - no STOP signal when buffer is empty
+ */
+{
+ if ( buffer_ptr == 0 || length == 0 )
+ {
+ return I2CERROR;
+ }
+
+ XmitByte = 0;
+ ByteToXmit = length;
+ XmitBuf = buffer_ptr;
+ XmitBufEmptyStop = 0; /* in order to avoid bus hung, ignored the user's stop_flag */
+
+ RcvByte = 0;
+ ByteToRcv = 0;
+ RcvBuf = 0;
+
+ /* we are the slave, just wait for being called, or pull */
+ /* I2C_Timer_Event( eumbbar ); */
+}
+
+/******************************************************
+ * function: I2C_read
+ *
+ * description:
+ * Receive a buffer of data from the sending master.
+ * If stop_flag is set, when the buffer is full and the
+ * sender does not signal STOP, generate a STOP signal.
+ * I2C is the slave performing receiving.
+ *
+ * note: this is slave receive API
+ ****************************************************/
+static I2CStatus I2C_read(unsigned int eumbbar,
+ unsigned char *buffer_ptr, /* pointer of receiving buffer */
+ unsigned int length, /* length of the receiving buffer */
+ unsigned int stop_flag ) /* 1 - signal STOP when buffer is full
+ * 0 - no STOP signal when buffer is full
+ */
+{
+ if ( buffer_ptr == 0 || length == 0 )
+ {
+ return I2CERROR;
+ }
+
+ RcvByte = 0;
+ ByteToRcv = length;
+ RcvBuf = buffer_ptr;
+ RcvBufFulStop = stop_flag;
+
+ XmitByte = 0;
+ ByteToXmit = 0;
+ XmitBuf = 0;
+
+ /* wait for master to call us, or poll */
+ /* I2C_Timer_Event( eumbbar ); */
+}
+#endif /* turn off dead code */
+
+/*********************************************************
+ * function: I2c_Timer_Event
+ *
+ * description:
+ * if interrupt is not used, this is the timer event handler.
+ * After each fixed time interval, this function can be called
+ * to check the I2C status and call appropriate function to
+ * handle the status event.
+ ********************************************************/
+static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) )
+{
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__ );
+#endif
+
+ I2C_STAT stat = I2C_Get_Stat( eumbbar );
+
+ if ( stat.mif == 1 )
+ {
+ if ( handler == 0 )
+ {
+ return I2C_ISR( eumbbar );
+ }
+ else
+ {
+ return (*handler)( eumbbar );
+ }
+ }
+
+ return I2CNOEVENT;
+}
+
+
+/****************** Device I/O function *****************/
+
+/******************************************************
+ * function: I2C_Start
+ *
+ * description: Generate a START signal in the desired mode.
+ * I2C is the master.
+ *
+ * Return I2CSUCCESS if no error.
+ *
+ * note:
+ ****************************************************/
+static I2CStatus I2C_Start( unsigned int eumbbar,
+ unsigned char slave_addr, /* address of the receiver */
+ I2C_MODE mode, /* XMIT(1) - put (write)
+ * RCV(0) - get (read)
+ */
+ unsigned int is_cnt ) /* 1 - this is a restart, don't check MBB
+ * 0 - this is a new start
+ */
+{
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__, __LINE__ ,
+ slave_addr,mode,is_cnt);
+#endif
+ unsigned int tmp = 0;
+ I2C_STAT stat;
+ I2C_CTRL ctrl = I2C_Get_Ctrl( eumbbar );
+
+ /* first make sure I2C has been initialized */
+ if ( ctrl.men == 0 )
+ {
+ return I2CERROR;
+ }
+
+ /* next make sure bus is idle */
+ stat = I2C_Get_Stat( eumbbar );
+
+ if ( is_cnt == 0 && stat.mbb == 1 )
+ {
+ /* sorry, we lost */
+ return I2CBUSBUSY;
+ }
+ else if ( is_cnt == 1 && stat.mif == 1 && stat.mal == 0 )
+ {
+ /* sorry, we lost the bus */
+ return I2CALOSS;
+ }
+
+
+ /* OK, I2C is enabled and we have the bus */
+
+ /* prepare to write the slave address */
+ ctrl.msta = 1;
+ ctrl.mtx = 1;
+ ctrl.txak = 0;
+ ctrl.rsta = is_cnt; /* set the repeat start bit */
+ I2C_Set_Ctrl( eumbbar, ctrl );
+
+ /* write the slave address and xmit/rcv mode bit */
+ tmp = load_runtime_reg( eumbbar, I2CDR );
+ tmp = ( tmp & 0xffffff00 ) | ((slave_addr & 0x007f)<<1) | ( mode == XMIT ? 0x0 : 0x1 );
+ store_runtime_reg( eumbbar, I2CDR, tmp );
+
+ if ( mode == RCV )
+ {
+ MasterRcvAddress = 1;
+ }
+ else
+ {
+ MasterRcvAddress = 0;
+ }
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Start exit\n", __FILE__, __LINE__ );
+#endif
+
+ /* wait for the interrupt or poll */
+ return I2CSUCCESS;
+}
+
+/***********************************************************
+ * function: I2c_Stop
+ *
+ * description: Generate a STOP signal to terminate the master
+ * transaction.
+ * return I2CSUCCESS
+ *
+ **********************************************************/
+static I2CStatus I2C_Stop( unsigned int eumbbar )
+{
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Stop enter\n", __FILE__, __LINE__ );
+#endif
+
+ I2C_CTRL ctrl = I2C_Get_Ctrl(eumbbar );
+ ctrl.msta = 0;
+ I2C_Set_Ctrl( eumbbar, ctrl );
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Stop exit\n", __FILE__, __LINE__ );
+#endif
+
+ return I2CSUCCESS;
+}
+
+/****************************************************
+ * function: I2C_Master_Xmit
+ *
+ * description: Master sends one byte of data to
+ * slave target
+ *
+ * return I2CSUCCESS if the byte transmitted.
+ * Otherwise no-zero
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) == 0
+ * I2CCR(MSTA) == 1 && I2CCR(MTX) == 1
+ *
+ ***************************************************/
+static I2CStatus I2C_Master_Xmit( unsigned int eumbbar )
+{
+ unsigned int val;
+ if ( ByteToXmit > 0 )
+ {
+
+ if ( ByteToXmit == XmitByte )
+ {
+ /* all xmitted */
+ ByteToXmit = 0;
+
+ if ( XmitBufEmptyStop == 1 )
+ {
+ I2C_Stop( eumbbar );
+ }
+
+ return I2CBUFFEMPTY;
+
+ }
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, *(XmitBuf + XmitByte) );
+#endif
+
+ val = *(XmitBuf + XmitByte);
+ val &= 0x000000ff;
+ store_runtime_reg( eumbbar, I2CDR, val );
+ XmitByte++;
+
+ return I2CSUCCESS;
+
+ }
+
+ return I2CBUFFEMPTY;
+}
+
+/***********************************************
+ * function: I2C_Master_Rcv
+ *
+ * description: master reads one byte data
+ * from slave source
+ *
+ * return I2CSUCCESS if no error
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
+ * I2CCR(MSTA) == 1 && I2CCR(MTX) == 0
+ *
+ ***********************************************/
+static I2CStatus I2C_Master_Rcv( unsigned int eumbbar )
+{
+ I2C_CTRL ctrl;
+ unsigned int val;
+ if ( ByteToRcv > 0 )
+ {
+
+ if ( ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1 )
+ {
+ /* master requests more than or equal to 2 bytes
+ * we are reading 2nd to last byte
+ */
+
+ /* we need to set I2CCR(TXAK) to generate a STOP */
+ ctrl = I2C_Get_Ctrl( eumbbar );
+ ctrl.txak = 1;
+ I2C_Set_Ctrl( eumbbar, ctrl );
+
+ /* Kahlua will automatically generate a STOP
+ * next time a transaction happens
+ */
+
+ /* note: the case of master requesting one byte is
+ * handled in I2C_ISR
+ */
+ }
+
+ /* generat a STOP before reading the last byte */
+ if ( RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1 )
+ {
+ I2C_Stop( eumbbar );
+ }
+
+ val = load_runtime_reg( eumbbar, I2CDR );
+ *(RcvBuf + RcvByte) = val & 0xFF;
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, *(RcvBuf + RcvByte) );
+#endif
+
+ RcvByte++;
+
+ if ( ByteToRcv == RcvByte )
+ {
+ ByteToRcv = 0;
+
+ return I2CBUFFFULL;
+ }
+
+ return I2CSUCCESS;
+ }
+
+ return I2CBUFFFULL;
+
+}
+
+/****************************************************
+ * function: I2C_Slave_Xmit
+ *
+ * description: Slave sends one byte of data to
+ * requesting destination
+ *
+ * return SUCCESS if the byte transmitted. Otherwise
+ * No-zero
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) = 0
+ * I2CCR(MSTA) == 0 && I2CCR(MTX) == 1
+ *
+ ***************************************************/
+static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar )
+{
+ unsigned int val;
+ if ( ByteToXmit > 0 )
+ {
+
+ if ( ByteToXmit == XmitByte )
+ {
+ /* no more data to send */
+ ByteToXmit = 0;
+
+ /* do not toggle I2CCR(MTX). Doing so will cause bus-hung
+ * since current Kahlua design does not give master a way
+ * to detect slave stop. It is always a good idea for
+ * master to use timer to prevent the long long delays
+ */
+
+ return I2CBUFFEMPTY;
+ }
+
+#ifdef I2CDBG
+ PRINT( "%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, *(XmitBuf + XmitByte) );
+#endif
+
+ val = *(XmitBuf + XmitByte);
+ val &= 0x000000ff;
+ store_runtime_reg( eumbbar, I2CDR, val );
+ XmitByte++;
+
+
+ return I2CSUCCESS;
+ }
+
+ return I2CBUFFEMPTY;
+}
+
+/***********************************************
+ * function: I2C_Slave_Rcv
+ *
+ * description: slave reads one byte data
+ * from master source
+ *
+ * return I2CSUCCESS if no error otherwise non-zero
+ *
+ * Note: condition must meet when this function is called:
+ * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
+ * I2CCR(MSTA) == 0 && I2CCR(MTX) = 0
+ *
+ ***********************************************/
+static I2CStatus I2C_Slave_Rcv(unsigned int eumbbar )
+{
+ unsigned int val;
+ I2C_CTRL ctrl;
+ if ( ByteToRcv > 0 )
+ {
+ val = load_runtime_reg( eumbbar, I2CDR );
+ *( RcvBuf + RcvByte ) = val & 0xff;
+#ifdef I2CDBG
+ PRINT( "%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, *(RcvBuf + RcvByte) );
+#endif
+ RcvByte++;
+
+ if ( ByteToRcv == RcvByte )
+ {
+ if ( RcvBufFulStop == 1 )
+ {
+ /* all done */
+ ctrl = I2C_Get_Ctrl( eumbbar );
+ ctrl.txak = 1;
+ I2C_Set_Ctrl( eumbbar, ctrl );
+ }
+
+ ByteToRcv = 0;
+ return I2CBUFFFULL;
+ }
+
+ return I2CSUCCESS;
+ }
+
+ return I2CBUFFFULL;
+}
+
+/****************** Device Control Function *************/
+
+/*********************************************************
+ * function: I2C_Init
+ *
+ * description: Initialize I2C unit with desired frequency divider,
+ * master's listening address, with interrupt enabled
+ * or disabled.
+ *
+ * note:
+ ********************************************************/
+static I2CStatus I2C_Init( unsigned int eumbbar,
+ unsigned char fdr, /* frequency divider */
+ unsigned char slave_addr, /* driver's address used for receiving */
+ unsigned int en_int) /* 1 - enable I2C interrupt
+ * 0 - disable I2C interrup
+ */
+{
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Init enter\n", __FILE__, __LINE__ );
+#endif
+
+ I2C_CTRL ctrl = I2C_Get_Ctrl( eumbbar );
+ unsigned int tmp;
+ /* disable the I2C module before we change everything */
+ ctrl.men = 0;
+ I2C_Set_Ctrl( eumbbar, ctrl );
+
+ /* set the frequency diver */
+ tmp = load_runtime_reg( eumbbar, I2CFDR );
+ tmp = ( tmp & 0xffffffc0 ) | ( fdr & 0x3f );
+ store_runtime_reg( eumbbar, I2CFDR, tmp );
+
+ /* Set our listening (slave) address */
+ tmp = load_runtime_reg( eumbbar, I2CADR );
+ tmp = ( tmp & 0xffffff01 ) | ( ( slave_addr & 0x7f) << 1 );
+ store_runtime_reg( eumbbar, I2CADR, tmp );
+
+ /* enable I2C with desired interrupt setting */
+ ctrl.men = 1;
+ ctrl.mien = en_int & 0x1;
+ I2C_Set_Ctrl( eumbbar, ctrl );
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_Init exit\n", __FILE__, __LINE__ );
+#endif
+
+ return I2CSUCCESS;
+
+}
+
+/*****************************************
+ * function I2c_Get_Stat
+ *
+ * description: Query I2C Status, i.e., read I2CSR
+ *
+ ****************************************/
+static I2C_STAT I2C_Get_Stat( unsigned int eumbbar )
+{
+ unsigned int temp = load_runtime_reg( eumbbar, I2CSR );
+#ifdef I2CDBG0
+ PRINT( "%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp );
+#endif
+
+ I2C_STAT stat;
+ stat.rsrv0 = ( temp & 0xffffff00 ) >> 8;
+ stat.mcf = ( temp & 0x00000080 ) >> 7;
+ stat.maas = ( temp & 0x00000040 ) >> 6;
+ stat.mbb = ( temp & 0x00000020 ) >> 5;
+ stat.mal = ( temp & 0x00000010 ) >> 4;
+ stat.rsrv1 = ( temp & 0x00000008 ) >> 3;
+ stat.srw = ( temp & 0x00000004 ) >> 2;
+ stat.mif = ( temp & 0x00000002 ) >> 1;
+ stat.rxak = ( temp & 0x00000001 );
+ return stat;
+}
+
+/*********************************************
+ * function: I2c_Set_Ctrl
+ *
+ * description: Change I2C Control bits,
+ * i.e., write to I2CCR
+ *
+ ********************************************/
+static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ctrl ) /* new control value */
+{
+ unsigned int temp = load_runtime_reg( eumbbar, I2CCR );
+ temp &= 0xffffff03;
+ temp |= ( ( ctrl.men & 0x1 ) << 7 );
+ temp |= ( ( ctrl.mien & 0x1 ) << 6 );
+ temp |= ( ( ctrl.msta & 0x1 ) << 5 );
+ temp |= ( ( ctrl.mtx & 0x1 ) << 4 );
+ temp |= ( ( ctrl.txak & 0x1 ) << 3 );
+ temp |= ( ( ctrl.rsta & 0x1 ) << 2 );
+#ifdef I2CDBG0
+ PRINT( "%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp );
+#endif
+ store_runtime_reg( eumbbar, I2CCR, temp );
+
+}
+
+/*****************************************
+ * function: I2C_Get_Ctrl
+ *
+ * description: Query I2C Control bits,
+ * i.e., read I2CCR
+ *****************************************/
+static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar )
+{
+ union {
+ I2C_CTRL ctrl ;
+ unsigned int temp;
+ } s;
+ s.temp = load_runtime_reg( eumbbar, I2CCR );
+#ifdef I2CDBG0
+ PRINT( "%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp );
+#endif
+
+ return s.ctrl;
+}
+
+
+/****************************************
+ * function: I2C_Slave_Addr
+ *
+ * description: Process slave address phase.
+ * return I2CSUCCESS if no error
+ *
+ * note: Precondition for calling this function:
+ * I2CSR(MIF) == 1 &&
+ * I2CSR(MAAS) == 1
+ ****************************************/
+static I2CStatus I2C_Slave_Addr( unsigned int eumbbar )
+{
+ I2C_STAT stat = I2C_Get_Stat( eumbbar );
+ I2C_CTRL ctrl = I2C_Get_Ctrl( eumbbar );
+
+ if ( stat.srw == 1 )
+ {
+ /* we are asked to xmit */
+ ctrl.mtx = 1;
+ I2C_Set_Ctrl( eumbbar, ctrl ); /* set MTX */
+ return I2C_Slave_Xmit( eumbbar );
+ }
+
+ /* we are asked to receive data */
+ ctrl.mtx = 0;
+ I2C_Set_Ctrl(eumbbar, ctrl );
+ (void)load_runtime_reg( eumbbar, I2CDR ); /* do a fake read to start */
+
+ return I2CADDRESS;
+}
+
+/***********************************************
+ * function: I2C_ISR
+ *
+ * description: I2C Interrupt service routine
+ *
+ * note: Precondition:
+ * I2CSR(MIF) == 1
+ **********************************************/
+static I2CStatus I2C_ISR( unsigned int eumbbar )
+{
+#ifdef I2CDBG0
+ PRINT( "%s(%d): I2C_ISR\n", __FILE__, __LINE__ );
+#endif
+
+ I2C_STAT stat = I2C_Get_Stat( eumbbar );
+ I2C_CTRL ctrl = I2C_Get_Ctrl( eumbbar );
+
+ /* clear MIF */
+ stat.mif = 0;
+
+ /* Now let see what kind of event this is */
+ if ( stat.mcf == 1 )
+ {
+ /* transfer compete */
+
+ /* clear the MIF bit */
+ I2C_Set_Stat( eumbbar, stat );
+
+ if ( ctrl.msta == 1 )
+ {
+ /* master */
+ if ( ctrl.mtx == 1 )
+ {
+ /* check if this is the address phase for master receive */
+ if ( MasterRcvAddress == 1 )
+ {
+ /* Yes, it is the address phase of master receive */
+ ctrl.mtx = 0;
+ /* now check how much we want to receive */
+ if ( ByteToRcv == 1 && RcvBufFulStop == 1 )
+ {
+ ctrl.txak = 1;
+ }
+
+ I2C_Set_Ctrl( eumbbar, ctrl );
+ (void)load_runtime_reg( eumbbar, I2CDR ); /* fake read first */
+
+ MasterRcvAddress = 0;
+ return I2CADDRESS;
+
+ }
+
+ /* master xmit */
+ if ( stat.rxak == 0 )
+ {
+ /* slave has acknowledged */
+ return I2C_Master_Xmit( eumbbar );
+ }
+
+ /* slave has not acknowledged yet, generate a STOP */
+ if ( XmitBufEmptyStop == 1 )
+ {
+ ctrl.msta = 0;
+ I2C_Set_Ctrl( eumbbar, ctrl );
+ }
+
+ return I2CSUCCESS;
+ }
+
+ /* master receive */
+ return I2C_Master_Rcv( eumbbar );
+ }
+
+ /* slave */
+ if ( ctrl.mtx == 1 )
+ {
+ /* slave xmit */
+ if ( stat.rxak == 0 )
+ {
+ /* master has acknowledged */
+ return I2C_Slave_Xmit( eumbbar );
+ }
+
+ /* master has not acknowledged, wait for STOP */
+ /* do nothing for preventing bus from hung */
+ return I2CSUCCESS;
+ }
+
+ /* slave rcv */
+ return I2C_Slave_Rcv( eumbbar );
+
+ }
+ else if ( stat.maas == 1 )
+ {
+ /* received a call from master */
+
+ /* clear the MIF bit */
+ I2C_Set_Stat(eumbbar, stat );
+
+ /* master is calling us, process the address phase */
+ return I2C_Slave_Addr( eumbbar );
+ }
+ else
+ {
+ /* has to be arbitration lost */
+ stat.mal = 0;
+ I2C_Set_Stat( eumbbar, stat );
+
+ ctrl.msta = 0; /* return to receive mode */
+ I2C_Set_Ctrl( eumbbar, ctrl );
+ }
+
+ return I2CSUCCESS;
+
+}
+
+/******************************************************
+ * function: I2C_Set_Stat
+ *
+ * description: modify the I2CSR
+ *
+ *****************************************************/
+static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat )
+{
+ union {
+ unsigned int val;
+ I2C_STAT stat;
+ } s_tmp;
+ union {
+ unsigned int val;
+ I2C_STAT stat;
+ } s;
+ s.val = load_runtime_reg( eumbbar, I2CSR );
+ s.val &= 0xffffff08;
+ s_tmp.stat = stat;
+ s.val |= (s_tmp.val & 0xf7);
+
+#ifdef I2CDBG0
+ PRINT( "%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val );
+#endif
+
+ store_runtime_reg( eumbbar, I2CSR, s.val );
+
+}
--- /dev/null
+/**************************************
+ * $Id: i2c2.S,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *
+ **************************************/
+
+/**********************************************************
+ * function: load_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ *
+ * output: r3 - register content
+ **********************************************************/
+ .text
+ .align 2
+ .global load_runtime_reg
+load_runtime_reg:
+
+/* xor r5,r5,r5
+* or r5,r5,r3
+*
+* lwbrx r3,r4,r5
+*/
+ lwbrx r3,r4,r3
+ sync
+
+ bclr 20, 0
+
+/****************************************************************
+ * function: store_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ * r5 - new value to be stored
+ *
+ ****************************************************************/
+ .text
+ .align 2
+ .global store_runtime_reg
+store_runtime_reg:
+
+ stwbrx r5, r4, r3
+ sync
+
+ bclr 20,0
+
+
+
--- /dev/null
+#ifndef I2C_EXPORT_H
+#define I2C_EXPORT_H
+
+/****************************************************
+ * $Id: i2c_export.h,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * Copyright Motrola 1999
+ *
+ * $Log: i2c_export.h,v $
+ * Revision 1.1 2000/11/20 17:22:33 wdenk
+ *
+ * * Added support for MBX860T (thanks to Rob Taylor)
+ *
+ * * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+ * Work In Progress (TM); current status: boots to command line input.
+ * EPIC code non-functional (interrupts disabled), No net, No IDE.
+ *
+ * * Add support for Status LED
+ *
+ * * Optionally panic() to reboot instead of hanging
+ *
+ * * Misc bug fixes
+ *
+ * * All frequencies in HZ now (internally)
+ *
+ * * Add support for BOOTP Domain Name Server Option
+ *
+ * Revision 1.1.1.1 2000/11/14 16:54:07 robt
+ * no message
+ *
+ * Revision 1.1.1.1 2000/11/14 14:49:39 robt
+ * no message
+ *
+ * Revision 1.3 1999/05/03 14:57:54 charliem
+ * Decouple the I2C library from DINK application source by making the PRINT
+ * function an optional parameter that is passed to I2C_Inititalize. If the
+ * function pointer is passed, it is used by the library; otherwise, no print
+ * output is performed.
+ *
+ * Revision 1.2 1999/04/30 16:25:53 charliem
+ * Change the DINK to I2C_do_transaction interface to allow the application
+ * to specify the data address as a parameter to I2C_do_transaction, rather
+ * than putting the data address into the first byte of the buffer.
+ * There is a work-around in I2C_do_transaction in this version, see comments
+ * in the i2c1.c code.
+ *
+ * Revision 1.1 1999/04/29 13:41:07 charliem
+ * Capture first pass at modifications to the I2C interface. This version is
+ * correct, but there are some additional modifications to be implemented.
+ * Nothing but I2C should be affected.
+ *
+ *
+ ****************************************************/
+
+/* These are the defined return values for the I2C_do_transaction function.
+ * Any non-zero value indicates failure. Failure modes can be added for
+ * more detailed error reporting.
+ */
+typedef enum _i2c_status
+{
+ I2C_SUCCESS = 0,
+ I2C_ERROR,
+} I2C_Status;
+
+/* These are the defined tasks for I2C_do_transaction.
+ * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
+ */
+typedef enum _i2c_transaction_mode
+{
+ I2C_MASTER_RCV = 0,
+ I2C_MASTER_XMIT = 1,
+} I2C_TRANSACTION_MODE;
+
+typedef enum _i2c_interrupt_mode
+{
+ I2C_INT_DISABLE = 0,
+ I2C_INT_ENABLE = 1,
+} I2C_INTERRUPT_MODE;
+
+typedef enum _i2c_stop
+{
+ I2C_NO_STOP = 0,
+ I2C_STOP = 1,
+} I2C_STOP_MODE;
+
+typedef enum _i2c_restart
+{
+ I2C_NO_RESTART = 0,
+ I2C_RESTART = 1,
+} I2C_RESTART_MODE;
+
+/******************** App. API ********************
+ * The application API is for user level application
+ * to use the functionality provided by I2C driver.
+ * This is a "generic" I2C interface, it should contain
+ * nothing specific to the Kahlua implementation.
+ * Only the generic functions are exported by the library.
+ *
+ * Note: Its App.s responsibility to swap the data
+ * byte. In our API, we just transfer whatever
+ * we are given
+ **************************************************/
+
+
+/* Initialize I2C unit with the following:
+ * driver's slave address
+ * interrupt enabled
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * desired clock rate
+ * digital filter frequency sampling rate
+ *
+ * This function must be called before I2C unit can be used.
+ */
+extern I2C_Status I2C_Initialize(
+ unsigned char addr, /* driver's I2C slave address */
+ I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
+ * 0 - disable I2C interrupt
+ */
+ int (*app_print_function)(char *,...)); /* pointer to optional "printf"
+ * provided by application
+ */
+
+/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
+ * are implemented. Both are only in polling mode.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ unsigned char data_addr,
+ int len,
+ char *buffer,
+ I2C_STOP_MODE stop,
+ int retry,
+ I2C_RESTART_MODE rsta);
+#endif
--- /dev/null
+#ifndef I2C_EXPORT_H
+#define I2C_EXPORT_H
+
+/****************************************************
+ * $Id: i2c_export.h,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+ *
+ * Copyright Motrola 1999
+ *
+ * $Log: i2c_export.h,v $
+ * Revision 1.1 2000/11/20 17:22:32 wdenk
+ *
+ * * Added support for MBX860T (thanks to Rob Taylor)
+ *
+ * * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+ * Work In Progress (TM); current status: boots to command line input.
+ * EPIC code non-functional (interrupts disabled), No net, No IDE.
+ *
+ * * Add support for Status LED
+ *
+ * * Optionally panic() to reboot instead of hanging
+ *
+ * * Misc bug fixes
+ *
+ * * All frequencies in HZ now (internally)
+ *
+ * * Add support for BOOTP Domain Name Server Option
+ *
+ * Revision 1.1.1.1 2000/11/14 16:54:07 robt
+ * no message
+ *
+ * Revision 1.1.1.1 2000/11/14 14:49:39 robt
+ * no message
+ *
+ * Revision 1.3 1999/05/03 14:57:54 charliem
+ * Decouple the I2C library from DINK application source by making the PRINT
+ * function an optional parameter that is passed to I2C_Inititalize. If the
+ * function pointer is passed, it is used by the library; otherwise, no print
+ * output is performed.
+ *
+ * Revision 1.2 1999/04/30 16:25:53 charliem
+ * Change the DINK to I2C_do_transaction interface to allow the application
+ * to specify the data address as a parameter to I2C_do_transaction, rather
+ * than putting the data address into the first byte of the buffer.
+ * There is a work-around in I2C_do_transaction in this version, see comments
+ * in the i2c1.c code.
+ *
+ * Revision 1.1 1999/04/29 13:41:07 charliem
+ * Capture first pass at modifications to the I2C interface. This version is
+ * correct, but there are some additional modifications to be implemented.
+ * Nothing but I2C should be affected.
+ *
+ *
+ ****************************************************/
+
+/* These are the defined return values for the I2C_do_transaction function.
+ * Any non-zero value indicates failure. Failure modes can be added for
+ * more detailed error reporting.
+ */
+typedef enum _i2c_status
+{
+ I2C_SUCCESS = 0,
+ I2C_ERROR,
+} I2C_Status;
+
+/* These are the defined tasks for I2C_do_transaction.
+ * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
+ */
+typedef enum _i2c_transaction_mode
+{
+ I2C_MASTER_RCV = 0,
+ I2C_MASTER_XMIT = 1,
+} I2C_TRANSACTION_MODE;
+
+typedef enum _i2c_interrupt_mode
+{
+ I2C_INT_DISABLE = 0,
+ I2C_INT_ENABLE = 1,
+} I2C_INTERRUPT_MODE;
+
+typedef enum _i2c_stop
+{
+ I2C_NO_STOP = 0,
+ I2C_STOP = 1,
+} I2C_STOP_MODE;
+
+typedef enum _i2c_restart
+{
+ I2C_NO_RESTART = 0,
+ I2C_RESTART = 1,
+} I2C_RESTART_MODE;
+
+/******************** App. API ********************
+ * The application API is for user level application
+ * to use the functionality provided by I2C driver.
+ * This is a "generic" I2C interface, it should contain
+ * nothing specific to the Kahlua implementation.
+ * Only the generic functions are exported by the library.
+ *
+ * Note: Its App.s responsibility to swap the data
+ * byte. In our API, we just transfer whatever
+ * we are given
+ **************************************************/
+
+
+/* Initialize I2C unit with the following:
+ * driver's slave address
+ * interrupt enabled
+ * optional pointer to application layer print function
+ *
+ * These parameters may be added:
+ * desired clock rate
+ * digital filter frequency sampling rate
+ *
+ * This function must be called before I2C unit can be used.
+ */
+extern I2C_Status I2C_Initialize(
+ unsigned char addr, /* driver's I2C slave address */
+ I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
+ * 0 - disable I2C interrupt
+ */
+ int (*app_print_function)(char *,...)); /* pointer to optional "printf"
+ * provided by application
+ */
+
+/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
+ * are implemented. Both are only in polling mode.
+ *
+ * en_int controls interrupt/polling mode
+ * act is the type of transaction
+ * addr is the I2C address of the slave device
+ * len is the length of data to send or receive
+ * buffer is the address of the data buffer
+ * stop = I2C_NO_STOP, don't signal STOP at end of transaction
+ * I2C_STOP, signal STOP at end of transaction
+ * retry is the timeout retry value, currently ignored
+ * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
+ * I2C_RESTART, this is a continuation of existing transaction
+ */
+extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
+ I2C_TRANSACTION_MODE act,
+ unsigned char i2c_addr,
+ unsigned char data_addr,
+ int len,
+ char *buffer,
+ I2C_STOP_MODE stop,
+ int retry,
+ I2C_RESTART_MODE rsta);
+#endif
--- /dev/null
+#ifndef I2O_H
+#define I2O_H
+/*********************************************************
+ * $Id: i2o.h,v 1.1 2000/11/20 17:22:32 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *********************************************************/
+
+#define I2O_REG_OFFSET 0x0004
+
+#define PCI_CFG_CLA 0x0B
+#define PCI_CFG_SCL 0x0A
+#define PCI_CFG_PIC 0x09
+
+#define I2O_IMR0 0x0050
+#define I2O_IMR1 0x0054
+#define I2O_OMR0 0x0058
+#define I2O_OMR1 0x005C
+
+#define I2O_ODBR 0x0060
+#define I2O_IDBR 0x0068
+
+#define I2O_OMISR 0x0030
+#define I2O_OMIMR 0x0034
+#define I2O_IMISR 0x0100
+#define I2O_IMIMR 0x0104
+
+/* accessable to PCI master but local processor */
+#define I2O_IFQPR 0x0040
+#define I2O_OFQPR 0x0044
+
+/* accessable to local processor */
+#define I2O_IFHPR 0x0120
+#define I2O_IFTPR 0x0128
+#define I2O_IPHPR 0x0130
+#define I2O_IPTPR 0x0138
+#define I2O_OFHPR 0x0140
+#define I2O_OFTPR 0x0148
+#define I2O_OPHPR 0x0150
+#define I2O_OPTPR 0x0158
+#define I2O_MUCR 0x0164
+#define I2O_QBAR 0x0170
+
+#define I2O_NUM_MSG 2
+
+typedef enum _i2o_status
+{
+ I2OSUCCESS = 0,
+ I2OINVALID,
+ I2OMSGINVALID,
+ I2ODBINVALID,
+ I2OQUEINVALID,
+ I2OQUEEMPTY,
+ I2OQUEFULL,
+ I2ONOEVENT,
+} I2OSTATUS;
+
+typedef enum _queue_size
+{
+ QSIZE_4K = 0x02,
+ QSIZE_8K = 0x04,
+ QSIZE_16K = 0x08,
+ QSIZE_32K = 0x10,
+ QSIZe_64K = 0x20,
+} QUEUE_SIZE;
+
+typedef enum _location
+{
+ LOCAL = 0, /* used by local processor to access its own on board device,
+ local processor's eumbbar is required */
+ REMOTE, /* used by PCI master to access the devices on its PCI device,
+ device's pcsrbar is required */
+} LOCATION;
+
+/* door bell */
+typedef enum _i2o_in_db
+{
+ IN_DB = 1,
+ MC, /* machine check */
+} I2O_IN_DB;
+
+/* I2O PCI configuration identification */
+typedef struct _i2o_iop
+{
+ unsigned int base_class : 8;
+ unsigned int sub_class : 8;
+ unsigned int prg_code : 8;
+} I2OIOP;
+
+/* I2O Outbound Message Interrupt Status Register */
+typedef struct _i2o_om_stat
+{
+ unsigned int rsvd0 : 26;
+ unsigned int opqi : 1;
+ unsigned int rsvd1 : 1;
+ unsigned int odi : 1;
+ unsigned int rsvd2 : 1;
+ unsigned int om1i : 1;
+ unsigned int om0i : 1;
+} I2OOMSTAT;
+
+/* I2O inbound Message Interrupt Status Register */
+typedef struct _i2o_im_stat
+{
+ unsigned int rsvd0 : 23;
+ unsigned int ofoi : 1;
+ unsigned int ipoi : 1;
+ unsigned int rsvd1 : 1;
+ unsigned int ipqi : 1;
+ unsigned int mci : 1;
+ unsigned int idi : 1;
+ unsigned int rsvd2 : 1;
+ unsigned int im1i : 1;
+ unsigned int im0i : 1;
+} I2OIMSTAT;
+
+/**
+ Enable the interrupt associated with in/out bound msg
+
+ Inbound message interrupt generated by PCI master and serviced by local processor
+ local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
+
+ Outbound message interrupt generated by local processor and serviced by PCI master
+ PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
+ **/
+extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ); /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+
+/**
+ Disable the interrupt associated with in/out bound msg
+
+ local processor needs to disable its inbound interrupts it is not interested (LOCAL)
+
+ PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
+ **/
+extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ); /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+
+/**
+ Read the msg register either from local inbound msg 0/1,
+ or an outbound msg 0/1 of devices.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, outbound msg of the device is read.
+ Otherwise local inbound msg is read.
+ **/
+extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int *msg );
+
+/**
+ Write to nth Msg register either on local outbound msg 0/1,
+ or aninbound msg 0/1 of devices
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, inbound msg on the device is written.
+ Otherwise local outbound msg is written.
+ **/
+extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int msg );
+
+/**
+ Enable the In/Out DoorBell Interrupt
+
+ InDoorBell interrupt is generated by PCI master and serviced by local processor
+ local processor needs to enable its inbound doorbell interrupts it wants to handle
+
+ OutDoorbell interrupt is generated by local processor and serviced by PCI master
+ PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
+ **/
+extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+
+/**
+ Disable the In/Out DoorBell Interrupt
+
+ local processor needs to disable its inbound doorbell interrupts it is not interested
+
+ PCI master needs to disable outbound doorbell interrupts of devices it is not interested
+
+ **/
+extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+
+/**
+ Read a local indoorbell register, or an outdoorbell of devices.
+ Reading a doorbell register, the register will be cleared.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, outdoorbell register on the device is read.
+ Otherwise local in doorbell is read
+ **/
+extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base); /* pcsrbar/eumbbar */
+
+/**
+ Write to a local outdoorbell register, or an indoorbell register of devices.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, in doorbell register on the device is written.
+ Otherwise local out doorbell is written
+ **/
+extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int msg ); /* in / out */
+
+/**
+ Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
+ the register will be cleared.
+
+ The outbound interrupt status is AND with the outbound
+ interrupt mask. The result is returned.
+
+ PCI master must pass the pcsrbar to the function.
+ **/
+extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
+
+/**
+ Read the inbound msg unit interrupt status. Reading an interrupt status register,
+ the register will be cleared.
+
+ The inbound interrupt status is AND with the inbound
+ interrupt mask. The result is returned.
+
+ Local process must pass its eumbbar to the function.
+**/
+extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
+
+/**
+ Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
+ MUCR.
+ **/
+extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
+ QUEUE_SIZE,
+ unsigned int qba);/* queue base address that must be aligned at 1M */
+/**
+ Enable the circular queue
+ **/
+extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
+
+/**
+ Disable the circular queue
+ **/
+extern void I2OFIFODisable( unsigned int eumbbar );
+
+/**
+ Enable the circular queue interrupt
+ PCI master enables outbound FIFO interrupt of device
+ Device enables its inbound FIFO interrupt
+ **/
+extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
+
+/**
+ Disable the circular queue interrupt
+ PCI master disables outbound FIFO interrupt of device
+ Device disables its inbound FIFO interrupt
+ **/
+extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
+
+/**
+ Enable the circular queue overflow interrupt
+ **/
+extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
+
+/**
+ Disable the circular queue overflow interrupt
+ **/
+extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
+
+/**
+ Allocate a free msg frame from free FIFO.
+
+ PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
+ while local processor allocates a free msg frame from outbound free queue(OFTPR)
+
+ Unless both free queues are initialized, allocating a free MF will return 0xffffffff
+ **/
+extern I2OSTATUS I2OFIFOAlloc( LOCATION,
+ unsigned int base,
+ void **pMsg);
+/**
+ Free a used msg frame back to free queue
+ PCI Master frees a MFA through outbound queue port of device(OFQPR)
+ while local processor frees a MFA into its inbound free queue(IFHPR)
+
+ Used msg frame does not need to be recycled in the order they
+ read
+
+ This function has to be called by PCI master to initialize Inbound free queue
+ and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
+ **/
+extern I2OSTATUS I2OFIFOFree( LOCATION,
+ unsigned int base,
+ void *pMsg );
+
+/**
+ Post a msg into FIFO
+ PCI Master posts a msg through inbound queue port of device(IFQPR)
+ while local processor post a msg into its outbound post queue(OPHPR)
+
+ The total number of msg must be less than the max size of the queue
+ Otherwise queue overflow interrupt will assert.
+ **/
+extern I2OSTATUS I2OFIFOPost( LOCATION,
+ unsigned int base,
+ void *pMsg );
+
+/**
+ Read a msg from FIFO
+ PCI Master reads a msg through outbound queue port of device(OFQPR)
+ while local processor reads a msg from its inbound post queue(IPTPR)
+ **/
+extern I2OSTATUS I2OFIFOGet( LOCATION,
+ unsigned int base,
+ void **pMsg );
+
+/**
+ Get the I2O PCI configuration identification register
+ **/
+extern I2OSTATUS I2OPCIConfigGet( LOCATION,
+ unsigned int base,
+ I2OIOP *);
+
+#endif
--- /dev/null
+##########################################################################
+#
+# $Id: Makefile,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+#
+# Copyright Motorola, Inc. 1997
+# ALL RIGHTS RESERVED
+#
+# You are hereby granted a copyright license to use, modify, and
+# distribute the SOFTWARE so long as this entire notice is retained
+# without alteration in any modified and/or redistributed versions,
+# and that such modified versions are clearly identified as such.
+# No licenses are granted by implication, estoppel or otherwise under
+# any patents or trademarks of Motorola, Inc.
+#
+# The SOFTWARE is provided on an "AS IS" basis and without warranty.
+# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+#
+# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+# INABILITY TO USE THE SOFTWARE.
+#
+# $Log: Makefile,v $
+# Revision 1.1 2000/11/20 17:22:33 wdenk
+#
+# * Added support for MBX860T (thanks to Rob Taylor)
+#
+# * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+# Work In Progress (TM); current status: boots to command line input.
+# EPIC code non-functional (interrupts disabled), No net, No IDE.
+#
+# * Add support for Status LED
+#
+# * Optionally panic() to reboot instead of hanging
+#
+# * Misc bug fixes
+#
+# * All frequencies in HZ now (internally)
+#
+# * Add support for BOOTP Domain Name Server Option
+#
+# Revision 1.1.1.1 2000/11/14 16:54:07 robt
+# no message
+#
+# Revision 1.1.1.1 2000/11/14 14:49:39 robt
+# no message
+#
+# Revision 1.2 1999/02/05 01:55:54 wyin
+# modified to set up soft link for hearder files
+# compilable version with dink
+#
+# Revision 1.1 1999/02/03 18:57:23 wyin
+# Base line
+#
+# Revision 1.12 1998/11/20 01:34:55 wyin
+# Added INTMEM function and data structure.
+# Enabled DCACHE.
+# There is a minor problem with DCACHE, the cache policy had to be write-through.
+# Otherwise, when power-on-reset, BlackBox cannot measure the scan chain length.
+# But consequence measurement is fine.
+#
+#
+############################################################################
+TARGET = libi2o.a
+
+#DEBUG = -g
+DEBUG =
+LST = -Hanno -S
+OPTIM =
+CC = /risc/tools/pkgs/metaware/bin/hcppc
+CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
+CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
+PREP = $(CC) $(CFLAGS) -P
+
+# Assembler used to build the .s files (for the board version)
+
+ASOPT = -big_si -c
+ASDEBUG = -l -fm
+AS = /risc/tools/pkgs/metaware/bin/asppc
+
+# Linker to bring .o files together into an executable.
+
+LKOPT = -Bbase=0 -Qn -q -r
+LKCMD =
+LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
+
+# DOS Utilities
+
+DEL = rm
+COPY = cp
+LIST = ls
+
+OBJECTS = i2o1.o i2o2.o
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ $(LINK) $(OBJECTS) -o $@
+
+objects: i2o1.o
+
+clean:
+ $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
+
+.s.o:
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
+# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
+
+.c.o:
+ $(CCobj) $<
+
+.c.s:
+ $(CCobj) $(LST) $<
+
+i2o1.o: i2o.h i2o1.c
+
+i2o2.o: i2o.h i2o2.s
--- /dev/null
+##########################################################################
+#
+# makefile_pc for use with PC mksnt tools dink32/drivers/i2o
+# $Id: Makefile_pc,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+#
+# Copyright Motorola, Inc. 1997
+# ALL RIGHTS RESERVED
+#
+# You are hereby granted a copyright license to use, modify, and
+# distribute the SOFTWARE so long as this entire notice is retained
+# without alteration in any modified and/or redistributed versions,
+# and that such modified versions are clearly identified as such.
+# No licenses are granted by implication, estoppel or otherwise under
+# any patents or trademarks of Motorola, Inc.
+#
+# The SOFTWARE is provided on an "AS IS" basis and without warranty.
+# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
+# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
+# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
+# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
+# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
+#
+# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
+# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
+# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
+# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
+# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
+# INABILITY TO USE THE SOFTWARE.
+#
+# $Log: Makefile_pc,v $
+# Revision 1.1 2000/11/20 17:22:33 wdenk
+#
+# * Added support for MBX860T (thanks to Rob Taylor)
+#
+# * Added support for Sandpoint8240 (thanks to Rob Taylor); this is
+# Work In Progress (TM); current status: boots to command line input.
+# EPIC code non-functional (interrupts disabled), No net, No IDE.
+#
+# * Add support for Status LED
+#
+# * Optionally panic() to reboot instead of hanging
+#
+# * Misc bug fixes
+#
+# * All frequencies in HZ now (internally)
+#
+# * Add support for BOOTP Domain Name Server Option
+#
+# Revision 1.1.1.1 2000/11/14 16:54:07 robt
+# no message
+#
+# Revision 1.1.1.1 2000/11/14 14:49:39 robt
+# no message
+#
+# Revision 1.1 1999/06/11 20:05:26 maurie
+# support for compiling dink on PC
+#
+# Revision 1.2 1999/02/05 01:55:54 wyin
+# modified to set up soft link for hearder files
+# compilable version with dink
+#
+# Revision 1.1 1999/02/03 18:57:23 wyin
+# Base line
+#
+# Revision 1.12 1998/11/20 01:34:55 wyin
+# Added INTMEM function and data structure.
+# Enabled DCACHE.
+# There is a minor problem with DCACHE, the cache policy had to be write-through.
+# Otherwise, when power-on-reset, BlackBox cannot measure the scan chain length.
+# But consequence measurement is fine.
+#
+#
+############################################################################
+TARGET = libi2o.a
+
+#DEBUG = -g
+DEBUG =
+LST = -Hanno -S
+OPTIM =
+CC = m:/old_tools/tools/hcppc/bin/hcppc
+CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
+CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
+PREP = $(CC) $(CFLAGS) -P
+
+# Assembler used to build the .s files (for the board version)
+
+ASOPT = -big_si -c
+ASDEBUG = -l -fm
+AS = m:/old_tools/tools/hcppc/bin/asppc
+
+# Linker to bring .o files together into an executable.
+
+LKOPT = -Bbase=0 -Qn -q -r
+LKCMD =
+LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
+
+# DOS Utilities
+
+DEL = rm
+COPY = cp
+LIST = ls
+
+OBJECTS = i2o1.o i2o2.o
+
+all: $(TARGET)
+
+$(TARGET): $(OBJECTS)
+ $(LINK) $(OBJECTS) -o $@
+
+objects: i2o1.o
+
+clean:
+ $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
+
+.s.o:
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
+# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
+
+.c.o:
+ $(CCobj) $<
+
+.c.s:
+ $(CCobj) $(LST) $<
+
+i2o1.o: i2o.h i2o1.c
+ $(CCobj) $<
+
+i2o2.o: i2o.h i2o2.s
+ $(DEL) -f $*.i
+ $(PREP) -Hasmcpp $<
+ $(AS) $(ASOPT) $*.i
--- /dev/null
+#ifndef I2O_H
+#define I2O_H
+/*********************************************************
+ * $Id: i2o.h,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *********************************************************/
+
+#define I2O_REG_OFFSET 0x0004
+
+#define PCI_CFG_CLA 0x0B
+#define PCI_CFG_SCL 0x0A
+#define PCI_CFG_PIC 0x09
+
+#define I2O_IMR0 0x0050
+#define I2O_IMR1 0x0054
+#define I2O_OMR0 0x0058
+#define I2O_OMR1 0x005C
+
+#define I2O_ODBR 0x0060
+#define I2O_IDBR 0x0068
+
+#define I2O_OMISR 0x0030
+#define I2O_OMIMR 0x0034
+#define I2O_IMISR 0x0100
+#define I2O_IMIMR 0x0104
+
+/* accessable to PCI master but local processor */
+#define I2O_IFQPR 0x0040
+#define I2O_OFQPR 0x0044
+
+/* accessable to local processor */
+#define I2O_IFHPR 0x0120
+#define I2O_IFTPR 0x0128
+#define I2O_IPHPR 0x0130
+#define I2O_IPTPR 0x0138
+#define I2O_OFHPR 0x0140
+#define I2O_OFTPR 0x0148
+#define I2O_OPHPR 0x0150
+#define I2O_OPTPR 0x0158
+#define I2O_MUCR 0x0164
+#define I2O_QBAR 0x0170
+
+#define I2O_NUM_MSG 2
+
+typedef enum _i2o_status
+{
+ I2OSUCCESS = 0,
+ I2OINVALID,
+ I2OMSGINVALID,
+ I2ODBINVALID,
+ I2OQUEINVALID,
+ I2OQUEEMPTY,
+ I2OQUEFULL,
+ I2ONOEVENT,
+} I2OSTATUS;
+
+typedef enum _queue_size
+{
+ QSIZE_4K = 0x02,
+ QSIZE_8K = 0x04,
+ QSIZE_16K = 0x08,
+ QSIZE_32K = 0x10,
+ QSIZe_64K = 0x20,
+} QUEUE_SIZE;
+
+typedef enum _location
+{
+ LOCAL = 0, /* used by local processor to access its own on board device,
+ local processor's eumbbar is required */
+ REMOTE, /* used by PCI master to access the devices on its PCI device,
+ device's pcsrbar is required */
+} LOCATION;
+
+/* door bell */
+typedef enum _i2o_in_db
+{
+ IN_DB = 1,
+ MC, /* machine check */
+} I2O_IN_DB;
+
+/* I2O PCI configuration identification */
+typedef struct _i2o_iop
+{
+ unsigned int base_class : 8;
+ unsigned int sub_class : 8;
+ unsigned int prg_code : 8;
+} I2OIOP;
+
+/* I2O Outbound Message Interrupt Status Register */
+typedef struct _i2o_om_stat
+{
+ unsigned int rsvd0 : 26;
+ unsigned int opqi : 1;
+ unsigned int rsvd1 : 1;
+ unsigned int odi : 1;
+ unsigned int rsvd2 : 1;
+ unsigned int om1i : 1;
+ unsigned int om0i : 1;
+} I2OOMSTAT;
+
+/* I2O inbound Message Interrupt Status Register */
+typedef struct _i2o_im_stat
+{
+ unsigned int rsvd0 : 23;
+ unsigned int ofoi : 1;
+ unsigned int ipoi : 1;
+ unsigned int rsvd1 : 1;
+ unsigned int ipqi : 1;
+ unsigned int mci : 1;
+ unsigned int idi : 1;
+ unsigned int rsvd2 : 1;
+ unsigned int im1i : 1;
+ unsigned int im0i : 1;
+} I2OIMSTAT;
+
+/**
+ Enable the interrupt associated with in/out bound msg
+
+ Inbound message interrupt generated by PCI master and serviced by local processor
+ local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
+
+ Outbound message interrupt generated by local processor and serviced by PCI master
+ PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
+ **/
+extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ); /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+
+/**
+ Disable the interrupt associated with in/out bound msg
+
+ local processor needs to disable its inbound interrupts it is not interested (LOCAL)
+
+ PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
+ **/
+extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ); /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+
+/**
+ Read the msg register either from local inbound msg 0/1,
+ or an outbound msg 0/1 of devices.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, outbound msg of the device is read.
+ Otherwise local inbound msg is read.
+ **/
+extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int *msg );
+
+/**
+ Write to nth Msg register either on local outbound msg 0/1,
+ or aninbound msg 0/1 of devices
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, inbound msg on the device is written.
+ Otherwise local outbound msg is written.
+ **/
+extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int msg );
+
+/**
+ Enable the In/Out DoorBell Interrupt
+
+ InDoorBell interrupt is generated by PCI master and serviced by local processor
+ local processor needs to enable its inbound doorbell interrupts it wants to handle
+
+ OutDoorbell interrupt is generated by local processor and serviced by PCI master
+ PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
+ **/
+extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+
+/**
+ Disable the In/Out DoorBell Interrupt
+
+ local processor needs to disable its inbound doorbell interrupts it is not interested
+
+ PCI master needs to disable outbound doorbell interrupts of devices it is not interested
+
+ **/
+extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+
+/**
+ Read a local indoorbell register, or an outdoorbell of devices.
+ Reading a doorbell register, the register will be cleared.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, outdoorbell register on the device is read.
+ Otherwise local in doorbell is read
+ **/
+extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base); /* pcsrbar/eumbbar */
+
+/**
+ Write to a local outdoorbell register, or an indoorbell register of devices.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, in doorbell register on the device is written.
+ Otherwise local out doorbell is written
+ **/
+extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int msg ); /* in / out */
+
+/**
+ Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
+ the register will be cleared.
+
+ The outbound interrupt status is AND with the outbound
+ interrupt mask. The result is returned.
+
+ PCI master must pass the pcsrbar to the function.
+ **/
+extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
+
+/**
+ Read the inbound msg unit interrupt status. Reading an interrupt status register,
+ the register will be cleared.
+
+ The inbound interrupt status is AND with the inbound
+ interrupt mask. The result is returned.
+
+ Local process must pass its eumbbar to the function.
+**/
+extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
+
+/**
+ Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
+ MUCR.
+ **/
+extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
+ QUEUE_SIZE,
+ unsigned int qba);/* queue base address that must be aligned at 1M */
+/**
+ Enable the circular queue
+ **/
+extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
+
+/**
+ Disable the circular queue
+ **/
+extern void I2OFIFODisable( unsigned int eumbbar );
+
+/**
+ Enable the circular queue interrupt
+ PCI master enables outbound FIFO interrupt of device
+ Device enables its inbound FIFO interrupt
+ **/
+extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
+
+/**
+ Disable the circular queue interrupt
+ PCI master disables outbound FIFO interrupt of device
+ Device disables its inbound FIFO interrupt
+ **/
+extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
+
+/**
+ Enable the circular queue overflow interrupt
+ **/
+extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
+
+/**
+ Disable the circular queue overflow interrupt
+ **/
+extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
+
+/**
+ Allocate a free msg frame from free FIFO.
+
+ PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
+ while local processor allocates a free msg frame from outbound free queue(OFTPR)
+
+ Unless both free queues are initialized, allocating a free MF will return 0xffffffff
+ **/
+extern I2OSTATUS I2OFIFOAlloc( LOCATION,
+ unsigned int base,
+ void **pMsg);
+/**
+ Free a used msg frame back to free queue
+ PCI Master frees a MFA through outbound queue port of device(OFQPR)
+ while local processor frees a MFA into its inbound free queue(IFHPR)
+
+ Used msg frame does not need to be recycled in the order they
+ read
+
+ This function has to be called by PCI master to initialize Inbound free queue
+ and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
+ **/
+extern I2OSTATUS I2OFIFOFree( LOCATION,
+ unsigned int base,
+ void *pMsg );
+
+/**
+ Post a msg into FIFO
+ PCI Master posts a msg through inbound queue port of device(IFQPR)
+ while local processor post a msg into its outbound post queue(OPHPR)
+
+ The total number of msg must be less than the max size of the queue
+ Otherwise queue overflow interrupt will assert.
+ **/
+extern I2OSTATUS I2OFIFOPost( LOCATION,
+ unsigned int base,
+ void *pMsg );
+
+/**
+ Read a msg from FIFO
+ PCI Master reads a msg through outbound queue port of device(OFQPR)
+ while local processor reads a msg from its inbound post queue(IPTPR)
+ **/
+extern I2OSTATUS I2OFIFOGet( LOCATION,
+ unsigned int base,
+ void **pMsg );
+
+/**
+ Get the I2O PCI configuration identification register
+ **/
+extern I2OSTATUS I2OPCIConfigGet( LOCATION,
+ unsigned int base,
+ I2OIOP *);
+
+#endif
--- /dev/null
+/*********************************************************
+ * $Id
+ *
+ * copyright @ Motorola, 1999
+ *********************************************************/
+#include "i2o.h"
+
+extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
+#pragma Alias( load_runtime_reg, "load_runtime_reg" );
+
+extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
+#pragma Alias( store_runtime_reg, "store_runtime_reg" );
+
+typedef struct _fifo_stat
+{
+ QUEUE_SIZE qsz;
+ unsigned int qba;
+} FIFOSTAT;
+
+FIFOSTAT fifo_stat = { QSIZE_4K, 0xffffffff };
+
+/**********************************************************************************
+ * function: I2OMsgEnable
+ *
+ * description: Enable the interrupt associated with in/out bound msg
+ * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
+ *
+ * All previously enabled interrupts are preserved.
+ * note:
+ * Inbound message interrupt generated by PCI master and serviced by local processor
+ * Outbound message interrupt generated by local processor and serviced by PCI master
+ *
+ * local processor needs to enable its inbound interrupts it wants to handle(LOCAL)
+ * PCI master needs to enable the outbound interrupts of devices it wants to handle(REMOTE)
+ ************************************************************************************/
+I2OSTATUS I2OMsgEnable ( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ) /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+{
+ unsigned int reg, val;
+ if ( ( n & 0x3 ) == 0 )
+ {
+ /* neither msg 0, nor msg 1 */
+ return I2OMSGINVALID;
+ }
+
+ n = (~n) & 0x3;
+ /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
+ * LOCAL : enable local inbound message, eumbbar as base
+ */
+ reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
+ val = load_runtime_reg( base, reg );
+
+ val &= 0xfffffffc; /* masked out the msg interrupt bits */
+ val |= n; /* LSB are the one we want */
+ store_runtime_reg( base, reg, val );
+
+ return I2OSUCCESS;
+}
+
+/*********************************************************************************
+ * function: I2OMsgDisable
+ *
+ * description: Disable the interrupt associated with in/out bound msg
+ * Other previously enabled interrupts are preserved.
+ * return I2OSUCCESS if no error otherwise return I2OMSGINVALID
+ *
+ * note:
+ * local processor needs to disable its inbound interrupts it is not interested(LOCAL)
+ * PCI master needs to disable outbound interrupts of devices it is not interested(REMOTE)
+ *********************************************************************************/
+I2OSTATUS I2OMsgDisable( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ) /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+{
+ unsigned int reg, val;
+
+ if ( ( n & 0x3 ) == 0 )
+ {
+ /* neither msg 0, nor msg 1 */
+ return I2OMSGINVALID;
+ }
+
+ /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
+ * LOCAL : disable local inbound message interrupt, eumbbar as base
+ */
+ reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
+ val = load_runtime_reg( base, reg );
+
+ val &= 0xfffffffc; /* masked out the msg interrupt bits */
+ val |= ( n & 0x3 );
+ store_runtime_reg( base, reg, val );
+
+ return I2OSUCCESS;
+
+}
+
+/**************************************************************************
+ * function: I2OMsgGet
+ *
+ * description: Local processor reads the nth Msg register from its inbound msg,
+ * or a PCI Master reads nth outbound msg from device
+ *
+ * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
+ *
+ * note:
+ * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
+ * If it is remote, outbound msg on the device is read; otherwise local inbound msg is read
+ *************************************************************************/
+I2OSTATUS I2OMsgGet ( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int *msg )
+{
+ if ( n >= I2O_NUM_MSG || msg == 0 )
+ {
+ return I2OMSGINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* read the outbound msg of the device, pcsrbar as base */
+ *msg = load_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET );
+ }
+ else
+ {
+ /* read the inbound msg sent by PCI master, eumbbar as base */
+ *msg = load_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET );
+ }
+
+ return I2OSUCCESS;
+}
+
+/***************************************************************
+ * function: I2OMsgPost
+ *
+ * description: Kahlua writes to its nth outbound msg register
+ * PCI master writes to nth inbound msg register of device
+ *
+ * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
+ *
+ * note:
+ * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
+ *
+ * If it is remote, inbound msg on the device is written; otherwise local outbound msg is written
+ ***************************************************************/
+I2OSTATUS I2OMsgPost( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int msg )
+{
+ if ( n >= I2O_NUM_MSG )
+ {
+ return I2OMSGINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* write to the inbound msg register of the device, pcsrbar as base */
+ store_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET, msg );
+ }
+ else
+ {
+ /* write to the outbound msg register for PCI master to read, eumbbar as base */
+ store_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET, msg );
+ }
+
+ return I2OSUCCESS;
+}
+
+/***********************************************************************
+ * function: I2ODBEnable
+ *
+ * description: Local processor enables it's inbound doorbell interrupt
+ * PCI master enables outbound doorbell interrupt of devices
+ * Other previously enabled interrupts are preserved.
+ * Return I2OSUCCESS if no error otherwise return I2ODBINVALID
+ *
+ * note:
+ * In DoorBell interrupt is generated by PCI master and serviced by local processor
+ * Out Doorbell interrupt is generated by local processor and serviced by PCI master
+ *
+ * Out Doorbell interrupt is generated by local processor and serviced by PCI master
+ * PCI master needs to enable the outbound doorbell interrupts of device it wants to handle
+ **********************************************************************/
+I2OSTATUS I2ODBEnable( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+{
+
+ /* LOCATION - REMOTE : PCI master initializes outbound doorbell message of device
+ * LOCAL : Kahlua initializes its inbound doorbell message
+ */
+ unsigned int val;
+
+ if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
+ {
+ return I2ODBINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* pcsrbar is base */
+ val = load_runtime_reg( base, I2O_OMIMR );
+ val &= 0xfffffff7;
+ store_runtime_reg( base, I2O_OMIMR , val );
+ }
+ else
+ {
+ /* eumbbar is base */
+ val = load_runtime_reg( base, I2O_IMIMR);
+ in_db = ( (~in_db) & 0x3 ) << 3;
+ val = ( val & 0xffffffe7) | in_db;
+ store_runtime_reg( base, I2O_IMIMR, val );
+ }
+
+ return I2OSUCCESS;
+}
+
+/**********************************************************************************
+ * function: I2ODBDisable
+ *
+ * description: local processor disables its inbound DoorBell Interrupt
+ * PCI master disables outbound DoorBell interrupt of device
+ * Other previously enabled interrupts are preserved.
+ * return I2OSUCCESS if no error.Otherwise return I2ODBINVALID
+ *
+ * note:
+ * local processor needs to disable its inbound doorbell interrupts it is not interested
+ *
+ * PCI master needs to disable outbound doorbell interrupts of device it is not interested
+ ************************************************************************************/
+I2OSTATUS I2ODBDisable( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+{
+ /* LOCATION - REMOTE : handle device's out bound message initialization
+ * LOCAL : handle local in bound message initialization
+ */
+ unsigned int val;
+
+ if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
+ {
+ return I2ODBINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* pcsrbar is the base */
+ val = load_runtime_reg( base, I2O_OMIMR );
+ val |= 0x8;
+ store_runtime_reg( base, I2O_OMIMR, val );
+ }
+ else
+ {
+ val = load_runtime_reg( base, I2O_IMIMR);
+ in_db = ( in_db & 0x3 ) << 3;
+ val |= in_db;
+ store_runtime_reg( base, I2O_IMIMR, val );
+ }
+
+ return I2OSUCCESS;
+}
+
+/**********************************************************************************
+ * function: I2ODBGet
+ *
+ * description: Local processor reads its in doorbell register,
+ * PCI master reads the outdoorbell register of device.
+ * After a doorbell register is read, the whole register will be cleared.
+ * Otherwise, HW keeps generating interrupt.
+ *
+ * note:
+ * If it is not local, pcsrbar must be passed to the function.
+ * Otherwise eumbbar is passed.
+ *
+ * If it is remote, out doorbell register on the device is read.
+ * Otherwise local in doorbell is read
+ *
+ * If the register is not cleared by write to it, any remaining bit of b'1's
+ * will cause interrupt pending.
+ *********************************************************************************/
+unsigned int I2ODBGet( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base) /* pcsrbar/eumbbar */
+{
+ unsigned int msg, val;
+
+ if ( loc == REMOTE )
+ {
+ /* read outbound doorbell register of device, pcsrbar is the base */
+ val = load_runtime_reg( base, I2O_ODBR );
+ msg = val & 0xe0000000;
+ store_runtime_reg( base, I2O_ODBR, val ); /* clear the register */
+ }
+ else
+ {
+ /* read the inbound doorbell register, eumbbar is the base */
+ val = load_runtime_reg( base, I2O_IDBR );
+ store_runtime_reg( base, I2O_IDBR, val ); /* clear the register */
+ msg = val;
+ }
+
+ return msg;
+}
+
+/**********************************************************************
+ * function: I2ODBPost
+ *
+ * description: local processor writes to a outbound doorbell register,
+ * PCI master writes to the inbound doorbell register of device
+ *
+ * note:
+ * If it is not local, pcsrbar must be passed to the function.
+ * Otherwise eumbbar is passed.
+ *
+ * If it is remote, in doorbell register on the device is written.
+ * Otherwise local out doorbell is written
+ *********************************************************************/
+void I2ODBPost( LOCATION loc, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int msg ) /* in / out */
+{
+ if ( loc == REMOTE )
+ {
+ /* write to inbound doorbell register of device, pcsrbar is the base */
+ store_runtime_reg( base, I2O_IDBR, msg );
+ }
+ else
+ {
+ /* write to local outbound doorbell register, eumbbar is the base */
+ store_runtime_reg( base, I2O_ODBR, msg & 0x1fffffff );
+ }
+
+}
+
+/********************************************************************
+ * function: I2OOutMsgStatGet
+ *
+ * description: PCI master reads device's outbound msg unit interrupt status.
+ * Reading an interrupt status register,
+ * the register will be cleared.
+ *
+ * The value of the status register is AND with the outbound
+ * interrupt mask and result is returned.
+ *
+ * note:
+ * pcsrbar must be passed to the function.
+ ********************************************************************/
+I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT *val )
+{
+ unsigned int stat;
+ unsigned int mask;
+
+ if ( val == 0 )
+ {
+ return I2OINVALID;
+ }
+
+ /* read device's outbound status */
+ stat = load_runtime_reg( pcsrbar, I2O_OMISR );
+ mask = load_runtime_reg( pcsrbar, I2O_OMIMR );
+ store_runtime_reg( pcsrbar, I2O_OMISR, stat & 0xffffffd7);
+
+ stat &= mask;
+ val->rsvd0 = ( stat & 0xffffffc0 ) >> 6;
+ val->opqi = ( stat & 0x00000020 ) >> 5;
+ val->rsvd1 = ( stat & 0x00000010 ) >> 4;
+ val->odi = ( stat & 0x00000008 ) >> 3;
+ val->rsvd2 = ( stat & 0x00000004 ) >> 2;
+ val->om1i = ( stat & 0x00000002 ) >> 1;
+ val->om0i = ( stat & 0x00000001 );
+
+ return I2OSUCCESS;
+}
+
+/********************************************************************
+ * function: I2OInMsgStatGet
+ *
+ * description: Local processor reads its inbound msg unit interrupt status.
+ * Reading an interrupt status register,
+ * the register will be cleared.
+ *
+ * The inbound msg interrupt status is AND with the inbound
+ * msg interrupt mask and result is returned.
+ *
+ * note:
+ * eumbbar must be passed to the function.
+ ********************************************************************/
+I2OSTATUS I2OInMsgStatGet(unsigned int eumbbar, I2OIMSTAT *val)
+{
+ unsigned int stat;
+ unsigned int mask;
+
+ if ( val == 0 )
+ {
+ return I2OINVALID;
+ }
+
+ /* read device's outbound status */
+ stat = load_runtime_reg( eumbbar, I2O_OMISR );
+ mask = load_runtime_reg( eumbbar, I2O_OMIMR );
+ store_runtime_reg( eumbbar, I2O_OMISR, stat & 0xffffffe7 );
+
+ stat &= mask;
+ val->rsvd0 = ( stat & 0xfffffe00 ) >> 9;
+ val->ofoi = ( stat & 0x00000100 ) >> 8;
+ val->ipoi = ( stat & 0x00000080 ) >> 7;
+ val->rsvd1 = ( stat & 0x00000040 ) >> 6;
+ val->ipqi = ( stat & 0x00000020 ) >> 5;
+ val->mci = ( stat & 0x00000010 ) >> 4;
+ val->idi = ( stat & 0x00000008 ) >> 3;
+ val->rsvd2 = ( stat & 0x00000004 ) >> 2;
+ val->im1i = ( stat & 0x00000002 ) >> 1;
+ val->im0i = ( stat & 0x00000001 );
+
+ return I2OSUCCESS;
+
+}
+
+/***********************************************************
+ * function: I2OFIFOInit
+ *
+ * description: Configure the I2O FIFO, including QBAR,
+ * IFHPR/IFTPR, IPHPR/IPTPR, OFHPR/OFTPR,
+ * OPHPR/OPTPR, MUCR.
+ *
+ * return I2OSUCCESS if no error,
+ * otherwise return I2OQUEINVALID
+ *
+ * note: It is NOT this driver's responsibility of initializing
+ * MFA blocks, i.e., FIFO queue itself. The MFA blocks
+ * must be initialized before I2O unit can be used.
+ ***********************************************************/
+I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
+ QUEUE_SIZE sz, /* value of CQS of MUCR */
+ unsigned int qba) /* queue base address that must be aligned at 1M */
+{
+
+ if ( ( qba & 0xfffff ) != 0 )
+ {
+ /* QBA must be aligned at 1Mbyte boundary */
+ return I2OQUEINVALID;
+ }
+
+ store_runtime_reg( eumbbar, I2O_QBAR, qba );
+ store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz );
+ store_runtime_reg( eumbbar, I2O_IFHPR, qba );
+ store_runtime_reg( eumbbar, I2O_IFTPR, qba );
+ store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 ));
+ store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 ));
+ store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 ));
+ store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 ));
+ store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 ));
+ store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 ));
+
+ fifo_stat.qsz = sz;
+ fifo_stat.qba = qba;
+
+ return I2OSUCCESS;
+}
+
+/**************************************************
+ * function: I2OFIFOEnable
+ *
+ * description: Enable the circular queue
+ * return I2OSUCCESS if no error.
+ * Otherwise I2OQUEINVALID is returned.
+ *
+ * note:
+ *************************************************/
+I2OSTATUS I2OFIFOEnable( unsigned int eumbbar )
+{
+ unsigned int val;
+
+ if ( fifo_stat.qba == 0xfffffff )
+ {
+ return I2OQUEINVALID;
+ }
+
+ val = load_runtime_reg( eumbbar, I2O_MUCR );
+ store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 );
+
+ return I2OSUCCESS;
+}
+
+/**************************************************
+ * function: I2OFIFODisable
+ *
+ * description: Disable the circular queue
+ *
+ * note:
+ *************************************************/
+void I2OFIFODisable( unsigned int eumbbar )
+{
+ if ( fifo_stat.qba == 0xffffffff )
+ {
+ /* not enabled */
+ return;
+ }
+
+ unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR );
+ store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );
+}
+
+/****************************************************
+ * function: I2OFIFOAlloc
+ *
+ * description: Allocate a free MFA from free FIFO.
+ * return I2OSUCCESS if no error.
+ * return I2OQUEEMPTY if no more free MFA.
+ * return I2OINVALID on other errors.
+ *
+ * A free MFA must be allocated before a
+ * message can be posted.
+ *
+ * note:
+ * PCI Master allocates a free MFA from inbound queue of device
+ * (pcsrbar is the base,) through the inbound queue port of device
+ * while local processor allocates a free MFA from its outbound
+ * queue (eumbbar is the base.)
+ *
+ ****************************************************/
+I2OSTATUS I2OFIFOAlloc( LOCATION loc,
+ unsigned int base,
+ void **pMsg )
+{
+ I2OSTATUS stat = I2OSUCCESS;
+ void *pHdr, *pTil;
+
+ if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
+ {
+ /* not configured */
+ return I2OQUEINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* pcsrbar is the base and read the inbound free tail ptr */
+ pTil = (void *)load_runtime_reg( base, I2O_IFQPR );
+ if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
+ {
+ stat = I2OQUEEMPTY;
+ }
+ else
+ {
+ *pMsg = pTil;
+ }
+ }
+ else
+ {
+ /* eumbbar is the base and read the outbound free tail ptr */
+ pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */
+ pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */
+
+ /* check underflow */
+ if ( pHdr == pTil )
+ {
+ /* hdr and til point to the same fifo item, no free MFA */
+ stat = I2OQUEEMPTY;
+ }
+ else
+ {
+ /* update OFTPR */
+ *pMsg = (void *)(*(unsigned char *)pTil);
+ pTil = (void *)((unsigned int)pTil + 4);
+ if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) )
+ {
+ /* reach the upper limit */
+ pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) ));
+ }
+ store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil );
+ }
+ }
+
+ return stat;
+}
+
+/******************************************************
+ * function: I2OFIFOFree
+ *
+ * description: Free a used MFA back to free queue after
+ * use.
+ * return I2OSUCCESS if no error.
+ * return I2OQUEFULL if inbound free queue
+ * overflow
+ *
+ * note: PCI Master frees a MFA into device's outbound queue
+ * (OFQPR) while local processor frees a MFA into its
+ * inbound queue (IFHPR).
+ *****************************************************/
+I2OSTATUS I2OFIFOFree( LOCATION loc,
+ unsigned int base,
+ void *pMsg )
+{
+ void **pHdr, **pTil;
+ I2OSTATUS stat = I2OSUCCESS;
+
+ if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
+ {
+ return I2OQUEINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* pcsrbar is the base */
+ store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg );
+ }
+ else
+ {
+ /* eumbbar is the base */
+ pHdr = (void **)load_runtime_reg( base, I2O_IFHPR );
+ pTil = (void **)load_runtime_reg( base, I2O_IFTPR );
+
+ /* store MFA */
+ *pHdr = pMsg;
+
+ /* update IFHPR */
+ pHdr += 4;
+
+ if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) )
+ {
+ /* reach the upper limit */
+ pHdr = (void **)fifo_stat.qba;
+ }
+
+ /* check inbound free queue overflow */
+ if ( pHdr != pTil )
+ {
+ store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
+ }
+ else
+ {
+ stat = I2OQUEFULL;
+ }
+
+ }
+
+ return stat;
+
+}
+
+/*********************************************
+ * function: I2OFIFOPost
+ *
+ * description: Post a msg into FIFO post queue
+ * the value of msg must be the one
+ * returned by I2OFIFOAlloc
+ *
+ * note: PCI Master posts a msg into device's inbound queue
+ * (IFQPR) while local processor post a msg into device's
+ * outbound queue (OPHPR)
+ *********************************************/
+I2OSTATUS I2OFIFOPost( LOCATION loc,
+ unsigned int base,
+ void *pMsg )
+{
+ void **pHdr, **pTil;
+ I2OSTATUS stat = I2OSUCCESS;
+
+ if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
+ {
+ return I2OQUEINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* pcsrbar is the base */
+ store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg );
+ }
+ else
+ {
+ /* eumbbar is the base */
+ pHdr = (void **)load_runtime_reg( base, I2O_OPHPR );
+ pTil = (void **)load_runtime_reg( base, I2O_OPTPR );
+
+ /* store MFA */
+ *pHdr = pMsg;
+
+ /* update IFHPR */
+ pHdr += 4;
+
+ if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) )
+ {
+ /* reach the upper limit */
+ pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) );
+ }
+
+ /* check post queue overflow */
+ if ( pHdr != pTil )
+ {
+ store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
+ }
+ else
+ {
+ stat = I2OQUEFULL;
+ }
+ }
+
+ return stat;
+}
+
+/************************************************
+ * function: I2OFIFOGet
+ *
+ * description: Read a msg from FIFO
+ * This function should be called
+ * only when there is a corresponding
+ * msg interrupt.
+ *
+ * note: PCI Master reads a msg from device's outbound queue
+ * (OFQPR) while local processor reads a msg from device's
+ * inbound queue (IPTPR)
+ ************************************************/
+I2OSTATUS I2OFIFOGet( LOCATION loc,
+ unsigned int base,
+ void **pMsg )
+{
+ I2OSTATUS stat = I2OSUCCESS;
+ void *pHdr, *pTil;
+
+ if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
+ {
+ /* not configured */
+ return I2OQUEINVALID;
+ }
+
+ if ( loc == REMOTE )
+ {
+ /* pcsrbar is the base */
+ pTil = (void *)load_runtime_reg( base, I2O_OFQPR );
+ if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
+ {
+ stat = I2OQUEEMPTY;
+ }
+ else
+ {
+ *pMsg = pTil;
+ }
+ }
+ else
+ {
+ /* eumbbar is the base and read the outbound free tail ptr */
+ pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */
+ pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */
+
+ /* check underflow */
+ if ( pHdr == pTil )
+ {
+ /* no free MFA */
+ stat = I2OQUEEMPTY;
+ }
+ else
+ {
+ /* update OFTPR */
+ *pMsg = (void *)(*(unsigned char *)pTil);
+ pTil = (void *)((unsigned int)pTil + 4);
+ if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) )
+ {
+ /* reach the upper limit */
+ pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) );
+ }
+
+ store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil );
+ }
+ }
+
+ return stat;
+}
+
+/********************************************************
+ * function: I2OIOP
+ *
+ * description: Get the I2O PCI configuration identification
+ * register.
+ *
+ * note: PCI master should pass pcsrbar while local processor
+ * should pass eumbbar.
+ *********************************************************/
+I2OSTATUS I2OPCIConfigGet( LOCATION loc,
+ unsigned int base,
+ I2OIOP * val)
+{
+ unsigned int tmp;
+ if ( val == 0 )
+ {
+ return I2OINVALID;
+ }
+ tmp = load_runtime_reg( base, PCI_CFG_CLA );
+ val->base_class = ( tmp & 0xFF) << 16;
+ tmp = load_runtime_reg( base, PCI_CFG_SCL );
+ val->sub_class= ( (tmp & 0xFF) << 8 );
+ tmp = load_runtime_reg( base, PCI_CFG_PIC );
+ val->prg_code = (tmp & 0xFF);
+ return I2OSUCCESS;
+}
+
+/*********************************************************
+ * function: I2OFIFOIntEnable
+ *
+ * description: Enable the circular post queue interrupt
+ *
+ * note:
+ * PCI master enables outbound FIFO interrupt of device
+ * pscrbar is the base
+ * Device enables its inbound FIFO interrupt
+ * eumbbar is the base
+ *******************************************************/
+void I2OFIFOIntEnable( LOCATION loc, unsigned int base )
+{
+ unsigned int reg, val;
+
+ /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
+ * LOCAL : enable local inbound message, eumbbar as base
+ */
+ reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
+ val = load_runtime_reg( base, reg );
+
+ val &= 0xffffffdf; /* clear the msg interrupt bits */
+ store_runtime_reg( base, reg, val );
+
+}
+
+/****************************************************
+ * function: I2OFIFOIntDisable
+ *
+ * description: Disable the circular post queue interrupt
+ *
+ * note:
+ * PCI master disables outbound FIFO interrupt of device
+ * (pscrbar is the base)
+ * Device disables its inbound FIFO interrupt
+ * (eumbbar is the base)
+ *****************************************************/
+void I2OFIFOIntDisable( LOCATION loc, unsigned int base )
+{
+
+ /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
+ * LOCAL : disable local inbound message interrupt, eumbbar as base
+ */
+ unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
+ unsigned int val = load_runtime_reg( base, reg );
+
+ val |= 0x00000020; /* masked out the msg interrupt bits */
+ store_runtime_reg( base, reg, val );
+
+}
+
+/*********************************************************
+ * function: I2OFIFOOverflowIntEnable
+ *
+ * description: Enable the circular queue overflow interrupt
+ *
+ * note:
+ * Device enables its inbound FIFO post overflow interrupt
+ * and outbound free overflow interrupt.
+ * eumbbar is the base
+ *******************************************************/
+void I2OFIFOOverflowIntEnable( unsigned int eumbbar )
+{
+ unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
+
+ val &= 0xfffffe7f; /* clear the two overflow interrupt bits */
+ store_runtime_reg( eumbbar, I2O_IMIMR, val );
+
+}
+
+/****************************************************
+ * function: I2OFIFOOverflowIntDisable
+ *
+ * description: Disable the circular queue overflow interrupt
+ *
+ * note:
+ * Device disables its inbound post FIFO overflow interrupt
+ * and outbound free FIFO overflow interrupt
+ * (eumbbar is the base)
+ *****************************************************/
+void I2OFIFOOverflowIntDisable( unsigned int eumbbar )
+{
+
+ unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
+
+ val |= 0x00000180; /* masked out the msg overflow interrupt bits */
+ store_runtime_reg( eumbbar, I2O_IMIMR, val );
+}
--- /dev/null
+/**************************************
+ * $Id: i2o2.S,v 1.1 2000/11/20 17:22:33 wdenk Exp $
+ *
+ * copyright @ Motorola, 1999
+ *
+ **************************************/
+
+/**********************************************************
+ * function: load_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ *
+ * output: r3 - register content
+ **********************************************************/
+ .text
+ .align 2
+ .global load_runtime_reg
+
+load_runtime_reg:
+
+ xor r5,r5,r5
+ or r5,r5,r3 /* save eumbbar */
+
+ lwbrx r3,r4,r5
+ sync
+
+ bclr 20, 0
+
+/****************************************************************
+ * function: store_runtime_reg
+ *
+ * input: r3 - value of eumbbar
+ * r4 - register offset in embedded utility space
+ * r5 - new value to be stored
+ *
+ ****************************************************************/
+ .text
+ .align 2
+ .global store_runtime_reg
+store_runtime_reg:
+
+ xor r0,r0,r0
+
+ stwbrx r5, r4, r3
+ sync
+
+ bclr 20,0
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <mpc8240.h>
+#include <asm/processor.h>
+#include <asm/pci_io.h>
+#include <commproc.h>
+#include "drivers/epic.h"
+
+/****************************************************************************/
+
+static __inline__ unsigned long get_msr(void)
+{
+ unsigned long msr;
+
+ asm volatile("mfmsr %0" : "=r" (msr) :);
+ return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+ asm volatile("mtmsr %0" : : "r" (msr));
+}
+
+static __inline__ unsigned long get_dec(void)
+{
+ unsigned long val;
+
+ asm volatile("mfdec %0" : "=r" (val) :);
+ return val;
+}
+
+
+static __inline__ void set_dec(unsigned long val)
+{
+ asm volatile("mtdec %0" : : "r" (val));
+}
+
+
+void enable_interrupts (void)
+{
+ set_msr (get_msr() | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int disable_interrupts (void)
+{
+ ulong msr = get_msr();
+ set_msr (msr & ~MSR_EE);
+ return ((msr & MSR_EE) != 0);
+}
+
+/****************************************************************************/
+
+void
+interrupt_init (bd_t *bd)
+{
+ /* it's all broken at the moment and I currently don't need interrupts
+ if you want to fix it, have a look at the epic drivers in dink32 v12
+ they do everthing and motorola said I could use the dink source in this project
+ as long as copyright notices remain intact.
+ epicInit(EPIC_DIRECT_IRQ,0);
+ set_msr (get_msr() | MSR_EE);
+ */
+}
+
+/****************************************************************************/
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt(struct pt_regs *regs)
+{
+ register unsigned long temp;
+ pci_readl(CFG_EUMB_ADDR + EPIC_PROC_INT_ACK_REG, temp);
+ sync(); /* i'm not convinced this is needed, but dink source has it */
+ temp &= 0xff; /*get vector*/
+
+ /*TODO: handle them -...*/
+ epicEOI();
+}
+
+/****************************************************************************/
+
+/*
+ * blank int handlers.
+ */
+
+void
+irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+}
+
+void
+irq_free_handler(int vec)
+{
+
+}
+
+/*TODO: some handlers for winbond and 87308 interrupts
+ and what about generic pci inteerupts?
+ vga?
+ */
+
+volatile ulong timestamp = 0;
+
+ void timer_interrupt(struct pt_regs *regs)
+ {
+ }
+
+ void reset_timer (void)
+ {
+ timestamp = 0;
+ }
+
+ ulong get_timer (ulong base)
+ {
+ return (timestamp - base);
+ }
+
+ void set_timer (ulong t)
+ {
+ timestamp = t;
+ }
--- /dev/null
+/*
+ * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* ppcboot - Startup Code for PowerPC based Embedded Boards
+ *
+ *
+ * The processor starts at 0x00000100 and the code is executed
+ * from flash. The code is organized to be at an other address
+ * in memory, but as long we don't jump around before relocating.
+ * board_init lies at a quite high address and when the cpu has
+ * jumped there, everything is ok.
+ * This works because the cpu gives the FLASH (CS0) the whole
+ * address space at startup, and board_init lies as a echo of
+ * the flash somewhere up there in the memorymap.
+ *
+ * board_init will change CS0 to be positioned at the correct
+ * address and (s)dram will be positioned at address 0
+ */
+#include <config.h>
+#include <mpc8240.h>
+#include "version.h"
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/* We don't want the MMU yet.
+*/
+#undef MSR_KERNEL
+#define MSR_KERNEL ( MSR_ME | MSR_RI ) /* Machine Check and Recoverable Interr. */
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+ START_GOT
+ GOT_ENTRY(_GOT2_TABLE_)
+ GOT_ENTRY(_FIXUP_TABLE_)
+
+ GOT_ENTRY(_start)
+ GOT_ENTRY(_start_of_vectors)
+ GOT_ENTRY(_end_of_vectors)
+ GOT_ENTRY(transfer_to_handler)
+
+ GOT_ENTRY(_end)
+ GOT_ENTRY(.bss)
+#if defined(CONFIG_FADS)
+ GOT_ENTRY(environment)
+#endif
+ END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+ .text
+ .long 0x27051956 /* PPCBOOT Magic Number */
+ .globl version_string
+version_string:
+ .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
+
+ . = EXC_OFF_SYS_RESET
+ .globl _start
+_start:
+ li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
+ b boot_cold
+
+ . = EXC_OFF_SYS_RESET + 0x10
+
+ .globl _start_warm
+_start_warm:
+ li r21, BOOTFLAG_WARM /* Software reboot */
+ b boot_warm
+
+boot_cold:
+boot_warm:
+
+ /* Initialize machine status; enable machine check interrupt */
+ /*----------------------------------------------------------------------*/
+ li r3, MSR_KERNEL /* Set ME, RI flags */
+ mtmsr r3
+ mtspr SRR1, r3 /* Make SRR1 match MSR */
+
+ mfspr r3, ICR /* clear Interrupt Cause Register */
+
+ addis r0,0,0x0000 // lets make sure that r0 is really 0
+
+ mfmsr r3 // turn off address translation
+ addis r4,0,0xffff
+ ori r4,r4,0xffcf
+ and r3,r3,r4
+ mtmsr r3
+ isync
+ sync // the MMU should be off...
+
+
+
+ /*
+ * Calculate absolute address in FLASH and jump there
+ *----------------------------------------------------------------------*/
+#ifndef DEBUG
+ lis r3, CFG_FLASH_BASE@h
+ ori r3, r3, CFG_FLASH_BASE@l
+ addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
+ mtlr r3
+ blr
+#endif
+in_flash:
+
+
+ /* thisk the stack pointer *somewhere* sensible. doesnt matter much where as we'll
+ move it when we relocate*/
+
+ lis r1, (CFG_MEMTEST_END - 0x3000)@h
+ ori r1, r1, (CFG_MEMTEST_END - 0x3000)@l
+
+
+ /* let the C-code set up the rest */
+ /* */
+ /* Be careful to keep code relocatable ! */
+ /*----------------------------------------------------------------------*/
+
+ GET_GOT /* initialize GOT access */
+
+ /* r3: IMMR */
+ bl cpu_init_f /* run low-level CPU init code (from Flash) */
+
+ mr r3, r21
+ /* r3: BOOTFLAG */
+ bl board_init_f /* run 1st part of board init code (from Flash) */
+
+
+
+ .globl _start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+ STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. "Never" generated on the 860. */
+ STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
+
+/* Instruction Storage exception. "Never" generated on the 860. */
+ STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+ STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+ . = EXC_OFF_ALIGN
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,DAR
+ stw r4,_DAR(r21)
+ mfspr r5,DSISR
+ stw r5,_DSISR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_Alignment:
+ .long AlignmentException - _start + EXC_OFF_SYS_RESET
+ .long int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+ . = EXC_OFF_PROGRAM
+ProgramCheck:
+ EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_ProgramCheck:
+ .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
+ .long int_return - _start + EXC_OFF_SYS_RESET
+
+ /* No FPU on MPC8xx. This exception is not supposed to happen.
+ */
+ STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
+
+ /* I guess we could implement decrementer, and may have
+ * to someday for timekeeping.
+ */
+ STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
+ STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+ STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_SYS_CALL, SystemCall, UnknownException)
+ STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
+ STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
+ STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
+ STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
+ STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, UnknownException)
+ STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
+ STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+ STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+ STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+ STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+ STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+ STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+ STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+ STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
+ STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
+ STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
+ STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
+
+ STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
+
+ .globl _end_of_vectors
+_end_of_vectors:
+
+
+ . = 0x3000
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+ .globl transfer_to_handler
+transfer_to_handler:
+ stw r22,_NIP(r21)
+ lis r22,MSR_POW@h
+ andc r23,r23,r22
+ stw r23,_MSR(r21)
+ SAVE_GPR(7, r21)
+ SAVE_4GPRS(8, r21)
+ SAVE_8GPRS(12, r21)
+ SAVE_8GPRS(24, r21)
+#if 0
+ andi. r23,r23,MSR_PR
+ mfspr r23,SPRG3 /* if from user, fix up tss.regs */
+ beq 2f
+ addi r24,r1,STACK_FRAME_OVERHEAD
+ stw r24,PT_REGS(r23)
+2: addi r2,r23,-TSS /* set r2 to current */
+ tovirt(r2,r2,r23)
+#endif
+ mflr r23
+ andi. r24,r23,0x3f00 /* get vector offset */
+ stw r24,TRAP(r21)
+ li r22,0
+ stw r22,RESULT(r21)
+ mtspr SPRG2,r22 /* r1 is now kernel sp */
+#if 0
+ addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
+ cmplw 0,r1,r2
+ cmplw 1,r1,r24
+ crand 1,1,4
+ bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
+#endif
+ lwz r24,0(r23) /* virtual address of handler */
+ lwz r23,4(r23) /* where to go when done */
+ mtspr SRR0,r24
+ mtspr SRR1,r20
+ mtlr r23
+ SYNC
+ rfi /* jump to handler, enable MMU */
+
+int_return:
+ mfmsr r29 /* Disable interrupts */
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r29,r29,r4
+ SYNC /* Some chip revs need this... */
+ mtmsr r29
+ SYNC
+ lwz r2,_CTR(r1)
+ lwz r0,_LINK(r1)
+ mtctr r2
+ mtlr r0
+ lwz r2,_XER(r1)
+ lwz r0,_CCR(r1)
+ mtspr XER,r2
+ mtcrf 0xFF,r0
+ REST_10GPRS(3, r1)
+ REST_10GPRS(13, r1)
+ REST_8GPRS(23, r1)
+ REST_GPR(31, r1)
+ lwz r2,_NIP(r1) /* Restore environment */
+ lwz r0,_MSR(r1)
+ mtspr SRR0,r2
+ mtspr SRR1,r0
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ SYNC
+ rfi
+
+/* Cache functions.
+*/
+ .globl icache_enable
+icache_enable:
+ mfspr r5,HID0 // turn on the I cache.
+ ori r5,r5,0x8800 // Instruction cache only//!
+ addis r6,0,0xFFFF
+ ori r6,r6,0xF7FF
+ and r6,r5,r6 // clear the invalidate bit
+ sync
+ mtspr HID0,r5
+ mtspr HID0,r6
+ isync
+ sync
+ blr
+
+ .globl icache_disable
+icache_disable:
+ mfspr r5,HID0
+ addis r6,0,0xFFFF
+ ori r6,r6,0x7FFF
+ and r5,r5,r6
+ sync
+ mtspr HID0,r5
+ isync
+ sync
+ blr
+
+ .globl icache_status
+icache_status:
+ mfspr r3, HID0
+ srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
+ andi. r3, r3, 1
+ blr
+
+ .globl dcache_enable
+dcache_enable:
+ mfspr r5,HID0 // turn on the D cache.
+ ori r5,r5,0x4400 // Data cache only//!
+ mfspr r4, PVR // read PVR
+ srawi r3, r4, 16 // shift off the least 16 bits
+ cmpi 0, 0, r3, 0xC // Check for Max pvr
+ bne NotMax
+ ori r5,r5,0x0040 // setting the DCFA bit, for Max rev 1 errata
+NotMax:
+ addis r6,0,0xFFFF
+ ori r6,r6,0xFBFF
+ and r6,r5,r6 // clear the invalidate bit
+ sync
+ mtspr HID0,r5
+ mtspr HID0,r6
+ isync
+ sync
+ blr
+
+ .globl dcache_disable
+dcache_disable:
+ mfspr r5,HID0
+ addis r6,0,0xFFFF
+ ori r6,r6,0xBFFF
+ and r5,r5,r6
+ sync
+ mtspr HID0,r5
+ isync
+ sync
+ blr
+
+ .globl dcache_status
+dcache_status:
+ mfspr r3, HID0
+ srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
+ andi. r3, r3, 1
+ blr
+
+ .globl dc_read
+dc_read:
+/*TODO : who uses this, what should it do?
+*/
+ blr
+
+
+ .globl get_pvr
+get_pvr:
+ mfspr r3, PVR
+ blr
+
+
+/*------------------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, bd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+ .globl relocate_code
+relocate_code:
+
+ mr r1, r3 /* Set new stack pointer */
+ mr r9, r4 /* Save copy of Board Info pointer */
+ mr r10, r5 /* Save copy of Destination Address */
+
+ mr r3, r5 /* Destination Address */
+#ifdef DEBUG
+ lis r4, CFG_SDRAM_BASE@h /* Source Address */
+ ori r4, r4, CFG_SDRAM_BASE@l
+#else
+ lis r4, CFG_FLASH_BASE@h /* Source Address */
+ ori r4, r4, CFG_FLASH_BASE@l
+#endif
+ lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
+ ori r5, r5, CFG_MONITOR_LEN@l
+ li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
+
+ /*
+ * Fix GOT pointer:
+ *
+ * New GOT-PTR = (old GOT-PTR - CFG_FLASH_BASE) + Destination Address
+ *
+ * Offset:
+ */
+ sub r15, r10, r4
+
+ /* First our own GOT */
+ add r14, r14, r15
+ /* the the one used by the C code */
+ add r30, r30, r15
+
+ /*
+ * Now relocate code
+ */
+
+ cmplw cr1,r3,r4
+ addi r0,r5,3
+ srwi. r0,r0,2
+ beq cr1,4f /* In place copy is not necessary */
+ beq 7f /* Protect against 0 count */
+ mtctr r0
+ bge cr1,2f
+
+ la r8,-4(r4)
+ la r7,-4(r3)
+1: lwzu r0,4(r8)
+ stwu r0,4(r7)
+ bdnz 1b
+ b 4f
+
+2: slwi r0,r0,2
+ add r8,r4,r0
+ add r7,r3,r0
+3: lwzu r0,-4(r8)
+ stwu r0,-4(r7)
+ bdnz 3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4: cmpwi r6,0
+ add r5,r3,r5
+ beq 7f /* Always flush prefetch queue in any case */
+ subi r0,r6,1
+ andc r3,r3,r0
+ mr r4,r3
+5: cmplw r4,r5
+ dcbst 0,r4
+ add r4,r4,r6
+ blt 5b
+ sync /* Wait for all dcbst to complete on bus */
+ mr r4,r3
+6: cmplw r4,r5
+ icbi 0,r4
+ add r4,r4,r6
+ blt 6b
+7: sync /* Wait for all icbi to complete on bus */
+ isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+ addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+ mtlr r0
+ blr
+
+in_ram:
+
+ /*
+ * Relocation Function, r14 point to got2+0x8000
+ *
+ * Adjust got2 pointers, no need to check for 0, this code
+ * already puts a few entries in the table.
+ */
+ li r0,__got2_entries@sectoff@l
+ la r3,GOT(_GOT2_TABLE_)
+ lwz r11,GOT(_GOT2_TABLE_)
+ mtctr r0
+ sub r11,r3,r11
+ addi r3,r3,-4
+1: lwzu r0,4(r3)
+ add r0,r0,r11
+ stw r0,0(r3)
+ bdnz 1b
+
+ /*
+ * Now adjust the fixups and the pointers to the fixups
+ * in case we need to move ourselves again.
+ */
+2: li r0,__fixup_entries@sectoff@l
+ lwz r3,GOT(_FIXUP_TABLE_)
+ cmpwi r0,0
+ mtctr r0
+ addi r3,r3,-4
+ beq 4f
+3: lwzu r4,4(r3)
+ lwzux r0,r4,r11
+ add r0,r0,r11
+ stw r10,0(r3)
+ stw r0,0(r4)
+ bdnz 3b
+4:
+clear_bss:
+ /*
+ * Now clear BSS segment
+ */
+ lwz r3,GOT(.bss)
+#if defined(CONFIG_FADS)
+ /*
+ * For the FADS - the environment is the very last item in flash.
+ * The real .bss stops just before environment starts, so only
+ * clear up to that point.
+ */
+ lwz r4,GOT(environment)
+#else
+ lwz r4,GOT(_end)
+#endif
+
+ cmplw 0, r3, r4
+ beq 6f
+
+ li r0, 0
+5:
+ stw r0, 0(r3)
+ addi r3, r3, 4
+ cmplw 0, r3, r4
+ blt 5b
+6:
+
+ mr r3, r9 /* Board Info pointer */
+ mr r4, r10 /* Destination Address */
+ bl board_init_r
+
+ /* Problems accessing "end" in C, so do it here */
+ .globl get_endaddr
+get_endaddr:
+ lwz r3,GOT(_end)
+ blr
+
+ /*
+ * Copy exception vector code to low memory
+ *
+ * r3: dest_addr
+ * r7: source address, r8: end address, r9: target address
+ */
+ .globl trap_init
+trap_init:
+ lwz r7, GOT(_start)
+ lwz r8, GOT(_end_of_vectors)
+
+ rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
+
+ cmplw 0, r7, r8
+ bgelr /* return if r7>=r8 - just in case */
+
+ mflr r4 /* save link register */
+1:
+ lwz r0, 0(r7)
+ stw r0, 0(r9)
+ addi r7, r7, 4
+ addi r9, r9, 4
+ cmplw 0, r7, r8
+ bne 1b
+
+ /*
+ * relocate `hdlr' and `int_return' entries
+ */
+ li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+ li r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 2b
+
+ li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+ bl trap_reloc
+
+ li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+ bl trap_reloc
+
+ li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+ li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+3:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 3b
+
+ mtlr r4 /* restore link register */
+ blr
+
+ /*
+ * Function: relocate entries for one exception vector
+ */
+trap_reloc:
+ lwz r0, 0(r7) /* hdlr ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 0(r7)
+
+ lwz r0, 4(r7) /* int_return ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 4(r7)
+
+ blr
--- /dev/null
+Analyzing: d:\ppcboot\mpc8240\start1.o
+Header idenfication: 0x7f, ELF, 32 bit MSB v1
+ type: 1, machine: 20
+ version: 00000001, entry: 00000000, phoff: 00000000
+ shoff: 00003410, flags: 00000000, ehsize: 52, phentsize: 0
+ phnum: 0, shentsize: 40, shnum: 10, shstrndx: 7
+
+
+==> .shstrtab
+ [ 1] .symtab
+ [ 9] .strtab
+ [ 17] .shstrtab
+ [ 27] .text
+ [ 33] .rela.text
+ [ 44] .data
+ [ 50] .bss
+ [ 55] .got2
+ [ 61] .rela.got2
+
+==> .text [1]: Section Header
+ type: 00000001, flags: 00000006
+ address: 00000000, offset: 00000034, size: 00003374
+ link: 00000000, info: 00000000, alignment: 1, entry size: 0
+
+
+==> .rela.text [2]: Section Header
+ type: 00000004, flags: 00000000
+ address: 00000000, offset: 0000416c, size: 000001a4
+ link: 00000008, info: 00000001, alignment: 4, entry size: 12
+
+
+==> .data [3]: Section Header
+ type: 00000001, flags: 00000003
+ address: 00000000, offset: 000033a8, size: 00000000
+ link: 00000000, info: 00000000, alignment: 1, entry size: 0
+
+
+==> .bss [4]: Section Header
+ type: 00000008, flags: 00000003
+ address: 00000000, offset: 000033a8, size: 00000000
+ link: 00000000, info: 00000000, alignment: 1, entry size: 0
+
+
+==> .got2 [5]: Section Header
+ type: 00000001, flags: 00000003
+ address: 00000000, offset: 000033a8, size: 00000020
+ link: 00000000, info: 00000000, alignment: 1, entry size: 0
+
+
+==> .rela.got2 [6]: Section Header
+ type: 00000004, flags: 00000000
+ address: 00000000, offset: 00004310, size: 00000060
+ link: 00000008, info: 00000005, alignment: 4, entry size: 12
+
+
+==> .shstrtab [7]: Section Header
+ type: 00000003, flags: 00000000
+ address: 00000000, offset: 000033c8, size: 00000048
+ link: 00000000, info: 00000000, alignment: 1, entry size: 0
+
+
+==> .symtab [8]: Section Header
+ type: 00000002, flags: 00000000
+ address: 00000000, offset: 000035a0, size: 00000680
+ link: 00000009, info: 0000004a, alignment: 4, entry size: 16
+
+
+==> .strtab [9]: Section Header
+ type: 00000003, flags: 00000000
+ address: 00000000, offset: 00003c20, size: 00000549
+ link: 00000000, info: 00000000, alignment: 1, entry size: 0
+
+
+==> .strtab
+ [ 1] start.S
+ [ 9] /cygdrive/d/ppcboot/include/asm/mmu.h
+ [ 47] /cygdrive/d/ppcboot/include/linux/config.h
+ [ 90] /cygdrive/d/ppcboot/include/asm/cache.h
+ [ 130] /cygdrive/d/ppcboot/include/asm/processor.h
+ [ 174] /cygdrive/d/ppcboot/include/asm/types.h
+ [ 214] /cygdrive/d/ppcboot/include/asm/ptrace.h
+ [ 255] /cygdrive/d/ppcboot/include/ppc_defs.h
+ [ 294] /cygdrive/d/ppcboot/include/ppc_asm.tmpl
+ [ 335] /cygdrive/d/ppcboot/include/version.h
+ [ 373] /cygdrive/d/ppcboot/include/mpc8240.h
+ [ 411] /cygdrive/d/ppcboot/include/config.h
+ [ 448] /cygdrive/d/ppcboot/include/config_Sandpoint8240.h
+ [ 499] boot_cold
+ [ 509] boot_warm
+ [ 519] in_flash
+ [ 528] MachineCheck
+ [ 541] int_return
+ [ 552] DataStorage
+ [ 564] InstStorage
+ [ 576] ExtInterrupt
+ [ 589] Alignment
+ [ 599] ProgramCheck
+ [ 612] FPUnavailable
+ [ 626] Decrementer
+ [ 638] Trap_0a
+ [ 646] Trap_0b
+ [ 654] SystemCall
+ [ 665] SingleStep
+ [ 676] Trap_0e
+ [ 684] Trap_0f
+ [ 692] InstructionTransMiss
+ [ 713] DataLoadTransMiss
+ [ 731] DataStoreTransMiss
+ [ 750] InstructionBreakpoint
+ [ 772] SysManageInt
+ [ 785] Reserved5
+ [ 795] Reserved6
+ [ 805] Reserved7
+ [ 815] Reserved8
+ [ 825] Reserved9
+ [ 835] ReservedA
+ [ 845] ReservedB
+ [ 855] ReservedC
+ [ 865] ReservedD
+ [ 875] ReservedE
+ [ 885] ReservedF
+ [ 895] RunModeTrace
+ [ 908] NotMax
+ [ 915] clear_bss
+ [ 925] trap_reloc
+ [ 936] _GOT2_TABLE_
+ [ 949] _FIXUP_TABLE_
+ [ 963] _start
+ [ 970] _start_of_vectors
+ [ 988] _end_of_vectors
+ [ 1004] transfer_to_handler
+ [ 1024] _end
+ [ 1029] version_string
+ [ 1044] _start_warm
+ [ 1056] cpu_init_f
+ [ 1067] board_init_f
+ [ 1080] MachineCheckException
+ [ 1102] UnknownException
+ [ 1119] external_interrupt
+ [ 1138] AlignmentException
+ [ 1157] ProgramCheckException
+ [ 1179] timer_interrupt
+ [ 1195] icache_enable
+ [ 1209] icache_disable
+ [ 1224] icache_status
+ [ 1238] dcache_enable
+ [ 1252] dcache_disable
+ [ 1267] dcache_status
+ [ 1281] dc_read
+ [ 1289] get_pvr
+ [ 1297] udelay
+ [ 1304] relocate_code
+ [ 1318] board_init_r
+ [ 1331] get_endaddr
+ [ 1343] trap_init
+
+==> .symtab
+ entry spndx value size bind type other shndx name
+ [ 0] 0 00000000 0 LOC NULL 0 UND
+ [ 1] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 2] 9 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/mmu.h
+ [ 3] 47 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/linux/config.h
+ [ 4] 9 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/mmu.h
+ [ 5] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 6] 90 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/cache.h
+ [ 7] 130 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/processor.h
+ [ 8] 174 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/types.h
+ [ 9] 130 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/processor.h
+ [ 10] 214 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/ptrace.h
+ [ 11] 47 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/linux/config.h
+ [ 12] 214 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/ptrace.h
+ [ 13] 130 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/processor.h
+ [ 14] 47 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/linux/config.h
+ [ 15] 130 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/processor.h
+ [ 16] 90 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/cache.h
+ [ 17] 47 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/linux/config.h
+ [ 18] 90 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/asm/cache.h
+ [ 19] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 20] 255 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/ppc_defs.h
+ [ 21] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 22] 294 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/ppc_asm.tmpl
+ [ 23] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 24] 335 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/version.h
+ [ 25] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 26] 373 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/mpc8240.h
+ [ 27] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 28] 411 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/config.h
+ [ 29] 448 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/config_Sandpoint8240.h
+ [ 30] 411 00000000 0 LOC FILE 0 ABS /cygdrive/d/ppcboot/include/config.h
+ [ 31] 1 00000000 0 LOC FILE 0 ABS start.S
+ [ 32] 0 00000000 0 LOC SECT 0 .text .text
+ [ 33] 0 00000000 0 LOC SECT 0 .data .data
+ [ 34] 0 00000000 0 LOC SECT 0 .bss .bss
+ [ 35] 0 00000000 0 LOC SECT 0 .got2 .got2
+ [ 36] 499 00000118 0 LOC NULL 0 .text boot_cold
+ [ 37] 509 00000118 0 LOC NULL 0 .text boot_warm
+ [ 38] 519 00000148 0 LOC NULL 0 .text in_flash
+ [ 39] 528 00000200 0 LOC NULL 0 .text MachineCheck
+ [ 40] 541 0000309c 0 LOC NULL 0 .text int_return
+ [ 41] 552 00000300 0 LOC NULL 0 .text DataStorage
+ [ 42] 564 00000400 0 LOC NULL 0 .text InstStorage
+ [ 43] 576 00000500 0 LOC NULL 0 .text ExtInterrupt
+ [ 44] 589 00000600 0 LOC NULL 0 .text Alignment
+ [ 45] 599 00000700 0 LOC NULL 0 .text ProgramCheck
+ [ 46] 612 00000800 0 LOC NULL 0 .text FPUnavailable
+ [ 47] 626 00000900 0 LOC NULL 0 .text Decrementer
+ [ 48] 638 00000a00 0 LOC NULL 0 .text Trap_0a
+ [ 49] 646 00000b00 0 LOC NULL 0 .text Trap_0b
+ [ 50] 654 00000c00 0 LOC NULL 0 .text SystemCall
+ [ 51] 665 00000d00 0 LOC NULL 0 .text SingleStep
+ [ 52] 676 00000e00 0 LOC NULL 0 .text Trap_0e
+ [ 53] 684 00000f00 0 LOC NULL 0 .text Trap_0f
+ [ 54] 692 00001000 0 LOC NULL 0 .text InstructionTransMiss
+ [ 55] 713 00001100 0 LOC NULL 0 .text DataLoadTransMiss
+ [ 56] 731 00001200 0 LOC NULL 0 .text DataStoreTransMiss
+ [ 57] 750 00001300 0 LOC NULL 0 .text InstructionBreakpoint
+ [ 58] 772 00001400 0 LOC NULL 0 .text SysManageInt
+ [ 59] 785 00001500 0 LOC NULL 0 .text Reserved5
+ [ 60] 795 00001600 0 LOC NULL 0 .text Reserved6
+ [ 61] 805 00001700 0 LOC NULL 0 .text Reserved7
+ [ 62] 815 00001800 0 LOC NULL 0 .text Reserved8
+ [ 63] 825 00001900 0 LOC NULL 0 .text Reserved9
+ [ 64] 835 00001a00 0 LOC NULL 0 .text ReservedA
+ [ 65] 845 00001b00 0 LOC NULL 0 .text ReservedB
+ [ 66] 855 00001c00 0 LOC NULL 0 .text ReservedC
+ [ 67] 865 00001d00 0 LOC NULL 0 .text ReservedD
+ [ 68] 875 00001e00 0 LOC NULL 0 .text ReservedE
+ [ 69] 885 00001f00 0 LOC NULL 0 .text ReservedF
+ [ 70] 895 00002000 0 LOC NULL 0 .text RunModeTrace
+ [ 71] 908 000031f8 0 LOC NULL 0 .text NotMax
+ [ 72] 915 000032a4 0 LOC NULL 0 .text clear_bss
+ [ 73] 925 00003354 0 LOC NULL 0 .text trap_reloc
+ [ 74] 936 00000000 0 GLOB NULL 0 UND _GOT2_TABLE_
+ [ 75] 949 00000000 0 GLOB NULL 0 UND _FIXUP_TABLE_
+ [ 76] 963 00000100 0 GLOB NULL 0 .text _start
+ [ 77] 970 0000016c 0 GLOB NULL 0 .text _start_of_vectors
+ [ 78] 988 00002090 0 GLOB NULL 0 .text _end_of_vectors
+ [ 79] 1004 00003000 0 GLOB NULL 0 .text transfer_to_handler
+ [ 80] 1024 00000000 0 GLOB NULL 0 UND _end
+ [ 81] 1029 00000004 0 GLOB NULL 0 .text version_string
+ [ 82] 1044 00000110 0 GLOB NULL 0 .text _start_warm
+ [ 83] 1056 00000000 0 GLOB NULL 0 UND cpu_init_f
+ [ 84] 1067 00000000 0 GLOB NULL 0 UND board_init_f
+ [ 85] 1080 00000000 0 GLOB NULL 0 UND MachineCheckException
+ [ 86] 1102 00000000 0 GLOB NULL 0 UND UnknownException
+ [ 87] 1119 00000000 0 GLOB NULL 0 UND external_interrupt
+ [ 88] 1138 00000000 0 GLOB NULL 0 UND AlignmentException
+ [ 89] 1157 00000000 0 GLOB NULL 0 UND ProgramCheckException
+ [ 90] 1179 00000000 0 GLOB NULL 0 UND timer_interrupt
+ [ 91] 1195 0000317c 0 GLOB NULL 0 .text icache_enable
+ [ 92] 1209 000031a8 0 GLOB NULL 0 .text icache_disable
+ [ 93] 1224 000031cc 0 GLOB NULL 0 .text icache_status
+ [ 94] 1238 000031dc 0 GLOB NULL 0 .text dcache_enable
+ [ 95] 1252 0000321c 0 GLOB NULL 0 .text dcache_disable
+ [ 96] 1267 00003240 0 GLOB NULL 0 .text dcache_status
+ [ 97] 1281 00003250 0 GLOB NULL 0 .text dc_read
+ [ 98] 1289 00003254 0 GLOB NULL 0 .text get_pvr
+ [ 99] 1297 0000325c 0 GLOB NULL 0 .text udelay
+ [ 100] 1304 000032a4 0 GLOB NULL 0 .text relocate_code
+ [ 101] 1318 00000000 0 GLOB NULL 0 UND board_init_r
+ [ 102] 1331 000032d4 0 GLOB NULL 0 .text get_endaddr
+ [ 103] 1343 000032dc 0 GLOB NULL 0 .text trap_init
+
+==> .rela.text
+ entry offset addend type name(symbol id)
+ [ 0] 00000160 00000000 10 cpu_init_f(83)
+ [ 1] 00000168 00000000 10 board_init_f(84)
+ [ 2] 00000288 00000288 26 MachineCheckException(85)
+ [ 3] 00000388 00000388 26 UnknownException(86)
+ [ 4] 00000488 00000488 26 UnknownException(86)
+ [ 5] 00000588 00000588 26 external_interrupt(87)
+ [ 6] 0000069c 0000069c 26 AlignmentException(88)
+ [ 7] 0000078c 0000078c 26 ProgramCheckException(89)
+ [ 8] 00000888 00000888 26 UnknownException(86)
+ [ 9] 00000988 00000988 26 timer_interrupt(90)
+ [ 10] 00000a88 00000a88 26 UnknownException(86)
+ [ 11] 00000b88 00000b88 26 UnknownException(86)
+ [ 12] 00000c88 00000c88 26 UnknownException(86)
+ [ 13] 00000d88 00000d88 26 UnknownException(86)
+ [ 14] 00000e88 00000e88 26 UnknownException(86)
+ [ 15] 00000f88 00000f88 26 UnknownException(86)
+ [ 16] 00001088 00001088 26 UnknownException(86)
+ [ 17] 00001188 00001188 26 UnknownException(86)
+ [ 18] 00001288 00001288 26 UnknownException(86)
+ [ 19] 00001388 00001388 26 UnknownException(86)
+ [ 20] 00001488 00001488 26 UnknownException(86)
+ [ 21] 00001588 00001588 26 UnknownException(86)
+ [ 22] 00001688 00001688 26 UnknownException(86)
+ [ 23] 00001788 00001788 26 UnknownException(86)
+ [ 24] 00001888 00001888 26 UnknownException(86)
+ [ 25] 00001988 00001988 26 UnknownException(86)
+ [ 26] 00001a88 00001a88 26 UnknownException(86)
+ [ 27] 00001b88 00001b88 26 UnknownException(86)
+ [ 28] 00001c88 00001c88 26 UnknownException(86)
+ [ 29] 00001d88 00001d88 26 UnknownException(86)
+ [ 30] 00001e88 00001e88 26 UnknownException(86)
+ [ 31] 00001f88 00001f88 26 UnknownException(86)
+ [ 32] 00002088 00002088 26 UnknownException(86)
+ [ 33] 000032d0 00000000 10 board_init_r(101)
+ [ 34] 00003370 0000b21c 26 .got2(35)
+
+==> .text
+00000000: 27051956 dc.l 0x27051956 ; Invalid opcode ''..V'
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="version_string" Size=0
+00000004: 70706362 andi. r16,r3,0x6362
+00000008: 6F6F7420 xoris r15,r27,0x7420
+0000000C: 302E352E addic rsp,r14,13614
+00000010: 3020284F addic rsp,r0,10319
+00000014: 63742031 ori r20,r27,0x2031
+00000018: 31203230 addic r9,r0,12848
+0000001C: 3030202D addic rsp,r16,8237
+00000020: 2031363A subfic rsp,r17,13882
+00000024: 35353A34 addic. r9,r21,14900
+00000028: 38290000 addi rsp,r9,0
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="_start" Size=0
+00000100: 3AA00001 li r21,1
+00000104: 48000014 b *+20 ; 0x00000118
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="_start_warm" Size=0
+00000110: 3AA00002 li r21,2
+00000114: 48000004 b *+4 ; 0x00000118
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="boot_warm" Size=0
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="boot_cold" Size=0
+00000118: 38601002 li r3,4098
+0000011C: 7C600124 mtmsr r3
+00000120: 7C7B03A6 mtsrr1 r3
+00000124: 7C7422A6 mfspr r3,ECR
+00000128: 3C000000 lis r0,0
+0000012C: 7C6000A6 mfmsr r3
+00000130: 3C80FFFF lis r4,-1
+00000134: 6084FFCF ori r4,r4,0xffcf
+00000138: 7C632038 and r3,r3,r4
+0000013C: 7C600124 mtmsr r3
+00000140: 4C00012C isync
+00000144: 7C0004AC sync
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="in_flash" Size=0
+00000148: 3C20007F lis rsp,127
+0000014C: 6021D000 ori rsp,rsp,0xd000
+00000150: 48000005 bl *+4 ; 0x00000154
+00000154: 7DC802A6 mflr r14
+00000158: 800E321C lwz r0,12828(r14)
+0000015C: 7DC07214 add r14,r0,r14
+00000160: 48000001 bl cpu_init_f
+00000164: 7EA3AB78 mr r3,r21
+00000168: 48000001 bl board_init_f
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="_start_of_vectors" Size=0
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="MachineCheck" Size=0
+00000200: 7E9043A6 mtsprg0 r20
+00000204: 7EB143A6 mtsprg1 r21
+00000208: 7E800026 mfcr r20
+0000020C: 7C350B78 mr r21,rsp
+00000210: 3AB5FF00 subi r21,r21,256
+00000214: 929500A8 stw r20,168(r21)
+00000218: 92D50068 stw r22,104(r21)
+0000021C: 92F5006C stw r23,108(r21)
+00000220: 7E9042A6 mfsprg0 r20
+00000224: 92950060 stw r20,96(r21)
+00000228: 7ED142A6 mfsprg1 r22
+0000022C: 92D50064 stw r22,100(r21)
+00000230: 7E8802A6 mflr r20
+00000234: 929500A0 stw r20,160(r21)
+00000238: 7EC902A6 mfctr r22
+0000023C: 92D5009C stw r22,156(r21)
+00000240: 7E8102A6 mfxer r20
+00000244: 929500A4 stw r20,164(r21)
+00000248: 7EDA02A6 mfsrr0 r22
+0000024C: 7EFB02A6 mfsrr1 r23
+00000250: 90150010 stw r0,16(r21)
+00000254: 90350014 stw rsp,20(r21)
+00000258: 90550018 stw r2,24(r21)
+0000025C: 90350000 stw rsp,0(r21)
+00000260: 7EA1AB78 mr rsp,r21
+00000264: 9075001C stw r3,28(r21)
+00000268: 90950020 stw r4,32(r21)
+0000026C: 90B50024 stw r5,36(r21)
+00000270: 90D50028 stw r6,40(r21)
+00000274: 806E8014 lwz r3,-32748(r14)
+00000278: 7C6803A6 mtlr r3
+0000027C: 38610010 addi r3,rsp,16
+00000280: 3A801002 li r20,4098
+00000284: 4E800021 blrl
+00000288: 00000288 dc.l 0x00000288 ; Invalid opcode '....'
+0000028C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="DataStorage" Size=0
+00000300: 7E9043A6 mtsprg0 r20
+00000304: 7EB143A6 mtsprg1 r21
+00000308: 7E800026 mfcr r20
+0000030C: 7C350B78 mr r21,rsp
+00000310: 3AB5FF00 subi r21,r21,256
+00000314: 929500A8 stw r20,168(r21)
+00000318: 92D50068 stw r22,104(r21)
+0000031C: 92F5006C stw r23,108(r21)
+00000320: 7E9042A6 mfsprg0 r20
+00000324: 92950060 stw r20,96(r21)
+00000328: 7ED142A6 mfsprg1 r22
+0000032C: 92D50064 stw r22,100(r21)
+00000330: 7E8802A6 mflr r20
+00000334: 929500A0 stw r20,160(r21)
+00000338: 7EC902A6 mfctr r22
+0000033C: 92D5009C stw r22,156(r21)
+00000340: 7E8102A6 mfxer r20
+00000344: 929500A4 stw r20,164(r21)
+00000348: 7EDA02A6 mfsrr0 r22
+0000034C: 7EFB02A6 mfsrr1 r23
+00000350: 90150010 stw r0,16(r21)
+00000354: 90350014 stw rsp,20(r21)
+00000358: 90550018 stw r2,24(r21)
+0000035C: 90350000 stw rsp,0(r21)
+00000360: 7EA1AB78 mr rsp,r21
+00000364: 9075001C stw r3,28(r21)
+00000368: 90950020 stw r4,32(r21)
+0000036C: 90B50024 stw r5,36(r21)
+00000370: 90D50028 stw r6,40(r21)
+00000374: 806E8014 lwz r3,-32748(r14)
+00000378: 7C6803A6 mtlr r3
+0000037C: 38610010 addi r3,rsp,16
+00000380: 3A801002 li r20,4098
+00000384: 4E800021 blrl
+00000388: 00000388 dc.l 0x00000388 ; Invalid opcode '....'
+0000038C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="InstStorage" Size=0
+00000400: 7E9043A6 mtsprg0 r20
+00000404: 7EB143A6 mtsprg1 r21
+00000408: 7E800026 mfcr r20
+0000040C: 7C350B78 mr r21,rsp
+00000410: 3AB5FF00 subi r21,r21,256
+00000414: 929500A8 stw r20,168(r21)
+00000418: 92D50068 stw r22,104(r21)
+0000041C: 92F5006C stw r23,108(r21)
+00000420: 7E9042A6 mfsprg0 r20
+00000424: 92950060 stw r20,96(r21)
+00000428: 7ED142A6 mfsprg1 r22
+0000042C: 92D50064 stw r22,100(r21)
+00000430: 7E8802A6 mflr r20
+00000434: 929500A0 stw r20,160(r21)
+00000438: 7EC902A6 mfctr r22
+0000043C: 92D5009C stw r22,156(r21)
+00000440: 7E8102A6 mfxer r20
+00000444: 929500A4 stw r20,164(r21)
+00000448: 7EDA02A6 mfsrr0 r22
+0000044C: 7EFB02A6 mfsrr1 r23
+00000450: 90150010 stw r0,16(r21)
+00000454: 90350014 stw rsp,20(r21)
+00000458: 90550018 stw r2,24(r21)
+0000045C: 90350000 stw rsp,0(r21)
+00000460: 7EA1AB78 mr rsp,r21
+00000464: 9075001C stw r3,28(r21)
+00000468: 90950020 stw r4,32(r21)
+0000046C: 90B50024 stw r5,36(r21)
+00000470: 90D50028 stw r6,40(r21)
+00000474: 806E8014 lwz r3,-32748(r14)
+00000478: 7C6803A6 mtlr r3
+0000047C: 38610010 addi r3,rsp,16
+00000480: 3A801002 li r20,4098
+00000484: 4E800021 blrl
+00000488: 00000488 dc.l 0x00000488 ; Invalid opcode '....'
+0000048C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ExtInterrupt" Size=0
+00000500: 7E9043A6 mtsprg0 r20
+00000504: 7EB143A6 mtsprg1 r21
+00000508: 7E800026 mfcr r20
+0000050C: 7C350B78 mr r21,rsp
+00000510: 3AB5FF00 subi r21,r21,256
+00000514: 929500A8 stw r20,168(r21)
+00000518: 92D50068 stw r22,104(r21)
+0000051C: 92F5006C stw r23,108(r21)
+00000520: 7E9042A6 mfsprg0 r20
+00000524: 92950060 stw r20,96(r21)
+00000528: 7ED142A6 mfsprg1 r22
+0000052C: 92D50064 stw r22,100(r21)
+00000530: 7E8802A6 mflr r20
+00000534: 929500A0 stw r20,160(r21)
+00000538: 7EC902A6 mfctr r22
+0000053C: 92D5009C stw r22,156(r21)
+00000540: 7E8102A6 mfxer r20
+00000544: 929500A4 stw r20,164(r21)
+00000548: 7EDA02A6 mfsrr0 r22
+0000054C: 7EFB02A6 mfsrr1 r23
+00000550: 90150010 stw r0,16(r21)
+00000554: 90350014 stw rsp,20(r21)
+00000558: 90550018 stw r2,24(r21)
+0000055C: 90350000 stw rsp,0(r21)
+00000560: 7EA1AB78 mr rsp,r21
+00000564: 9075001C stw r3,28(r21)
+00000568: 90950020 stw r4,32(r21)
+0000056C: 90B50024 stw r5,36(r21)
+00000570: 90D50028 stw r6,40(r21)
+00000574: 806E8014 lwz r3,-32748(r14)
+00000578: 7C6803A6 mtlr r3
+0000057C: 38610010 addi r3,rsp,16
+00000580: 3A801002 li r20,4098
+00000584: 4E800021 blrl
+00000588: 00000588 dc.l 0x00000588 ; Invalid opcode '....'
+0000058C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Alignment" Size=0
+00000600: 7E9043A6 mtsprg0 r20
+00000604: 7EB143A6 mtsprg1 r21
+00000608: 7E800026 mfcr r20
+0000060C: 7C350B78 mr r21,rsp
+00000610: 3AB5FF00 subi r21,r21,256
+00000614: 929500A8 stw r20,168(r21)
+00000618: 92D50068 stw r22,104(r21)
+0000061C: 92F5006C stw r23,108(r21)
+00000620: 7E9042A6 mfsprg0 r20
+00000624: 92950060 stw r20,96(r21)
+00000628: 7ED142A6 mfsprg1 r22
+0000062C: 92D50064 stw r22,100(r21)
+00000630: 7E8802A6 mflr r20
+00000634: 929500A0 stw r20,160(r21)
+00000638: 7EC902A6 mfctr r22
+0000063C: 92D5009C stw r22,156(r21)
+00000640: 7E8102A6 mfxer r20
+00000644: 929500A4 stw r20,164(r21)
+00000648: 7EDA02A6 mfsrr0 r22
+0000064C: 7EFB02A6 mfsrr1 r23
+00000650: 90150010 stw r0,16(r21)
+00000654: 90350014 stw rsp,20(r21)
+00000658: 90550018 stw r2,24(r21)
+0000065C: 90350000 stw rsp,0(r21)
+00000660: 7EA1AB78 mr rsp,r21
+00000664: 9075001C stw r3,28(r21)
+00000668: 90950020 stw r4,32(r21)
+0000066C: 90B50024 stw r5,36(r21)
+00000670: 90D50028 stw r6,40(r21)
+00000674: 7C9302A6 mfspr r4,DAR
+00000678: 909500B4 stw r4,180(r21)
+0000067C: 7CB202A6 mfspr r5,DSISR
+00000680: 90B500B8 stw r5,184(r21)
+00000684: 38610010 addi r3,rsp,16
+00000688: 3A801002 li r20,4098
+0000068C: 52F40420 rlwimi r20,r23,0,16,16
+00000690: 80CE8014 lwz r6,-32748(r14)
+00000694: 7CC803A6 mtlr r6
+00000698: 4E800021 blrl
+0000069C: 0000069C dc.l 0x0000069c ; Invalid opcode '....'
+000006A0: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ProgramCheck" Size=0
+00000700: 7E9043A6 mtsprg0 r20
+00000704: 7EB143A6 mtsprg1 r21
+00000708: 7E800026 mfcr r20
+0000070C: 7C350B78 mr r21,rsp
+00000710: 3AB5FF00 subi r21,r21,256
+00000714: 929500A8 stw r20,168(r21)
+00000718: 92D50068 stw r22,104(r21)
+0000071C: 92F5006C stw r23,108(r21)
+00000720: 7E9042A6 mfsprg0 r20
+00000724: 92950060 stw r20,96(r21)
+00000728: 7ED142A6 mfsprg1 r22
+0000072C: 92D50064 stw r22,100(r21)
+00000730: 7E8802A6 mflr r20
+00000734: 929500A0 stw r20,160(r21)
+00000738: 7EC902A6 mfctr r22
+0000073C: 92D5009C stw r22,156(r21)
+00000740: 7E8102A6 mfxer r20
+00000744: 929500A4 stw r20,164(r21)
+00000748: 7EDA02A6 mfsrr0 r22
+0000074C: 7EFB02A6 mfsrr1 r23
+00000750: 90150010 stw r0,16(r21)
+00000754: 90350014 stw rsp,20(r21)
+00000758: 90550018 stw r2,24(r21)
+0000075C: 90350000 stw rsp,0(r21)
+00000760: 7EA1AB78 mr rsp,r21
+00000764: 9075001C stw r3,28(r21)
+00000768: 90950020 stw r4,32(r21)
+0000076C: 90B50024 stw r5,36(r21)
+00000770: 90D50028 stw r6,40(r21)
+00000774: 38610010 addi r3,rsp,16
+00000778: 3A801002 li r20,4098
+0000077C: 52F40420 rlwimi r20,r23,0,16,16
+00000780: 80CE8014 lwz r6,-32748(r14)
+00000784: 7CC803A6 mtlr r6
+00000788: 4E800021 blrl
+0000078C: 0000078C dc.l 0x0000078c ; Invalid opcode '....'
+00000790: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="FPUnavailable" Size=0
+00000800: 7E9043A6 mtsprg0 r20
+00000804: 7EB143A6 mtsprg1 r21
+00000808: 7E800026 mfcr r20
+0000080C: 7C350B78 mr r21,rsp
+00000810: 3AB5FF00 subi r21,r21,256
+00000814: 929500A8 stw r20,168(r21)
+00000818: 92D50068 stw r22,104(r21)
+0000081C: 92F5006C stw r23,108(r21)
+00000820: 7E9042A6 mfsprg0 r20
+00000824: 92950060 stw r20,96(r21)
+00000828: 7ED142A6 mfsprg1 r22
+0000082C: 92D50064 stw r22,100(r21)
+00000830: 7E8802A6 mflr r20
+00000834: 929500A0 stw r20,160(r21)
+00000838: 7EC902A6 mfctr r22
+0000083C: 92D5009C stw r22,156(r21)
+00000840: 7E8102A6 mfxer r20
+00000844: 929500A4 stw r20,164(r21)
+00000848: 7EDA02A6 mfsrr0 r22
+0000084C: 7EFB02A6 mfsrr1 r23
+00000850: 90150010 stw r0,16(r21)
+00000854: 90350014 stw rsp,20(r21)
+00000858: 90550018 stw r2,24(r21)
+0000085C: 90350000 stw rsp,0(r21)
+00000860: 7EA1AB78 mr rsp,r21
+00000864: 9075001C stw r3,28(r21)
+00000868: 90950020 stw r4,32(r21)
+0000086C: 90B50024 stw r5,36(r21)
+00000870: 90D50028 stw r6,40(r21)
+00000874: 806E8014 lwz r3,-32748(r14)
+00000878: 7C6803A6 mtlr r3
+0000087C: 38610010 addi r3,rsp,16
+00000880: 3A801002 li r20,4098
+00000884: 4E800021 blrl
+00000888: 00000888 dc.l 0x00000888 ; Invalid opcode '....'
+0000088C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Decrementer" Size=0
+00000900: 7E9043A6 mtsprg0 r20
+00000904: 7EB143A6 mtsprg1 r21
+00000908: 7E800026 mfcr r20
+0000090C: 7C350B78 mr r21,rsp
+00000910: 3AB5FF00 subi r21,r21,256
+00000914: 929500A8 stw r20,168(r21)
+00000918: 92D50068 stw r22,104(r21)
+0000091C: 92F5006C stw r23,108(r21)
+00000920: 7E9042A6 mfsprg0 r20
+00000924: 92950060 stw r20,96(r21)
+00000928: 7ED142A6 mfsprg1 r22
+0000092C: 92D50064 stw r22,100(r21)
+00000930: 7E8802A6 mflr r20
+00000934: 929500A0 stw r20,160(r21)
+00000938: 7EC902A6 mfctr r22
+0000093C: 92D5009C stw r22,156(r21)
+00000940: 7E8102A6 mfxer r20
+00000944: 929500A4 stw r20,164(r21)
+00000948: 7EDA02A6 mfsrr0 r22
+0000094C: 7EFB02A6 mfsrr1 r23
+00000950: 90150010 stw r0,16(r21)
+00000954: 90350014 stw rsp,20(r21)
+00000958: 90550018 stw r2,24(r21)
+0000095C: 90350000 stw rsp,0(r21)
+00000960: 7EA1AB78 mr rsp,r21
+00000964: 9075001C stw r3,28(r21)
+00000968: 90950020 stw r4,32(r21)
+0000096C: 90B50024 stw r5,36(r21)
+00000970: 90D50028 stw r6,40(r21)
+00000974: 806E8014 lwz r3,-32748(r14)
+00000978: 7C6803A6 mtlr r3
+0000097C: 38610010 addi r3,rsp,16
+00000980: 3A801002 li r20,4098
+00000984: 4E800021 blrl
+00000988: 00000988 dc.l 0x00000988 ; Invalid opcode '....'
+0000098C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Trap_0a" Size=0
+00000A00: 7E9043A6 mtsprg0 r20
+00000A04: 7EB143A6 mtsprg1 r21
+00000A08: 7E800026 mfcr r20
+00000A0C: 7C350B78 mr r21,rsp
+00000A10: 3AB5FF00 subi r21,r21,256
+00000A14: 929500A8 stw r20,168(r21)
+00000A18: 92D50068 stw r22,104(r21)
+00000A1C: 92F5006C stw r23,108(r21)
+00000A20: 7E9042A6 mfsprg0 r20
+00000A24: 92950060 stw r20,96(r21)
+00000A28: 7ED142A6 mfsprg1 r22
+00000A2C: 92D50064 stw r22,100(r21)
+00000A30: 7E8802A6 mflr r20
+00000A34: 929500A0 stw r20,160(r21)
+00000A38: 7EC902A6 mfctr r22
+00000A3C: 92D5009C stw r22,156(r21)
+00000A40: 7E8102A6 mfxer r20
+00000A44: 929500A4 stw r20,164(r21)
+00000A48: 7EDA02A6 mfsrr0 r22
+00000A4C: 7EFB02A6 mfsrr1 r23
+00000A50: 90150010 stw r0,16(r21)
+00000A54: 90350014 stw rsp,20(r21)
+00000A58: 90550018 stw r2,24(r21)
+00000A5C: 90350000 stw rsp,0(r21)
+00000A60: 7EA1AB78 mr rsp,r21
+00000A64: 9075001C stw r3,28(r21)
+00000A68: 90950020 stw r4,32(r21)
+00000A6C: 90B50024 stw r5,36(r21)
+00000A70: 90D50028 stw r6,40(r21)
+00000A74: 806E8014 lwz r3,-32748(r14)
+00000A78: 7C6803A6 mtlr r3
+00000A7C: 38610010 addi r3,rsp,16
+00000A80: 3A801002 li r20,4098
+00000A84: 4E800021 blrl
+00000A88: 00000A88 dc.l 0x00000a88 ; Invalid opcode '....'
+00000A8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Trap_0b" Size=0
+00000B00: 7E9043A6 mtsprg0 r20
+00000B04: 7EB143A6 mtsprg1 r21
+00000B08: 7E800026 mfcr r20
+00000B0C: 7C350B78 mr r21,rsp
+00000B10: 3AB5FF00 subi r21,r21,256
+00000B14: 929500A8 stw r20,168(r21)
+00000B18: 92D50068 stw r22,104(r21)
+00000B1C: 92F5006C stw r23,108(r21)
+00000B20: 7E9042A6 mfsprg0 r20
+00000B24: 92950060 stw r20,96(r21)
+00000B28: 7ED142A6 mfsprg1 r22
+00000B2C: 92D50064 stw r22,100(r21)
+00000B30: 7E8802A6 mflr r20
+00000B34: 929500A0 stw r20,160(r21)
+00000B38: 7EC902A6 mfctr r22
+00000B3C: 92D5009C stw r22,156(r21)
+00000B40: 7E8102A6 mfxer r20
+00000B44: 929500A4 stw r20,164(r21)
+00000B48: 7EDA02A6 mfsrr0 r22
+00000B4C: 7EFB02A6 mfsrr1 r23
+00000B50: 90150010 stw r0,16(r21)
+00000B54: 90350014 stw rsp,20(r21)
+00000B58: 90550018 stw r2,24(r21)
+00000B5C: 90350000 stw rsp,0(r21)
+00000B60: 7EA1AB78 mr rsp,r21
+00000B64: 9075001C stw r3,28(r21)
+00000B68: 90950020 stw r4,32(r21)
+00000B6C: 90B50024 stw r5,36(r21)
+00000B70: 90D50028 stw r6,40(r21)
+00000B74: 806E8014 lwz r3,-32748(r14)
+00000B78: 7C6803A6 mtlr r3
+00000B7C: 38610010 addi r3,rsp,16
+00000B80: 3A801002 li r20,4098
+00000B84: 4E800021 blrl
+00000B88: 00000B88 dc.l 0x00000b88 ; Invalid opcode '....'
+00000B8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="SystemCall" Size=0
+00000C00: 7E9043A6 mtsprg0 r20
+00000C04: 7EB143A6 mtsprg1 r21
+00000C08: 7E800026 mfcr r20
+00000C0C: 7C350B78 mr r21,rsp
+00000C10: 3AB5FF00 subi r21,r21,256
+00000C14: 929500A8 stw r20,168(r21)
+00000C18: 92D50068 stw r22,104(r21)
+00000C1C: 92F5006C stw r23,108(r21)
+00000C20: 7E9042A6 mfsprg0 r20
+00000C24: 92950060 stw r20,96(r21)
+00000C28: 7ED142A6 mfsprg1 r22
+00000C2C: 92D50064 stw r22,100(r21)
+00000C30: 7E8802A6 mflr r20
+00000C34: 929500A0 stw r20,160(r21)
+00000C38: 7EC902A6 mfctr r22
+00000C3C: 92D5009C stw r22,156(r21)
+00000C40: 7E8102A6 mfxer r20
+00000C44: 929500A4 stw r20,164(r21)
+00000C48: 7EDA02A6 mfsrr0 r22
+00000C4C: 7EFB02A6 mfsrr1 r23
+00000C50: 90150010 stw r0,16(r21)
+00000C54: 90350014 stw rsp,20(r21)
+00000C58: 90550018 stw r2,24(r21)
+00000C5C: 90350000 stw rsp,0(r21)
+00000C60: 7EA1AB78 mr rsp,r21
+00000C64: 9075001C stw r3,28(r21)
+00000C68: 90950020 stw r4,32(r21)
+00000C6C: 90B50024 stw r5,36(r21)
+00000C70: 90D50028 stw r6,40(r21)
+00000C74: 806E8014 lwz r3,-32748(r14)
+00000C78: 7C6803A6 mtlr r3
+00000C7C: 38610010 addi r3,rsp,16
+00000C80: 3A801002 li r20,4098
+00000C84: 4E800021 blrl
+00000C88: 00000C88 dc.l 0x00000c88 ; Invalid opcode '....'
+00000C8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="SingleStep" Size=0
+00000D00: 7E9043A6 mtsprg0 r20
+00000D04: 7EB143A6 mtsprg1 r21
+00000D08: 7E800026 mfcr r20
+00000D0C: 7C350B78 mr r21,rsp
+00000D10: 3AB5FF00 subi r21,r21,256
+00000D14: 929500A8 stw r20,168(r21)
+00000D18: 92D50068 stw r22,104(r21)
+00000D1C: 92F5006C stw r23,108(r21)
+00000D20: 7E9042A6 mfsprg0 r20
+00000D24: 92950060 stw r20,96(r21)
+00000D28: 7ED142A6 mfsprg1 r22
+00000D2C: 92D50064 stw r22,100(r21)
+00000D30: 7E8802A6 mflr r20
+00000D34: 929500A0 stw r20,160(r21)
+00000D38: 7EC902A6 mfctr r22
+00000D3C: 92D5009C stw r22,156(r21)
+00000D40: 7E8102A6 mfxer r20
+00000D44: 929500A4 stw r20,164(r21)
+00000D48: 7EDA02A6 mfsrr0 r22
+00000D4C: 7EFB02A6 mfsrr1 r23
+00000D50: 90150010 stw r0,16(r21)
+00000D54: 90350014 stw rsp,20(r21)
+00000D58: 90550018 stw r2,24(r21)
+00000D5C: 90350000 stw rsp,0(r21)
+00000D60: 7EA1AB78 mr rsp,r21
+00000D64: 9075001C stw r3,28(r21)
+00000D68: 90950020 stw r4,32(r21)
+00000D6C: 90B50024 stw r5,36(r21)
+00000D70: 90D50028 stw r6,40(r21)
+00000D74: 806E8014 lwz r3,-32748(r14)
+00000D78: 7C6803A6 mtlr r3
+00000D7C: 38610010 addi r3,rsp,16
+00000D80: 3A801002 li r20,4098
+00000D84: 4E800021 blrl
+00000D88: 00000D88 dc.l 0x00000d88 ; Invalid opcode '....'
+00000D8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Trap_0e" Size=0
+00000E00: 7E9043A6 mtsprg0 r20
+00000E04: 7EB143A6 mtsprg1 r21
+00000E08: 7E800026 mfcr r20
+00000E0C: 7C350B78 mr r21,rsp
+00000E10: 3AB5FF00 subi r21,r21,256
+00000E14: 929500A8 stw r20,168(r21)
+00000E18: 92D50068 stw r22,104(r21)
+00000E1C: 92F5006C stw r23,108(r21)
+00000E20: 7E9042A6 mfsprg0 r20
+00000E24: 92950060 stw r20,96(r21)
+00000E28: 7ED142A6 mfsprg1 r22
+00000E2C: 92D50064 stw r22,100(r21)
+00000E30: 7E8802A6 mflr r20
+00000E34: 929500A0 stw r20,160(r21)
+00000E38: 7EC902A6 mfctr r22
+00000E3C: 92D5009C stw r22,156(r21)
+00000E40: 7E8102A6 mfxer r20
+00000E44: 929500A4 stw r20,164(r21)
+00000E48: 7EDA02A6 mfsrr0 r22
+00000E4C: 7EFB02A6 mfsrr1 r23
+00000E50: 90150010 stw r0,16(r21)
+00000E54: 90350014 stw rsp,20(r21)
+00000E58: 90550018 stw r2,24(r21)
+00000E5C: 90350000 stw rsp,0(r21)
+00000E60: 7EA1AB78 mr rsp,r21
+00000E64: 9075001C stw r3,28(r21)
+00000E68: 90950020 stw r4,32(r21)
+00000E6C: 90B50024 stw r5,36(r21)
+00000E70: 90D50028 stw r6,40(r21)
+00000E74: 806E8014 lwz r3,-32748(r14)
+00000E78: 7C6803A6 mtlr r3
+00000E7C: 38610010 addi r3,rsp,16
+00000E80: 3A801002 li r20,4098
+00000E84: 4E800021 blrl
+00000E88: 00000E88 dc.l 0x00000e88 ; Invalid opcode '....'
+00000E8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Trap_0f" Size=0
+00000F00: 7E9043A6 mtsprg0 r20
+00000F04: 7EB143A6 mtsprg1 r21
+00000F08: 7E800026 mfcr r20
+00000F0C: 7C350B78 mr r21,rsp
+00000F10: 3AB5FF00 subi r21,r21,256
+00000F14: 929500A8 stw r20,168(r21)
+00000F18: 92D50068 stw r22,104(r21)
+00000F1C: 92F5006C stw r23,108(r21)
+00000F20: 7E9042A6 mfsprg0 r20
+00000F24: 92950060 stw r20,96(r21)
+00000F28: 7ED142A6 mfsprg1 r22
+00000F2C: 92D50064 stw r22,100(r21)
+00000F30: 7E8802A6 mflr r20
+00000F34: 929500A0 stw r20,160(r21)
+00000F38: 7EC902A6 mfctr r22
+00000F3C: 92D5009C stw r22,156(r21)
+00000F40: 7E8102A6 mfxer r20
+00000F44: 929500A4 stw r20,164(r21)
+00000F48: 7EDA02A6 mfsrr0 r22
+00000F4C: 7EFB02A6 mfsrr1 r23
+00000F50: 90150010 stw r0,16(r21)
+00000F54: 90350014 stw rsp,20(r21)
+00000F58: 90550018 stw r2,24(r21)
+00000F5C: 90350000 stw rsp,0(r21)
+00000F60: 7EA1AB78 mr rsp,r21
+00000F64: 9075001C stw r3,28(r21)
+00000F68: 90950020 stw r4,32(r21)
+00000F6C: 90B50024 stw r5,36(r21)
+00000F70: 90D50028 stw r6,40(r21)
+00000F74: 806E8014 lwz r3,-32748(r14)
+00000F78: 7C6803A6 mtlr r3
+00000F7C: 38610010 addi r3,rsp,16
+00000F80: 3A801002 li r20,4098
+00000F84: 4E800021 blrl
+00000F88: 00000F88 dc.l 0x00000f88 ; Invalid opcode '....'
+00000F8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="InstructionTransMiss" Size=0
+00001000: 7E9043A6 mtsprg0 r20
+00001004: 7EB143A6 mtsprg1 r21
+00001008: 7E800026 mfcr r20
+0000100C: 7C350B78 mr r21,rsp
+00001010: 3AB5FF00 subi r21,r21,256
+00001014: 929500A8 stw r20,168(r21)
+00001018: 92D50068 stw r22,104(r21)
+0000101C: 92F5006C stw r23,108(r21)
+00001020: 7E9042A6 mfsprg0 r20
+00001024: 92950060 stw r20,96(r21)
+00001028: 7ED142A6 mfsprg1 r22
+0000102C: 92D50064 stw r22,100(r21)
+00001030: 7E8802A6 mflr r20
+00001034: 929500A0 stw r20,160(r21)
+00001038: 7EC902A6 mfctr r22
+0000103C: 92D5009C stw r22,156(r21)
+00001040: 7E8102A6 mfxer r20
+00001044: 929500A4 stw r20,164(r21)
+00001048: 7EDA02A6 mfsrr0 r22
+0000104C: 7EFB02A6 mfsrr1 r23
+00001050: 90150010 stw r0,16(r21)
+00001054: 90350014 stw rsp,20(r21)
+00001058: 90550018 stw r2,24(r21)
+0000105C: 90350000 stw rsp,0(r21)
+00001060: 7EA1AB78 mr rsp,r21
+00001064: 9075001C stw r3,28(r21)
+00001068: 90950020 stw r4,32(r21)
+0000106C: 90B50024 stw r5,36(r21)
+00001070: 90D50028 stw r6,40(r21)
+00001074: 806E8014 lwz r3,-32748(r14)
+00001078: 7C6803A6 mtlr r3
+0000107C: 38610010 addi r3,rsp,16
+00001080: 3A801002 li r20,4098
+00001084: 4E800021 blrl
+00001088: 00001088 dc.l 0x00001088 ; Invalid opcode '....'
+0000108C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="DataLoadTransMiss" Size=0
+00001100: 7E9043A6 mtsprg0 r20
+00001104: 7EB143A6 mtsprg1 r21
+00001108: 7E800026 mfcr r20
+0000110C: 7C350B78 mr r21,rsp
+00001110: 3AB5FF00 subi r21,r21,256
+00001114: 929500A8 stw r20,168(r21)
+00001118: 92D50068 stw r22,104(r21)
+0000111C: 92F5006C stw r23,108(r21)
+00001120: 7E9042A6 mfsprg0 r20
+00001124: 92950060 stw r20,96(r21)
+00001128: 7ED142A6 mfsprg1 r22
+0000112C: 92D50064 stw r22,100(r21)
+00001130: 7E8802A6 mflr r20
+00001134: 929500A0 stw r20,160(r21)
+00001138: 7EC902A6 mfctr r22
+0000113C: 92D5009C stw r22,156(r21)
+00001140: 7E8102A6 mfxer r20
+00001144: 929500A4 stw r20,164(r21)
+00001148: 7EDA02A6 mfsrr0 r22
+0000114C: 7EFB02A6 mfsrr1 r23
+00001150: 90150010 stw r0,16(r21)
+00001154: 90350014 stw rsp,20(r21)
+00001158: 90550018 stw r2,24(r21)
+0000115C: 90350000 stw rsp,0(r21)
+00001160: 7EA1AB78 mr rsp,r21
+00001164: 9075001C stw r3,28(r21)
+00001168: 90950020 stw r4,32(r21)
+0000116C: 90B50024 stw r5,36(r21)
+00001170: 90D50028 stw r6,40(r21)
+00001174: 806E8014 lwz r3,-32748(r14)
+00001178: 7C6803A6 mtlr r3
+0000117C: 38610010 addi r3,rsp,16
+00001180: 3A801002 li r20,4098
+00001184: 4E800021 blrl
+00001188: 00001188 dc.l 0x00001188 ; Invalid opcode '....'
+0000118C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="DataStoreTransMiss" Size=0
+00001200: 7E9043A6 mtsprg0 r20
+00001204: 7EB143A6 mtsprg1 r21
+00001208: 7E800026 mfcr r20
+0000120C: 7C350B78 mr r21,rsp
+00001210: 3AB5FF00 subi r21,r21,256
+00001214: 929500A8 stw r20,168(r21)
+00001218: 92D50068 stw r22,104(r21)
+0000121C: 92F5006C stw r23,108(r21)
+00001220: 7E9042A6 mfsprg0 r20
+00001224: 92950060 stw r20,96(r21)
+00001228: 7ED142A6 mfsprg1 r22
+0000122C: 92D50064 stw r22,100(r21)
+00001230: 7E8802A6 mflr r20
+00001234: 929500A0 stw r20,160(r21)
+00001238: 7EC902A6 mfctr r22
+0000123C: 92D5009C stw r22,156(r21)
+00001240: 7E8102A6 mfxer r20
+00001244: 929500A4 stw r20,164(r21)
+00001248: 7EDA02A6 mfsrr0 r22
+0000124C: 7EFB02A6 mfsrr1 r23
+00001250: 90150010 stw r0,16(r21)
+00001254: 90350014 stw rsp,20(r21)
+00001258: 90550018 stw r2,24(r21)
+0000125C: 90350000 stw rsp,0(r21)
+00001260: 7EA1AB78 mr rsp,r21
+00001264: 9075001C stw r3,28(r21)
+00001268: 90950020 stw r4,32(r21)
+0000126C: 90B50024 stw r5,36(r21)
+00001270: 90D50028 stw r6,40(r21)
+00001274: 806E8014 lwz r3,-32748(r14)
+00001278: 7C6803A6 mtlr r3
+0000127C: 38610010 addi r3,rsp,16
+00001280: 3A801002 li r20,4098
+00001284: 4E800021 blrl
+00001288: 00001288 dc.l 0x00001288 ; Invalid opcode '....'
+0000128C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="InstructionBreakpoint" Size=0
+00001300: 7E9043A6 mtsprg0 r20
+00001304: 7EB143A6 mtsprg1 r21
+00001308: 7E800026 mfcr r20
+0000130C: 7C350B78 mr r21,rsp
+00001310: 3AB5FF00 subi r21,r21,256
+00001314: 929500A8 stw r20,168(r21)
+00001318: 92D50068 stw r22,104(r21)
+0000131C: 92F5006C stw r23,108(r21)
+00001320: 7E9042A6 mfsprg0 r20
+00001324: 92950060 stw r20,96(r21)
+00001328: 7ED142A6 mfsprg1 r22
+0000132C: 92D50064 stw r22,100(r21)
+00001330: 7E8802A6 mflr r20
+00001334: 929500A0 stw r20,160(r21)
+00001338: 7EC902A6 mfctr r22
+0000133C: 92D5009C stw r22,156(r21)
+00001340: 7E8102A6 mfxer r20
+00001344: 929500A4 stw r20,164(r21)
+00001348: 7EDA02A6 mfsrr0 r22
+0000134C: 7EFB02A6 mfsrr1 r23
+00001350: 90150010 stw r0,16(r21)
+00001354: 90350014 stw rsp,20(r21)
+00001358: 90550018 stw r2,24(r21)
+0000135C: 90350000 stw rsp,0(r21)
+00001360: 7EA1AB78 mr rsp,r21
+00001364: 9075001C stw r3,28(r21)
+00001368: 90950020 stw r4,32(r21)
+0000136C: 90B50024 stw r5,36(r21)
+00001370: 90D50028 stw r6,40(r21)
+00001374: 806E8014 lwz r3,-32748(r14)
+00001378: 7C6803A6 mtlr r3
+0000137C: 38610010 addi r3,rsp,16
+00001380: 3A801002 li r20,4098
+00001384: 4E800021 blrl
+00001388: 00001388 dc.l 0x00001388 ; Invalid opcode '....'
+0000138C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="SysManageInt" Size=0
+00001400: 7E9043A6 mtsprg0 r20
+00001404: 7EB143A6 mtsprg1 r21
+00001408: 7E800026 mfcr r20
+0000140C: 7C350B78 mr r21,rsp
+00001410: 3AB5FF00 subi r21,r21,256
+00001414: 929500A8 stw r20,168(r21)
+00001418: 92D50068 stw r22,104(r21)
+0000141C: 92F5006C stw r23,108(r21)
+00001420: 7E9042A6 mfsprg0 r20
+00001424: 92950060 stw r20,96(r21)
+00001428: 7ED142A6 mfsprg1 r22
+0000142C: 92D50064 stw r22,100(r21)
+00001430: 7E8802A6 mflr r20
+00001434: 929500A0 stw r20,160(r21)
+00001438: 7EC902A6 mfctr r22
+0000143C: 92D5009C stw r22,156(r21)
+00001440: 7E8102A6 mfxer r20
+00001444: 929500A4 stw r20,164(r21)
+00001448: 7EDA02A6 mfsrr0 r22
+0000144C: 7EFB02A6 mfsrr1 r23
+00001450: 90150010 stw r0,16(r21)
+00001454: 90350014 stw rsp,20(r21)
+00001458: 90550018 stw r2,24(r21)
+0000145C: 90350000 stw rsp,0(r21)
+00001460: 7EA1AB78 mr rsp,r21
+00001464: 9075001C stw r3,28(r21)
+00001468: 90950020 stw r4,32(r21)
+0000146C: 90B50024 stw r5,36(r21)
+00001470: 90D50028 stw r6,40(r21)
+00001474: 806E8014 lwz r3,-32748(r14)
+00001478: 7C6803A6 mtlr r3
+0000147C: 38610010 addi r3,rsp,16
+00001480: 3A801002 li r20,4098
+00001484: 4E800021 blrl
+00001488: 00001488 dc.l 0x00001488 ; Invalid opcode '....'
+0000148C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Reserved5" Size=0
+00001500: 7E9043A6 mtsprg0 r20
+00001504: 7EB143A6 mtsprg1 r21
+00001508: 7E800026 mfcr r20
+0000150C: 7C350B78 mr r21,rsp
+00001510: 3AB5FF00 subi r21,r21,256
+00001514: 929500A8 stw r20,168(r21)
+00001518: 92D50068 stw r22,104(r21)
+0000151C: 92F5006C stw r23,108(r21)
+00001520: 7E9042A6 mfsprg0 r20
+00001524: 92950060 stw r20,96(r21)
+00001528: 7ED142A6 mfsprg1 r22
+0000152C: 92D50064 stw r22,100(r21)
+00001530: 7E8802A6 mflr r20
+00001534: 929500A0 stw r20,160(r21)
+00001538: 7EC902A6 mfctr r22
+0000153C: 92D5009C stw r22,156(r21)
+00001540: 7E8102A6 mfxer r20
+00001544: 929500A4 stw r20,164(r21)
+00001548: 7EDA02A6 mfsrr0 r22
+0000154C: 7EFB02A6 mfsrr1 r23
+00001550: 90150010 stw r0,16(r21)
+00001554: 90350014 stw rsp,20(r21)
+00001558: 90550018 stw r2,24(r21)
+0000155C: 90350000 stw rsp,0(r21)
+00001560: 7EA1AB78 mr rsp,r21
+00001564: 9075001C stw r3,28(r21)
+00001568: 90950020 stw r4,32(r21)
+0000156C: 90B50024 stw r5,36(r21)
+00001570: 90D50028 stw r6,40(r21)
+00001574: 806E8014 lwz r3,-32748(r14)
+00001578: 7C6803A6 mtlr r3
+0000157C: 38610010 addi r3,rsp,16
+00001580: 3A801002 li r20,4098
+00001584: 4E800021 blrl
+00001588: 00001588 dc.l 0x00001588 ; Invalid opcode '....'
+0000158C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Reserved6" Size=0
+00001600: 7E9043A6 mtsprg0 r20
+00001604: 7EB143A6 mtsprg1 r21
+00001608: 7E800026 mfcr r20
+0000160C: 7C350B78 mr r21,rsp
+00001610: 3AB5FF00 subi r21,r21,256
+00001614: 929500A8 stw r20,168(r21)
+00001618: 92D50068 stw r22,104(r21)
+0000161C: 92F5006C stw r23,108(r21)
+00001620: 7E9042A6 mfsprg0 r20
+00001624: 92950060 stw r20,96(r21)
+00001628: 7ED142A6 mfsprg1 r22
+0000162C: 92D50064 stw r22,100(r21)
+00001630: 7E8802A6 mflr r20
+00001634: 929500A0 stw r20,160(r21)
+00001638: 7EC902A6 mfctr r22
+0000163C: 92D5009C stw r22,156(r21)
+00001640: 7E8102A6 mfxer r20
+00001644: 929500A4 stw r20,164(r21)
+00001648: 7EDA02A6 mfsrr0 r22
+0000164C: 7EFB02A6 mfsrr1 r23
+00001650: 90150010 stw r0,16(r21)
+00001654: 90350014 stw rsp,20(r21)
+00001658: 90550018 stw r2,24(r21)
+0000165C: 90350000 stw rsp,0(r21)
+00001660: 7EA1AB78 mr rsp,r21
+00001664: 9075001C stw r3,28(r21)
+00001668: 90950020 stw r4,32(r21)
+0000166C: 90B50024 stw r5,36(r21)
+00001670: 90D50028 stw r6,40(r21)
+00001674: 806E8014 lwz r3,-32748(r14)
+00001678: 7C6803A6 mtlr r3
+0000167C: 38610010 addi r3,rsp,16
+00001680: 3A801002 li r20,4098
+00001684: 4E800021 blrl
+00001688: 00001688 dc.l 0x00001688 ; Invalid opcode '....'
+0000168C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Reserved7" Size=0
+00001700: 7E9043A6 mtsprg0 r20
+00001704: 7EB143A6 mtsprg1 r21
+00001708: 7E800026 mfcr r20
+0000170C: 7C350B78 mr r21,rsp
+00001710: 3AB5FF00 subi r21,r21,256
+00001714: 929500A8 stw r20,168(r21)
+00001718: 92D50068 stw r22,104(r21)
+0000171C: 92F5006C stw r23,108(r21)
+00001720: 7E9042A6 mfsprg0 r20
+00001724: 92950060 stw r20,96(r21)
+00001728: 7ED142A6 mfsprg1 r22
+0000172C: 92D50064 stw r22,100(r21)
+00001730: 7E8802A6 mflr r20
+00001734: 929500A0 stw r20,160(r21)
+00001738: 7EC902A6 mfctr r22
+0000173C: 92D5009C stw r22,156(r21)
+00001740: 7E8102A6 mfxer r20
+00001744: 929500A4 stw r20,164(r21)
+00001748: 7EDA02A6 mfsrr0 r22
+0000174C: 7EFB02A6 mfsrr1 r23
+00001750: 90150010 stw r0,16(r21)
+00001754: 90350014 stw rsp,20(r21)
+00001758: 90550018 stw r2,24(r21)
+0000175C: 90350000 stw rsp,0(r21)
+00001760: 7EA1AB78 mr rsp,r21
+00001764: 9075001C stw r3,28(r21)
+00001768: 90950020 stw r4,32(r21)
+0000176C: 90B50024 stw r5,36(r21)
+00001770: 90D50028 stw r6,40(r21)
+00001774: 806E8014 lwz r3,-32748(r14)
+00001778: 7C6803A6 mtlr r3
+0000177C: 38610010 addi r3,rsp,16
+00001780: 3A801002 li r20,4098
+00001784: 4E800021 blrl
+00001788: 00001788 dc.l 0x00001788 ; Invalid opcode '....'
+0000178C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Reserved8" Size=0
+00001800: 7E9043A6 mtsprg0 r20
+00001804: 7EB143A6 mtsprg1 r21
+00001808: 7E800026 mfcr r20
+0000180C: 7C350B78 mr r21,rsp
+00001810: 3AB5FF00 subi r21,r21,256
+00001814: 929500A8 stw r20,168(r21)
+00001818: 92D50068 stw r22,104(r21)
+0000181C: 92F5006C stw r23,108(r21)
+00001820: 7E9042A6 mfsprg0 r20
+00001824: 92950060 stw r20,96(r21)
+00001828: 7ED142A6 mfsprg1 r22
+0000182C: 92D50064 stw r22,100(r21)
+00001830: 7E8802A6 mflr r20
+00001834: 929500A0 stw r20,160(r21)
+00001838: 7EC902A6 mfctr r22
+0000183C: 92D5009C stw r22,156(r21)
+00001840: 7E8102A6 mfxer r20
+00001844: 929500A4 stw r20,164(r21)
+00001848: 7EDA02A6 mfsrr0 r22
+0000184C: 7EFB02A6 mfsrr1 r23
+00001850: 90150010 stw r0,16(r21)
+00001854: 90350014 stw rsp,20(r21)
+00001858: 90550018 stw r2,24(r21)
+0000185C: 90350000 stw rsp,0(r21)
+00001860: 7EA1AB78 mr rsp,r21
+00001864: 9075001C stw r3,28(r21)
+00001868: 90950020 stw r4,32(r21)
+0000186C: 90B50024 stw r5,36(r21)
+00001870: 90D50028 stw r6,40(r21)
+00001874: 806E8014 lwz r3,-32748(r14)
+00001878: 7C6803A6 mtlr r3
+0000187C: 38610010 addi r3,rsp,16
+00001880: 3A801002 li r20,4098
+00001884: 4E800021 blrl
+00001888: 00001888 dc.l 0x00001888 ; Invalid opcode '....'
+0000188C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="Reserved9" Size=0
+00001900: 7E9043A6 mtsprg0 r20
+00001904: 7EB143A6 mtsprg1 r21
+00001908: 7E800026 mfcr r20
+0000190C: 7C350B78 mr r21,rsp
+00001910: 3AB5FF00 subi r21,r21,256
+00001914: 929500A8 stw r20,168(r21)
+00001918: 92D50068 stw r22,104(r21)
+0000191C: 92F5006C stw r23,108(r21)
+00001920: 7E9042A6 mfsprg0 r20
+00001924: 92950060 stw r20,96(r21)
+00001928: 7ED142A6 mfsprg1 r22
+0000192C: 92D50064 stw r22,100(r21)
+00001930: 7E8802A6 mflr r20
+00001934: 929500A0 stw r20,160(r21)
+00001938: 7EC902A6 mfctr r22
+0000193C: 92D5009C stw r22,156(r21)
+00001940: 7E8102A6 mfxer r20
+00001944: 929500A4 stw r20,164(r21)
+00001948: 7EDA02A6 mfsrr0 r22
+0000194C: 7EFB02A6 mfsrr1 r23
+00001950: 90150010 stw r0,16(r21)
+00001954: 90350014 stw rsp,20(r21)
+00001958: 90550018 stw r2,24(r21)
+0000195C: 90350000 stw rsp,0(r21)
+00001960: 7EA1AB78 mr rsp,r21
+00001964: 9075001C stw r3,28(r21)
+00001968: 90950020 stw r4,32(r21)
+0000196C: 90B50024 stw r5,36(r21)
+00001970: 90D50028 stw r6,40(r21)
+00001974: 806E8014 lwz r3,-32748(r14)
+00001978: 7C6803A6 mtlr r3
+0000197C: 38610010 addi r3,rsp,16
+00001980: 3A801002 li r20,4098
+00001984: 4E800021 blrl
+00001988: 00001988 dc.l 0x00001988 ; Invalid opcode '....'
+0000198C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ReservedA" Size=0
+00001A00: 7E9043A6 mtsprg0 r20
+00001A04: 7EB143A6 mtsprg1 r21
+00001A08: 7E800026 mfcr r20
+00001A0C: 7C350B78 mr r21,rsp
+00001A10: 3AB5FF00 subi r21,r21,256
+00001A14: 929500A8 stw r20,168(r21)
+00001A18: 92D50068 stw r22,104(r21)
+00001A1C: 92F5006C stw r23,108(r21)
+00001A20: 7E9042A6 mfsprg0 r20
+00001A24: 92950060 stw r20,96(r21)
+00001A28: 7ED142A6 mfsprg1 r22
+00001A2C: 92D50064 stw r22,100(r21)
+00001A30: 7E8802A6 mflr r20
+00001A34: 929500A0 stw r20,160(r21)
+00001A38: 7EC902A6 mfctr r22
+00001A3C: 92D5009C stw r22,156(r21)
+00001A40: 7E8102A6 mfxer r20
+00001A44: 929500A4 stw r20,164(r21)
+00001A48: 7EDA02A6 mfsrr0 r22
+00001A4C: 7EFB02A6 mfsrr1 r23
+00001A50: 90150010 stw r0,16(r21)
+00001A54: 90350014 stw rsp,20(r21)
+00001A58: 90550018 stw r2,24(r21)
+00001A5C: 90350000 stw rsp,0(r21)
+00001A60: 7EA1AB78 mr rsp,r21
+00001A64: 9075001C stw r3,28(r21)
+00001A68: 90950020 stw r4,32(r21)
+00001A6C: 90B50024 stw r5,36(r21)
+00001A70: 90D50028 stw r6,40(r21)
+00001A74: 806E8014 lwz r3,-32748(r14)
+00001A78: 7C6803A6 mtlr r3
+00001A7C: 38610010 addi r3,rsp,16
+00001A80: 3A801002 li r20,4098
+00001A84: 4E800021 blrl
+00001A88: 00001A88 dc.l 0x00001a88 ; Invalid opcode '....'
+00001A8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ReservedB" Size=0
+00001B00: 7E9043A6 mtsprg0 r20
+00001B04: 7EB143A6 mtsprg1 r21
+00001B08: 7E800026 mfcr r20
+00001B0C: 7C350B78 mr r21,rsp
+00001B10: 3AB5FF00 subi r21,r21,256
+00001B14: 929500A8 stw r20,168(r21)
+00001B18: 92D50068 stw r22,104(r21)
+00001B1C: 92F5006C stw r23,108(r21)
+00001B20: 7E9042A6 mfsprg0 r20
+00001B24: 92950060 stw r20,96(r21)
+00001B28: 7ED142A6 mfsprg1 r22
+00001B2C: 92D50064 stw r22,100(r21)
+00001B30: 7E8802A6 mflr r20
+00001B34: 929500A0 stw r20,160(r21)
+00001B38: 7EC902A6 mfctr r22
+00001B3C: 92D5009C stw r22,156(r21)
+00001B40: 7E8102A6 mfxer r20
+00001B44: 929500A4 stw r20,164(r21)
+00001B48: 7EDA02A6 mfsrr0 r22
+00001B4C: 7EFB02A6 mfsrr1 r23
+00001B50: 90150010 stw r0,16(r21)
+00001B54: 90350014 stw rsp,20(r21)
+00001B58: 90550018 stw r2,24(r21)
+00001B5C: 90350000 stw rsp,0(r21)
+00001B60: 7EA1AB78 mr rsp,r21
+00001B64: 9075001C stw r3,28(r21)
+00001B68: 90950020 stw r4,32(r21)
+00001B6C: 90B50024 stw r5,36(r21)
+00001B70: 90D50028 stw r6,40(r21)
+00001B74: 806E8014 lwz r3,-32748(r14)
+00001B78: 7C6803A6 mtlr r3
+00001B7C: 38610010 addi r3,rsp,16
+00001B80: 3A801002 li r20,4098
+00001B84: 4E800021 blrl
+00001B88: 00001B88 dc.l 0x00001b88 ; Invalid opcode '....'
+00001B8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ReservedC" Size=0
+00001C00: 7E9043A6 mtsprg0 r20
+00001C04: 7EB143A6 mtsprg1 r21
+00001C08: 7E800026 mfcr r20
+00001C0C: 7C350B78 mr r21,rsp
+00001C10: 3AB5FF00 subi r21,r21,256
+00001C14: 929500A8 stw r20,168(r21)
+00001C18: 92D50068 stw r22,104(r21)
+00001C1C: 92F5006C stw r23,108(r21)
+00001C20: 7E9042A6 mfsprg0 r20
+00001C24: 92950060 stw r20,96(r21)
+00001C28: 7ED142A6 mfsprg1 r22
+00001C2C: 92D50064 stw r22,100(r21)
+00001C30: 7E8802A6 mflr r20
+00001C34: 929500A0 stw r20,160(r21)
+00001C38: 7EC902A6 mfctr r22
+00001C3C: 92D5009C stw r22,156(r21)
+00001C40: 7E8102A6 mfxer r20
+00001C44: 929500A4 stw r20,164(r21)
+00001C48: 7EDA02A6 mfsrr0 r22
+00001C4C: 7EFB02A6 mfsrr1 r23
+00001C50: 90150010 stw r0,16(r21)
+00001C54: 90350014 stw rsp,20(r21)
+00001C58: 90550018 stw r2,24(r21)
+00001C5C: 90350000 stw rsp,0(r21)
+00001C60: 7EA1AB78 mr rsp,r21
+00001C64: 9075001C stw r3,28(r21)
+00001C68: 90950020 stw r4,32(r21)
+00001C6C: 90B50024 stw r5,36(r21)
+00001C70: 90D50028 stw r6,40(r21)
+00001C74: 806E8014 lwz r3,-32748(r14)
+00001C78: 7C6803A6 mtlr r3
+00001C7C: 38610010 addi r3,rsp,16
+00001C80: 3A801002 li r20,4098
+00001C84: 4E800021 blrl
+00001C88: 00001C88 dc.l 0x00001c88 ; Invalid opcode '....'
+00001C8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ReservedD" Size=0
+00001D00: 7E9043A6 mtsprg0 r20
+00001D04: 7EB143A6 mtsprg1 r21
+00001D08: 7E800026 mfcr r20
+00001D0C: 7C350B78 mr r21,rsp
+00001D10: 3AB5FF00 subi r21,r21,256
+00001D14: 929500A8 stw r20,168(r21)
+00001D18: 92D50068 stw r22,104(r21)
+00001D1C: 92F5006C stw r23,108(r21)
+00001D20: 7E9042A6 mfsprg0 r20
+00001D24: 92950060 stw r20,96(r21)
+00001D28: 7ED142A6 mfsprg1 r22
+00001D2C: 92D50064 stw r22,100(r21)
+00001D30: 7E8802A6 mflr r20
+00001D34: 929500A0 stw r20,160(r21)
+00001D38: 7EC902A6 mfctr r22
+00001D3C: 92D5009C stw r22,156(r21)
+00001D40: 7E8102A6 mfxer r20
+00001D44: 929500A4 stw r20,164(r21)
+00001D48: 7EDA02A6 mfsrr0 r22
+00001D4C: 7EFB02A6 mfsrr1 r23
+00001D50: 90150010 stw r0,16(r21)
+00001D54: 90350014 stw rsp,20(r21)
+00001D58: 90550018 stw r2,24(r21)
+00001D5C: 90350000 stw rsp,0(r21)
+00001D60: 7EA1AB78 mr rsp,r21
+00001D64: 9075001C stw r3,28(r21)
+00001D68: 90950020 stw r4,32(r21)
+00001D6C: 90B50024 stw r5,36(r21)
+00001D70: 90D50028 stw r6,40(r21)
+00001D74: 806E8014 lwz r3,-32748(r14)
+00001D78: 7C6803A6 mtlr r3
+00001D7C: 38610010 addi r3,rsp,16
+00001D80: 3A801002 li r20,4098
+00001D84: 4E800021 blrl
+00001D88: 00001D88 dc.l 0x00001d88 ; Invalid opcode '....'
+00001D8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ReservedE" Size=0
+00001E00: 7E9043A6 mtsprg0 r20
+00001E04: 7EB143A6 mtsprg1 r21
+00001E08: 7E800026 mfcr r20
+00001E0C: 7C350B78 mr r21,rsp
+00001E10: 3AB5FF00 subi r21,r21,256
+00001E14: 929500A8 stw r20,168(r21)
+00001E18: 92D50068 stw r22,104(r21)
+00001E1C: 92F5006C stw r23,108(r21)
+00001E20: 7E9042A6 mfsprg0 r20
+00001E24: 92950060 stw r20,96(r21)
+00001E28: 7ED142A6 mfsprg1 r22
+00001E2C: 92D50064 stw r22,100(r21)
+00001E30: 7E8802A6 mflr r20
+00001E34: 929500A0 stw r20,160(r21)
+00001E38: 7EC902A6 mfctr r22
+00001E3C: 92D5009C stw r22,156(r21)
+00001E40: 7E8102A6 mfxer r20
+00001E44: 929500A4 stw r20,164(r21)
+00001E48: 7EDA02A6 mfsrr0 r22
+00001E4C: 7EFB02A6 mfsrr1 r23
+00001E50: 90150010 stw r0,16(r21)
+00001E54: 90350014 stw rsp,20(r21)
+00001E58: 90550018 stw r2,24(r21)
+00001E5C: 90350000 stw rsp,0(r21)
+00001E60: 7EA1AB78 mr rsp,r21
+00001E64: 9075001C stw r3,28(r21)
+00001E68: 90950020 stw r4,32(r21)
+00001E6C: 90B50024 stw r5,36(r21)
+00001E70: 90D50028 stw r6,40(r21)
+00001E74: 806E8014 lwz r3,-32748(r14)
+00001E78: 7C6803A6 mtlr r3
+00001E7C: 38610010 addi r3,rsp,16
+00001E80: 3A801002 li r20,4098
+00001E84: 4E800021 blrl
+00001E88: 00001E88 dc.l 0x00001e88 ; Invalid opcode '....'
+00001E8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="ReservedF" Size=0
+00001F00: 7E9043A6 mtsprg0 r20
+00001F04: 7EB143A6 mtsprg1 r21
+00001F08: 7E800026 mfcr r20
+00001F0C: 7C350B78 mr r21,rsp
+00001F10: 3AB5FF00 subi r21,r21,256
+00001F14: 929500A8 stw r20,168(r21)
+00001F18: 92D50068 stw r22,104(r21)
+00001F1C: 92F5006C stw r23,108(r21)
+00001F20: 7E9042A6 mfsprg0 r20
+00001F24: 92950060 stw r20,96(r21)
+00001F28: 7ED142A6 mfsprg1 r22
+00001F2C: 92D50064 stw r22,100(r21)
+00001F30: 7E8802A6 mflr r20
+00001F34: 929500A0 stw r20,160(r21)
+00001F38: 7EC902A6 mfctr r22
+00001F3C: 92D5009C stw r22,156(r21)
+00001F40: 7E8102A6 mfxer r20
+00001F44: 929500A4 stw r20,164(r21)
+00001F48: 7EDA02A6 mfsrr0 r22
+00001F4C: 7EFB02A6 mfsrr1 r23
+00001F50: 90150010 stw r0,16(r21)
+00001F54: 90350014 stw rsp,20(r21)
+00001F58: 90550018 stw r2,24(r21)
+00001F5C: 90350000 stw rsp,0(r21)
+00001F60: 7EA1AB78 mr rsp,r21
+00001F64: 9075001C stw r3,28(r21)
+00001F68: 90950020 stw r4,32(r21)
+00001F6C: 90B50024 stw r5,36(r21)
+00001F70: 90D50028 stw r6,40(r21)
+00001F74: 806E8014 lwz r3,-32748(r14)
+00001F78: 7C6803A6 mtlr r3
+00001F7C: 38610010 addi r3,rsp,16
+00001F80: 3A801002 li r20,4098
+00001F84: 4E800021 blrl
+00001F88: 00001F88 dc.l 0x00001f88 ; Invalid opcode '....'
+00001F8C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="RunModeTrace" Size=0
+00002000: 7E9043A6 mtsprg0 r20
+00002004: 7EB143A6 mtsprg1 r21
+00002008: 7E800026 mfcr r20
+0000200C: 7C350B78 mr r21,rsp
+00002010: 3AB5FF00 subi r21,r21,256
+00002014: 929500A8 stw r20,168(r21)
+00002018: 92D50068 stw r22,104(r21)
+0000201C: 92F5006C stw r23,108(r21)
+00002020: 7E9042A6 mfsprg0 r20
+00002024: 92950060 stw r20,96(r21)
+00002028: 7ED142A6 mfsprg1 r22
+0000202C: 92D50064 stw r22,100(r21)
+00002030: 7E8802A6 mflr r20
+00002034: 929500A0 stw r20,160(r21)
+00002038: 7EC902A6 mfctr r22
+0000203C: 92D5009C stw r22,156(r21)
+00002040: 7E8102A6 mfxer r20
+00002044: 929500A4 stw r20,164(r21)
+00002048: 7EDA02A6 mfsrr0 r22
+0000204C: 7EFB02A6 mfsrr1 r23
+00002050: 90150010 stw r0,16(r21)
+00002054: 90350014 stw rsp,20(r21)
+00002058: 90550018 stw r2,24(r21)
+0000205C: 90350000 stw rsp,0(r21)
+00002060: 7EA1AB78 mr rsp,r21
+00002064: 9075001C stw r3,28(r21)
+00002068: 90950020 stw r4,32(r21)
+0000206C: 90B50024 stw r5,36(r21)
+00002070: 90D50028 stw r6,40(r21)
+00002074: 806E8014 lwz r3,-32748(r14)
+00002078: 7C6803A6 mtlr r3
+0000207C: 38610010 addi r3,rsp,16
+00002080: 3A801002 li r20,4098
+00002084: 4E800021 blrl
+00002088: 00002088 dc.l 0x00002088 ; Invalid opcode '.. .'
+0000208C: 0000309C dc.l 0x0000309c ; Invalid opcode '..0.'
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="_end_of_vectors" Size=0
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="transfer_to_handler" Size=0
+00003000: 92D50090 stw r22,144(r21)
+00003004: 3EC00004 lis r22,4
+00003008: 7EF7B078 andc r23,r23,r22
+0000300C: 92F50094 stw r23,148(r21)
+00003010: 90F5002C stw r7,44(r21)
+00003014: 91150030 stw r8,48(r21)
+00003018: 91350034 stw r9,52(r21)
+0000301C: 91550038 stw r10,56(r21)
+00003020: 9175003C stw r11,60(r21)
+00003024: 91950040 stw r12,64(r21)
+00003028: 91B50044 stw r13,68(r21)
+0000302C: 91D50048 stw r14,72(r21)
+00003030: 91F5004C stw r15,76(r21)
+00003034: 92150050 stw r16,80(r21)
+00003038: 92350054 stw r17,84(r21)
+0000303C: 92550058 stw r18,88(r21)
+00003040: 9275005C stw r19,92(r21)
+00003044: 93150070 stw r24,112(r21)
+00003048: 93350074 stw r25,116(r21)
+0000304C: 93550078 stw r26,120(r21)
+00003050: 9375007C stw r27,124(r21)
+00003054: 93950080 stw r28,128(r21)
+00003058: 93B50084 stw r29,132(r21)
+0000305C: 93D50088 stw r30,136(r21)
+00003060: 93F5008C stw r31,140(r21)
+00003064: 7EE802A6 mflr r23
+00003068: 72F83F00 andi. r24,r23,0x3f00
+0000306C: 931500B0 stw r24,176(r21)
+00003070: 3AC00000 li r22,0
+00003074: 92D500BC stw r22,188(r21)
+00003078: 7ED243A6 mtsprg2 r22
+0000307C: 83170000 lwz r24,0(r23)
+00003080: 82F70004 lwz r23,4(r23)
+00003084: 7F1A03A6 mtsrr0 r24
+00003088: 7E9B03A6 mtsrr1 r20
+0000308C: 7EE803A6 mtlr r23
+00003090: 7C0004AC sync
+00003094: 4C00012C isync
+00003098: 4C000064 rfi
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="int_return" Size=0
+0000309C: 7FA000A6 mfmsr r29
+000030A0: 38800000 li r4,0
+000030A4: 60848000 ori r4,r4,0x8000
+000030A8: 7FBD2078 andc r29,r29,r4
+000030AC: 7C0004AC sync
+000030B0: 4C00012C isync
+000030B4: 7FA00124 mtmsr r29
+000030B8: 7C0004AC sync
+000030BC: 4C00012C isync
+000030C0: 8041009C lwz r2,156(rsp)
+000030C4: 800100A0 lwz r0,160(rsp)
+000030C8: 7C4903A6 mtctr r2
+000030CC: 7C0803A6 mtlr r0
+000030D0: 804100A4 lwz r2,164(rsp)
+000030D4: 800100A8 lwz r0,168(rsp)
+000030D8: 7C4103A6 mtxer r2
+000030DC: 7C0FF120 mtcrf 0xff,r0
+000030E0: 8061001C lwz r3,28(rsp)
+000030E4: 80810020 lwz r4,32(rsp)
+000030E8: 80A10024 lwz r5,36(rsp)
+000030EC: 80C10028 lwz r6,40(rsp)
+000030F0: 80E1002C lwz r7,44(rsp)
+000030F4: 81010030 lwz r8,48(rsp)
+000030F8: 81210034 lwz r9,52(rsp)
+000030FC: 81410038 lwz r10,56(rsp)
+00003100: 8161003C lwz r11,60(rsp)
+00003104: 81810040 lwz r12,64(rsp)
+00003108: 81A10044 lwz r13,68(rsp)
+0000310C: 81C10048 lwz r14,72(rsp)
+00003110: 81E1004C lwz r15,76(rsp)
+00003114: 82010050 lwz r16,80(rsp)
+00003118: 82210054 lwz r17,84(rsp)
+0000311C: 82410058 lwz r18,88(rsp)
+00003120: 8261005C lwz r19,92(rsp)
+00003124: 82810060 lwz r20,96(rsp)
+00003128: 82A10064 lwz r21,100(rsp)
+0000312C: 82C10068 lwz r22,104(rsp)
+00003130: 82E1006C lwz r23,108(rsp)
+00003134: 83010070 lwz r24,112(rsp)
+00003138: 83210074 lwz r25,116(rsp)
+0000313C: 83410078 lwz r26,120(rsp)
+00003140: 8361007C lwz r27,124(rsp)
+00003144: 83810080 lwz r28,128(rsp)
+00003148: 83A10084 lwz r29,132(rsp)
+0000314C: 83C10088 lwz r30,136(rsp)
+00003150: 83E1008C lwz r31,140(rsp)
+00003154: 80410090 lwz r2,144(rsp)
+00003158: 80010094 lwz r0,148(rsp)
+0000315C: 7C5A03A6 mtsrr0 r2
+00003160: 7C1B03A6 mtsrr1 r0
+00003164: 80010010 lwz r0,16(rsp)
+00003168: 80410018 lwz r2,24(rsp)
+0000316C: 80210014 lwz rsp,20(rsp)
+00003170: 7C0004AC sync
+00003174: 4C00012C isync
+00003178: 4C000064 rfi
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="icache_enable" Size=0
+0000317C: 7CB0FAA6 mfdbsr r5
+00003180: 60A58800 ori r5,r5,0x8800
+00003184: 3CC0FFFF lis r6,-1
+00003188: 60C6F7FF ori r6,r6,0xf7ff
+0000318C: 7CA63038 and r6,r5,r6
+00003190: 7C0004AC sync
+00003194: 7CB0FBA6 mtdbsr r5
+00003198: 7CD0FBA6 mtdbsr r6
+0000319C: 4C00012C isync
+000031A0: 7C0004AC sync
+000031A4: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="icache_disable" Size=0
+000031A8: 7CB0FAA6 mfdbsr r5
+000031AC: 3CC0FFFF lis r6,-1
+000031B0: 60C67FFF ori r6,r6,0x7fff
+000031B4: 7CA53038 and r5,r5,r6
+000031B8: 7C0004AC sync
+000031BC: 7CB0FBA6 mtdbsr r5
+000031C0: 4C00012C isync
+000031C4: 7C0004AC sync
+000031C8: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="icache_status" Size=0
+000031CC: 7C70FAA6 mfdbsr r3
+000031D0: 54638BFE srwi r3,r3,15
+000031D4: 70630001 andi. r3,r3,0x0001
+000031D8: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="dcache_enable" Size=0
+000031DC: 7CB0FAA6 mfdbsr r5
+000031E0: 60A54400 ori r5,r5,0x4400
+000031E4: 7C9F42A6 mfpvr r4
+000031E8: 7C838670 srawi r3,r4,16
+000031EC: 2C03000C cmpwi r3,0x000c
+000031F0: 40820008 bne *+8 ; 0x000031F8
+000031F4: 60A50040 ori r5,r5,0x0040
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="NotMax" Size=0
+000031F8: 3CC0FFFF lis r6,-1
+000031FC: 60C6FBFF ori r6,r6,0xfbff
+00003200: 7CA63038 and r6,r5,r6
+00003204: 7C0004AC sync
+00003208: 7CB0FBA6 mtdbsr r5
+0000320C: 7CD0FBA6 mtdbsr r6
+00003210: 4C00012C isync
+00003214: 7C0004AC sync
+00003218: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="dcache_disable" Size=0
+0000321C: 7CB0FAA6 mfdbsr r5
+00003220: 3CC0FFFF lis r6,-1
+00003224: 60C6BFFF ori r6,r6,0xbfff
+00003228: 7CA53038 and r5,r5,r6
+0000322C: 7C0004AC sync
+00003230: 7CB0FBA6 mtdbsr r5
+00003234: 4C00012C isync
+00003238: 7C0004AC sync
+0000323C: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="dcache_status" Size=0
+00003240: 7C70FAA6 mfdbsr r3
+00003244: 546393BE srwi r3,r3,14
+00003248: 70630001 andi. r3,r3,0x0001
+0000324C: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="dc_read" Size=0
+00003250: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="get_pvr" Size=0
+00003254: 7C7F42A6 mfpvr r3
+00003258: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="udelay" Size=0
+0000325C: 1C832710 mulli r4,r3,10000
+00003260: 38A00C35 li r5,3125
+00003264: 7C842BD6 divw r4,r4,r5
+00003268: 7CAD42E6 mftbu r5
+0000326C: 7CCC42E6 mftb r6
+00003270: 7CED42E6 mftbu r7
+00003274: 7C053800 cmpw r5,r7
+00003278: 4082FFF0 bne *-16 ; 0x00003268
+0000327C: 7D262014 addc r9,r6,r4
+00003280: 7D050194 addze r8,r5
+00003284: 7CAD42E6 mftbu r5
+00003288: 7C054000 cmpw r5,r8
+0000328C: 4180FFF8 blt *-8 ; 0x00003284
+00003290: 41810010 bgt *+16 ; 0x000032A0
+00003294: 7CCC42E6 mftb r6
+00003298: 7C064800 cmpw r6,r9
+0000329C: 4180FFE8 blt *-24 ; 0x00003284
+000032A0: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="relocate_code" Size=0
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="clear_bss" Size=0
+000032A4: 806E801C lwz r3,-32740(r14)
+000032A8: 808E8018 lwz r4,-32744(r14)
+000032AC: 7C032040 cmplw r3,r4
+000032B0: 41820018 beq *+24 ; 0x000032C8
+000032B4: 38000000 li r0,0
+000032B8: 90030000 stw r0,0(r3)
+000032BC: 38630004 addi r3,r3,4
+000032C0: 7C032040 cmplw r3,r4
+000032C4: 4082FFF4 bne *-12 ; 0x000032B8
+000032C8: 7D234B78 mr r3,r9
+000032CC: 7D445378 mr r4,r10
+000032D0: 48000001 bl *+0 ; 0x000032D0
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="get_endaddr" Size=0
+000032D4: 806E8018 lwz r3,-32744(r14)
+000032D8: 4E800020 blr
+
+Hunk: Kind=HUNK_GLOBAL_CODE Name="trap_init" Size=0
+000032DC: 80EE8008 lwz r7,-32760(r14)
+000032E0: 810E8010 lwz r8,-32752(r14)
+000032E4: 54E904BE clrlwi r9,r7,18
+000032E8: 7C074040 cmplw r7,r8
+000032EC: 4C800020 bgelr
+000032F0: 7C8802A6 mflr r4
+000032F4: 80070000 lwz r0,0(r7)
+000032F8: 90090000 stw r0,0(r9)
+000032FC: 38E70004 addi r7,r7,4
+00003300: 39290004 addi r9,r9,4
+00003304: 7C074040 cmplw r7,r8
+00003308: 4082FFEC bne *-20 ; 0x000032F4
+0000330C: 38E00288 li r7,648
+00003310: 39000600 li r8,1536
+00003314: 48000041 bl *+64 ; 0x00003354
+00003318: 38E70100 addi r7,r7,256
+0000331C: 7C074040 cmplw r7,r8
+00003320: 4180FFF4 blt *-12 ; 0x00003314
+00003324: 38E0069C li r7,1692
+00003328: 4800002D bl *+44 ; 0x00003354
+0000332C: 38E0078C li r7,1932
+00003330: 48000025 bl *+36 ; 0x00003354
+00003334: 38E00888 li r7,2184
+00003338: 39002090 li r8,8336
+0000333C: 48000019 bl *+24 ; 0x00003354
+00003340: 38E70100 addi r7,r7,256
+00003344: 7C074040 cmplw r7,r8
+00003348: 4180FFF4 blt *-12 ; 0x0000333C
+0000334C: 7C8803A6 mtlr r4
+00003350: 4E800020 blr
+
+Hunk: Kind=HUNK_LOCAL_CODE Name="trap_reloc" Size=0
+00003354: 80070000 lwz r0,0(r7)
+00003358: 7C001A14 add r0,r0,r3
+0000335C: 90070000 stw r0,0(r7)
+00003360: 80070004 lwz r0,4(r7)
+00003364: 7C001A14 add r0,r0,r3
+00003368: 90070004 stw r0,4(r7)
+0000336C: 4E800020 blr
+00003370: 0000B21C dc.l 0x0000b21c ; Invalid opcode '....'
+
+==> .data
+
+==> .bss
+
+==> .rela.got2
+ entry offset addend type name(symbol id)
+ [ 0] 00000000 00000000 1 _GOT2_TABLE_(74)
+ [ 1] 00000004 00000000 1 _FIXUP_TABLE_(75)
+ [ 2] 00000008 00000000 1 _start(76)
+ [ 3] 0000000c 00000000 1 _start_of_vectors(77)
+ [ 4] 00000010 00000000 1 _end_of_vectors(78)
+ [ 5] 00000014 00000000 1 transfer_to_handler(79)
+ [ 6] 00000018 00000000 1 _end(80)
+ [ 7] 0000001c 00000000 1 .bss(34)
+
+==> .got2
+00000000: 00000000 00000000 00000000 00000000 '................'
+00000010: 00000000 00000000 00000000 00000000 '................'
--- /dev/null
+/*
+ * linux/arch/ppc/kernel/traps.c
+ *
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <ppcboot.h>
+#include <asm/processor.h>
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+*/
+#define END_OF_MEM 0x00400000
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+ int cnt = 0;
+ unsigned long i;
+
+ printf("Call backtrace: ");
+ while (sp) {
+ if ((uint)sp > END_OF_MEM)
+ break;
+
+ i = sp[1];
+ if (cnt++ % 7 == 0)
+ printf("\n");
+ printf("%08lX ", i);
+ if (cnt > 32) break;
+ sp = (unsigned long *)*sp;
+ }
+ printf("\n");
+}
+
+void show_regs(struct pt_regs * regs)
+{
+ int i;
+
+ printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
+ regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+ printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+ regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
+ regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
+ regs->msr&MSR_IR ? 1 : 0,
+ regs->msr&MSR_DR ? 1 : 0);
+
+ printf("\n");
+ for (i = 0; i < 32; i++) {
+ if ((i % 8) == 0)
+ {
+ printf("GPR%02d: ", i);
+ }
+
+ printf("%08lX ", regs->gpr[i]);
+ if ((i % 8) == 7)
+ {
+ printf("\n");
+ }
+ }
+}
+
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+ unsigned long fixup;
+
+ /* Probing PCI using config cycles cause this exception
+ * when a device is not present. Catch it and return to
+ * the PCI exception handler.
+ */
+ if ((fixup = search_exception_table(regs->nip)) != 0) {
+ regs->nip = fixup;
+ return;
+ }
+
+ printf("Machine check in kernel mode.\n");
+ printf("Caused by (from msr): ");
+ printf("regs %p ",regs);
+ switch( regs->msr & 0x0000F000)
+ {
+ case (1<<12) :
+ printf("Machine check signal - probably due to mm fault\n"
+ "with mmu off\n");
+ break;
+ case (1<<13) :
+ printf("Transfer error ack signal\n");
+ break;
+ case (1<<14) :
+ printf("Data parity signal\n");
+ break;
+ case (1<<15) :
+ printf("Address parity signal\n");
+ break;
+ default:
+ printf("Unknown values in msr\n");
+ }
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Software Emulation Exception");
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+ printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+ regs->nip, regs->msr, regs->trap);
+ _exception(0, regs);
+}
+
+/* Probe an address by reading. If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+#if 0
+ int retval;
+
+ __asm__ __volatile__( \
+ "1: lwz %0,0(%1)\n" \
+ " eieio\n" \
+ " li %0,0\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,-1\n" \
+ " b 2b\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=r" (retval) : "r"(addr));
+
+ return (retval);
+#endif
+ return 0;
+}
START = start.o kgdb.o
OBJS = traps.o serial.o cpu.o cpu_init.o speed.o \
- commproc.o interrupts.o scc.o i2c.o video.o wlkbd.o
+ commproc.o interrupts.o fec.o scc.o \
+ i2c.o video.o wlkbd.o status_led.o
all: .depend $(START) $(LIB)
#include <net.h>
#include <command.h>
-#if (CONFIG_COMMANDS & CFG_CMD_NET)
+#define ET_DEBUG
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
#define BD_OFFSET 0x860 /* offset to begin of DPRAM + allocation for serial IF*/
#define TX_BUF_CNT 2
-#define TOUT_LOOP 1000000
+#define TOUT_LOOP 100000
+
+#define PKT_MAXBUF_SIZE 1518
+#define PKT_MINBUF_SIZE 64
+#define PKT_MAXBLR_SIZE 1520
+
/* static char rxbuf[PKTBUFSRX][ DBUF_LENGTH ]; */
static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ];
int eth_send(volatile void *packet, int length)
{
int i, j=0;
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
#if 0
volatile char *in, *out;
#endif
while (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) j++;
#ifdef ET_DEBUG
- printf("cycles: %d status: %x\n", j, rtx->txbd[txIdx].cbd_sc);
+ printf("%s[%d] %s: cycles: %d status: %x\n",
+ __FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc);
#endif
i = (rtx->txbd[txIdx++].cbd_sc & BD_ENET_TX_STATS) /* return only status bits */;
if (txIdx >= TX_BUF_CNT) txIdx = 0;
#endif
- while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) j++;
- if (j>=TOUT_LOOP) printf("TX not ready\n");
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
+ udelay(1);
+ j++;
+ }
+ if (j>=TOUT_LOOP) {
+ printf("TX not ready\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_HB) printf("- No heartbeat\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_LC) printf("- Late collision\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_RL) printf("- Retrans limit\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_UN) printf("- Underrun\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_CSL) printf("- Carrier lost\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_DEF) printf("- Deferred\n");
+ }
rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
rtx->txbd[txIdx].cbd_datlen = length;
rtx->txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST |BD_ENET_TX_WRAP);
- while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) j++;
- if (j>=TOUT_LOOP) printf("TX timeout\n");
+
+ /* Activate transmit Buffer Descriptor polling */
+ fecp->fec_x_des_active = 0x01000000; /* Descriptor polling active */
+
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
+ udelay(1);
+ j++;
+ }
+ if (j>=TOUT_LOOP) {
+ printf("TX timeout\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_HB) printf("- No heartbeat\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_LC) printf("- Late collision\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_RL) printf("- Retrans limit\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_UN) printf("- Underrun\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_CSL) printf("- Carrier lost\n");
+if (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_DEF) printf("- Deferred\n");
+ }
#ifdef ET_DEBUG
- printf("cycles: %d status: %x\n", j, rtx->txbd[txIdx].cbd_sc);
+ printf("%s[%d] %s: cycles: %d status: %x\n",
+ __FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc);
#endif
i = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS) /* return only status bits */;
+
+printf("%s[%d] %s: return 0x%x\n",__FILE__,__LINE__,__FUNCTION__,i);
return i;
}
int eth_rx(void)
{
int length;
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+
+ /* Try to fill Buffer Descriptors */
+ fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
for (;;)
{
length = rtx->rxbd[rxIdx].cbd_datlen;
- if (rtx->rxbd[rxIdx].cbd_sc & 0x003f)
- {
+ if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
#ifdef ET_DEBUG
- printf("err: %x\n", rtx->rxbd[rxIdx].cbd_sc);
+ printf("%s[%d] %s: err: %x\n",
+ __FILE__,__LINE__,__FUNCTION__,rtx->rxbd[rxIdx].cbd_sc);
#endif
- }
- else
- {
+ } else {
/* Pass the packet up to the protocol layers. */
NetReceive(NetRxPackets[rxIdx], length - 4);
}
if ((rxIdx + 1) >= PKTBUFSRX) {
rtx->rxbd[PKTBUFSRX - 1].cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
rxIdx = 0;
- }
- else {
+ } else {
rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
rxIdx++;
}
}
+
+ /* Try to fill Buffer Descriptors */
+ fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
+printf("%s[%d] %s: len=%d\n",__FILE__,__LINE__,__FUNCTION__,length);
return length;
}
/**************************************************************
- *
- * FEC Ethernet Initialization Routine
- *
- *************************************************************/
+ *
+ * FEC Ethernet Initialization Routine
+ *
+ *************************************************************/
+
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_ECNTRL_ETHER_EN 0x00000002
+#define FEC_ECNTRL_RESET 0x00000001
+
+#define FEC_RESET_DELAY 50
-int eth_init(bd_t *bis)
+int eth_init (bd_t * bd)
{
- int i;
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
-
- /* Whack a reset.
- * A delay is required between a reset of the FEC block and
- * initialization of other FEC registers because the reset takes
- * some time to complete. If you don't delay, subsequent writes
- * to FEC registers might get killed by the reset routinewhich is
- * still in progress.
- */
- fecp->fec_ecntrl = 1;
- udelay (20);
-
- /* We use striclty polling mode only
- */
- fecp->fec_imask = 0;
-
- /* Clear any outstanding interrupt.
- */
- fecp->fec_ievent = 0xffc0;
-
- /* Reset all multicast.
- */
- fecp->fec_hash_table_high = 0;
- fecp->fec_hash_table_low = 0;
-
- /* Set maximum receive buffer size.
- */
- fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fecp->fec_r_hash = PKT_MAXBUF_SIZE;
-
- /* Configure all of port D for MII.
- */
- immr->im_ioport.iop_pdpar = 0x1fff;
-
- /* Bits moved from Rev. D onward */
- if ((_get_IMMR() & 0xffff) < 0x0501) {
- immr->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
- } else {
- immr->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
- }
-
- /* Set MII speed to 2.5 MHz
- */
- fecp->fec_mii_speed = fep->phy_speed =
- ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
-
-
- rxIdx = 0;
- txIdx = 0;
-
- /* assign static pointer to BD area */
- rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + BD_OFFSET);
-
- /* Set receive and transmit descriptor base
- */
- fecp->fec_r_des_start = (unsigned int)(&rtx->rxbd[0]);
- fecp->fec_x_des_start = (unsigned int)(&rtx->txbd[0]);
-
-
-#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
- /* Configure port A pins for Txd and Rxd.
- */
- immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
- immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
- immr->im_ioport.iop_paodr &= ~PA_ENET_TXD;
-#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
- /* Configure port B pins for Txd and Rxd.
- */
- immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
- immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
- immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
-#else
-#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
-#endif
+ int i;
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
+
+printf ("Start FEC init\n");
+ /* Whack a reset.
+ * A delay is required between a reset of the FEC block and
+ * initialization of other FEC registers because the reset takes
+ * some time to complete. If you don't delay, subsequent writes
+ * to FEC registers might get killed by the reset routine which is
+ * still in progress.
+ */
+ fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
+ for (i = 0;
+ (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
+ ++i) {
+ udelay (1);
+ }
+ if (i == FEC_RESET_DELAY) {
+ printf ("FEC_RESET_DELAY timeout\n");
+ return 0;
+ }
+
+ /* We use strictly polling mode only
+ */
+ fecp->fec_imask = 0;
+
+ /* Clear any pending interrupt
+ */
+ fecp->fec_ievent = 0xffc0;
-#if defined(PC_ENET_LBK)
- /* Configure port C pins to disable External Loopback
- */
- immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
- immr->im_ioport.iop_pcdir |= PC_ENET_LBK;
- immr->im_ioport.iop_pcso &= ~PC_ENET_LBK;
- immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
-#endif /* PC_ENET_LBK */
-
- /* Configure port C pins to enable CLSN and RENA.
- */
- immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
- immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
- immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
-
- /* Configure port A for TCLK and RCLK.
- */
- immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
- immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
-
- /*
- * Configure Serial Interface clock routing -- see section 16.7.5.3
- * First, clear all FEC bits to zero, then set the ones we want.
- */
-
- immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK;
- immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT;
-
-
- /*
- * Initialize SDCR -- see section 16.9.23.7
- * SDMA configuration register
- */
- immr->im_siu_conf.sc_sdcr = 0x01;
-
-
- /*
- * Setup FEC Ethernet Parameter RAM
- */
-
- pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
- pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
-
- pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
-
-
- /*
- * Setup Receiver Buffer Descriptors (13.14.24.18)
- * Settings:
- * Empty, Wrap
- */
-
- for (i = 0; i < PKTBUFSRX; i++)
- {
- rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
- rtx->rxbd[i].cbd_datlen = 0; /* Reset */
- rtx->rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
- }
-
- rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
-
- /*
- * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
- * Settings:
- * Add PADs to Short FRAMES, Wrap, Last, Tx CRC
- */
-
- for (i = 0; i < TX_BUF_CNT; i++)
- {
- rtx->txbd[i].cbd_sc = (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
- rtx->txbd[i].cbd_datlen = 0; /* Reset */
- rtx->txbd[i].cbd_bufaddr = (uint)&txbuf[i][0];
- }
-
- rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
-
- /*
- * Enter Command: Initialize Rx Params for FEC
- */
-
- do { /* Spin until ready to issue command */
- __asm__ ("eieio");
- } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
- /* Issue command */
- immr->im_cpm.cp_cpcr = ((CPM_CR_INIT_RX << 8) | (CPM_CR_ENET << 4) | CPM_CR_FLG);
- do { /* Spin until command processed */
- __asm__ ("eieio");
- } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
-
- /*
- * Ethernet Specific Parameter RAM
- * see table 13-16, pg. 660,
- * pg. 681 (example with suggested settings)
- */
-
- pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */
- pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */
- pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */
- pram_ptr->sen_alec = 0x0; /* Alignment Error Counter (unused) */
- pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */
- pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */
-
- pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */
- pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */
- pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */
-
- pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */
- pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */
-
- pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */
- pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */
- pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
- pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
-
-#define ea bis->bi_enetaddr
- pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
- pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
- pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
+ /* No need to set the IVEC register */
+
+ /* Set station address
+ */
+#define ea bd->bi_enetaddr
+ fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) |
+ (ea[2] << 8) | (ea[3] ) ;
+ fecp->fec_addr_high = (ea[4] << 24) | (ea[5] << 16) ;
#undef ea
- pram_ptr->sen_pper = 0x0; /* Persistence (unused) */
- pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */
- pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */
- pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */
- pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */
- pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */
- pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
- pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
-
- /*
- * Enter Command: Initialize Tx Params for FEC
- */
-
- do { /* Spin until ready to issue command */
- __asm__ ("eieio");
- } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
- /* Issue command */
- immr->im_cpm.cp_cpcr = ((CPM_CR_INIT_TX << 8) | (CPM_CR_ENET << 4) | CPM_CR_FLG);
- do { /* Spin until command processed */
- __asm__ ("eieio");
- } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
-
- /*
- * Mask all Events in SCCM - we use polling mode
- */
- immr->im_cpm.cp_scc[SCC_ENET].scc_sccm = 0;
-
- /*
- * Clear Events in SCCE -- Clear bits by writing 1's
- */
-
- immr->im_cpm.cp_scc[SCC_ENET].scc_scce = ~(0x0);
-
-
- /*
- * Initialize GSMR High 32-Bits
- * Settings: Normal Mode
- */
-
- immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrh = 0;
-
- /*
- * Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive
- * Settings:
- * TCI = Invert
- * TPL = 48 bits
- * TPP = Repeating 10's
- * MODE = Ethernet
- */
-
- immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl = ( SCC_GSMRL_TCI | \
- SCC_GSMRL_TPL_48 | \
- SCC_GSMRL_TPP_10 | \
- SCC_GSMRL_MODE_ENET);
-
- /*
- * Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4
- */
-
- immr->im_cpm.cp_scc[SCC_ENET].scc_dsr = 0xd555;
-
- /*
- * Initialize the PSMR
- * Settings:
- * CRC = 32-Bit CCITT
- * NIB = Begin searching for SFD 22 bits after RENA
- * BRO = Reject broadcast packets
- * PROMISCOUS = Catch all packets regardless of dest. MAC adress
- */
- immr->im_cpm.cp_scc[SCC_ENET].scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22
- /* | SCC_PMSR_BRO | SCC_PMSR_PRO */);
-
- /*
- * Configure Ethernet TENA Signal
- */
-
-#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
- immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
- immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
-#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
- immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
- immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
-#else
-#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
-#endif
+ rxIdx = 0;
+ txIdx = 0;
+
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + m8xx_cpm_dpbase_align(8));
+ /*
+ * Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings:
+ * Empty, Wrap
+ */
+ for (i = 0; i < PKTBUFSRX; i++) {
+ rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+ rtx->rxbd[i].cbd_datlen = 0; /* Reset */
+ rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ }
+ rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /*
+ * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings:
+ * Add PADs to Short FRAMES, Wrap, Last, Tx CRC
+ */
+ for (i = 0; i < TX_BUF_CNT; i++) {
+ rtx->txbd[i].cbd_sc =
+ (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+ rtx->txbd[i].cbd_datlen = 0; /* Reset */
+ rtx->txbd[i].cbd_bufaddr = (uint) & txbuf[i][0];
+ }
+ rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
-#if defined(CONFIG_FADS) && defined(CONFIG_MPC860T)
- /*
- * Port C is used to control the PHY,MC68160.
- */
- immr->im_ioport.iop_pcdir |=
- (PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL);
+ /* Clear multicast address hash table
+ */
+ fecp->fec_hash_table_high = 0;
+ fecp->fec_hash_table_low = 0;
- immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL;
- immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL);
- *((uint *) BCSR1) &= ~BCSR1_ETHEN;
-#endif /* FADS860T */
+ /* Set maximum receive buffer size.
+ */
+ fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-#ifdef CONFIG_MBX
- board_ether_init();
+ /* Set receive and transmit descriptor base
+ */
+ fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
+ fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
+
+ /* Set maximum frame length
+ */
+ fecp->fec_r_hash = PKT_MAXBUF_SIZE;
+
+ /* Enable MII mode
+ */
+#if 0 /* Full duplex mode */
+ fecp->fec_r_cntrl = 0x04; /* MII enable */
+ fecp->fec_x_cntrl = 0x04; /* FD enable */
+#else /* Half duplex mode */
+ fecp->fec_r_cntrl = 0x06; /* MII enable | No Rcv on Xmit */
+ fecp->fec_x_cntrl = 0x00;
#endif
- /*
- * Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive
- */
+ /* Enable big endian and don't care about SDMA FC.
+ */
+ fecp->fec_fun_code = 0x78000000;
- immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ /* Configure all of port D for MII.
+ */
+ immr->im_ioport.iop_pdpar = 0x1fff;
- return 1;
+ /* Bits moved from Rev. D onward */
+ if ((get_immr (0) & 0xffff) < 0x0501) {
+ immr->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
+ } else {
+ immr->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
+ }
+
+ /* Set MII speed to 2.5 MHz
+ */
+ fecp->fec_mii_speed = ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
+
+ rxIdx = 0;
+ txIdx = 0;
+
+ /* And last, enable the transmit and receive processing
+ */
+ fecp->fec_ecntrl = 6;
+ fecp->fec_r_des_active = 0x01000000;
+
+printf ("FEC init done\n");
+ return 1;
}
void eth_halt(void)
{
+#if 0
volatile immap_t *immr = (immap_t *)CFG_IMMR;
immr->im_cpm.cp_scc[SCC_ENET].scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
}
#if 0
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _FEC_H_
+#define _FEC_H_
+
+
+#endif /* _FEC_H_ */
void timer_interrupt(struct pt_regs *regs)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#ifdef CONFIG_STATUS_LED
+ extern void status_led_tick (ulong);
+#endif
#if 0
printf ("*** Timer Interrupt *** ");
#endif
timestamp++;
+#ifdef CONFIG_STATUS_LED
+ status_led_tick (timestamp);
+#endif /* CONFIG_STATUS_LED */
+
#if defined(CONFIG_WATCHDOG) || defined(CFG_CMA_LCD_HEARTBEAT)
if ((timestamp % 1000) == 0) {
-
#if defined(CFG_CMA_LCD_HEARTBEAT)
extern void lcd_heartbeat(void);
-
lcd_heartbeat();
#endif /* CFG_CMA_LCD_HEARTBEAT */
#include <net.h>
#include <command.h>
-#if (CONFIG_COMMANDS & CFG_CMD_NET)
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(SCC_ENET)
#if 0
#define BD_OFFSET 0x860 /* offset to begin of DPRAM + allocation for serial IF*/
}
#endif
-#endif /* CFG_CMD_NET */
+#endif /* CFG_CMD_NET, SCC_ENET */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include "mpc8xx.h"
+#include <status_led.h>
+
+/*
+ * The purpose of this code is to signal the operational status of a
+ * target which usually boots over the network; while running in
+ * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
+ * message has been received, the LED is turned off. The Linux
+ * kernel, once it is running, will start blinking the LED again,
+ * with another frequency.
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CONFIG_STATUS_LED
+
+static int status_led_state;
+static int status_led_init_done = 0;
+
+static void status_led_init (void)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ immr->STATUS_LED_PAR &= ~(STATUS_LED_BIT);
+#ifdef STATUS_LED_ODR
+ immr->STATUS_LED_ODR &= ~(STATUS_LED_BIT);
+#endif
+ immr->STATUS_LED_DAT &= ~(STATUS_LED_BIT); /* start with off */
+ immr->STATUS_LED_DIR |= STATUS_LED_BIT ;
+ status_led_state = STATUS_LED_BLINKING;
+ status_led_init_done = 1;
+}
+
+void status_led_tick (ulong timestamp)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ if (status_led_state != STATUS_LED_BLINKING)
+ return;
+
+ if (!status_led_init_done)
+ status_led_init();
+
+ if ((timestamp % STATUS_LED_PERIOD) == 0) {
+ immr->STATUS_LED_DAT ^= STATUS_LED_BIT;
+ }
+}
+
+void status_led_set (int state)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ if (!status_led_init_done)
+ status_led_init();
+
+ switch (state) {
+ default:
+ return;
+ case STATUS_LED_BLINKING:
+ break;
+ case STATUS_LED_ON:
+ immr->STATUS_LED_DAT |= STATUS_LED_BIT;
+ break;
+ case STATUS_LED_OFF:
+ immr->STATUS_LED_DAT &= ~(STATUS_LED_BIT);
+ break;
+ }
+ status_led_state = state;
+}
+
+#endif /* CONFIG_STATUS_LED */
#include "net.h"
#include "bootp.h"
#include "tftp.h"
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */
/*
* Got a good BOOTP reply. Copy the data into our variables.
*/
+#ifdef CONFIG_STATUS_LED
+ status_led_set (STATUS_LED_OFF);
+#endif
NetOurIP = bp->bp_yiaddr;
NetServerIP = bp->bp_siaddr;
NetCopyEther(NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src);
va_list args;
va_start(args, fmt);
printf(fmt);
+ putc('\n');
va_end(args);
-
- /* Hang */
- for(;;);
+#if 1
+ hang();
+#else
+ udelay (100000); /* allow messages to go out */
+ do_reset (NULL, NULL, 0, 0, NULL);
+#endif
}
out32 (EMAC_M0, in32 (EMAC_M0) & ~EMAC_M0_SRST);
speed = miiphy_speed();
- printf("ENET Speed is %d Mbs... \n\r", (int)speed);
+ printf("ENET Speed is %d Mbs... \n", (int)speed);
duplex = miiphy_duplex();
if( duplex == HALF)
- printf("HALF duplex connection\n\r");
+ printf("HALF duplex connection\n");
else
- printf("FULL duplex connection\n\r");
+ printf("FULL duplex connection\n");
/* set the Mal configuration reg */
mtdcr(malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
unsigned long mal_errr)
{
mtdcr(malesr, isr); /* clear interrupt */
- printf ("MAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n\r",
+ printf ("MAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n",
isr, uic, maldef, mal_errr);
#if 0
+-----------------------------------------------------------------------------*/
void emac_err (unsigned long isr)
{
- printf ("EMAC error occured.... ISR = %lx\n\r", isr);
+ printf ("EMAC error occured.... ISR = %lx\n", isr);
out32(EMAC_ISR, isr);
}
{
if(miiphy_read(i, &data))
{
- printf("read error for reg %lx\n\r",i);
+ printf("read error for reg %lx\n",i);
return;
}
- printf("Phy reg %lx ==> %4x\n\r", i, data);
+ printf("Phy reg %lx ==> %4x\n", i, data);
/* jump to the next set of regs */
if(i==0x07)
{
udelay(7);
if(i > 5)
- { printf("read err 1\n\r");
+ { printf("read err 1\n");
return -1;
}
i++;
{
udelay(7);
if(i > 5)
- { printf("read err 2\n\r");
+ { printf("read err 2\n");
return -1;
}
i++;
sta_reg = in32(EMAC_STACR);
}
if ((sta_reg & EMAC_STACR_PHYE) !=0)
- { printf("read err 3\n\r");
+ { printf("read err 3\n");
printf("a2: read: EMAC_STACR=0x%0lx, i=%d\n", sta_reg, (int)i); /* test-only */
return -1;
}
unsigned short bmcr = 0x0;
if (miiphy_read(PHY_ANLPAR,&bmcr)) {
- printf("phy speed1 read failed \n\r");
+ printf("phy speed1 read failed \n");
miiphy_dump();
}
if (miiphy_read(PHY_ANLPAR,&bmcr))
{
- printf("phy duplex read failed \n\r");
+ printf("phy duplex read failed \n");
miiphy_dump();
}
--- /dev/null
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o flash.o board_init.o ns16550.o ns87308.o serial.o speed.o
+#eepro100.o
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $^
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# Sandpoint boards
+#
+
+TEXT_BASE = 0xFE000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <mpc8240.h>
+#include <asm/processor.h>
+#include <asm/pci_io.h>
+#include "w83c553f.h"
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+ulong flash_get_size (vu_long *addr, flash_info_t *info);
+
+int flash_write (uchar *, ulong, ulong);
+flash_info_t *addr2info (ulong);
+
+static int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+static int flash_protect (int flag, ulong from, ulong to, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ * Protection Flags:
+ */
+#define FLAG_PROTECT_SET 0x01
+#define FLAG_PROTECT_CLEAR 0x02
+
+/*flash command address offsets*/
+
+#define ADDR0 (0x555)
+#define ADDR1 (0x2AA)
+#define ADDR3 (0x001)
+
+#define FLASH_WORD_SIZE unsigned char
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+ unsigned long size;
+ int i;
+ unsigned long base;
+ register unsigned long temp;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* Static FLASH Bank configuration here - FIXME XXX */
+
+ /*Enable writes to Sandpoint flash*/
+ printf("setting flash write enable\n");
+ CONFIG_READ_BYTE(CFG_WINBOND_ISA_CFG_ADDR + WINBOND_CSCR, temp);
+ temp &= 0xDF; /* clear BIOSWP bit */
+ CONFIG_WRITE_BYTE(CFG_WINBOND_ISA_CFG_ADDR + WINBOND_CSCR, temp);
+
+ size = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size, size<<20);
+ }
+
+
+ flash_get_offsets (base, &flash_info[0]);
+
+ /* monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET,
+ base + size-CFG_MONITOR_LEN,
+ base + size - 1,
+ &flash_info[0]);
+
+
+ flash_info[1].flash_id = FLASH_UNKNOWN;
+ flash_info[1].sector_count = -1;
+
+ flash_info[0].size = size;
+
+ return (size);
+}
+
+/*-----------------------------------------------------------------------
+ * Check or set protection status for monitor sectors
+ *
+ * The monitor always occupies the _first_ part of the _first_ Flash bank.
+ */
+static int flash_protect (int flag, ulong from, ulong to, flash_info_t *info)
+{
+ ulong b_end = info->start[0] + info->size - 1; /* bank end address */
+ int rc = 0;
+ int first = -1;
+ int last = -1;
+ int i;
+
+ if (to < info->start[0]) {
+ return (0);
+ }
+
+ for (i=0; i<info->sector_count; ++i) {
+ ulong end; /* last address in current sect */
+ short s_end;
+
+ s_end = info->sector_count - 1;
+
+ end = (i == s_end) ? b_end : info->start[i + 1] - 1;
+
+ if (from > end) {
+ continue;
+ }
+ if (to < info->start[i]) {
+ continue;
+ }
+
+ if (from == info->start[i]) {
+ first = i;
+ if (last < 0) {
+ last = s_end;
+ }
+ }
+ if (to == end) {
+ last = i;
+ if (first < 0) {
+ first = 0;
+ }
+ }
+ }
+
+ for (i=first; i<=last; ++i) {
+ if (flag & FLAG_PROTECT_CLEAR) {
+ info->protect[i] = 0;
+ } else if (flag & FLAG_PROTECT_SET) {
+ info->protect[i] = 1;
+ }
+ if (info->protect[i]) {
+ rc = 1;
+ }
+ }
+ return (rc);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+
+ /* set up sector start adress table */
+ if (info->flash_id & FLASH_MAN_SST)
+ {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ }
+ else
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t *info)
+{
+ int i;
+ int k;
+ int size;
+ int erased;
+ volatile unsigned long *flash;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD: printf ("AMD "); break;
+ case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
+ case FLASH_MAN_SST: printf ("SST "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+ break;
+ case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+ break;
+ default: printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i=0; i<info->sector_count; ++i) {
+ /*
+ * Check if whole sector is erased
+ */
+ if (i != (info->sector_count-1))
+ size = info->start[i+1] - info->start[i];
+ else
+ size = info->start[0] + info->size - info->start[i];
+ erased = 1;
+ flash = (volatile unsigned long *)info->start[i];
+ size = size >> 2; /* divide by 4 for longword access */
+ for (k=0; k<size; k++)
+ {
+ if (*flash++ != 0xffffffff)
+ {
+ erased = 0;
+ break;
+ }
+ }
+
+ if ((i % 5) == 0)
+ printf ("\n ");
+#if 0 /* test-only */
+ printf (" %08lX%s",
+ info->start[i],
+ info->protect[i] ? " (RO)" : " "
+#else
+ printf (" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ",
+ info->protect[i] ? "RO " : " "
+#endif
+ );
+ }
+ printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+ short i;
+ FLASH_WORD_SIZE value;
+ ulong base = (ulong)addr;
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+ printf("flash_get_size: \n");
+ /* Write auto select command: read Manufacturer ID */
+ eieio();
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0xAA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x55;
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x90;
+ value = addr2[0];
+
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (FLASH_WORD_SIZE)FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (FLASH_WORD_SIZE)SST_MANUFACT:
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+ printf("recognised manufacturer");
+
+ value = addr2[ADDR3]; /* device ID */
+ // printf("\ndev_code=%x\n", value);
+
+ switch (value) {
+ case (FLASH_WORD_SIZE)AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+#if 0 /* enable when device IDs are available */
+ case (FLASH_WORD_SIZE)AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 67;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 67;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+#endif
+ case (FLASH_WORD_SIZE)SST_ID_xF800A:
+ info->flash_id += FLASH_SST800A;
+ info->sector_count = 16;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (FLASH_WORD_SIZE)SST_ID_xF160A:
+ info->flash_id += FLASH_SST160A;
+ info->sector_count = 32;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (FLASH_WORD_SIZE)AMD_ID_F040B:
+ info->flash_id += FLASH_AM040B;
+ info->sector_count = 8;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+
+ }
+
+ printf("flash id %lx; sector count %x, size %lx\n", info->flash_id,info->sector_count,info->size);
+ /* set up sector start adress table */
+ if (info->flash_id & FLASH_MAN_SST)
+ {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ }
+ else
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+ if (info->flash_id & FLASH_MAN_SST)
+ info->protect[i] = 0;
+ else
+ info->protect[i] = addr2[2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ addr2 = (FLASH_WORD_SIZE *)info->start[0];
+ *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+ }
+
+ return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+void flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+ int flag, prot, sect, l_sect;
+ ulong start, now, last;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("- missing\n");
+ } else {
+ printf ("- no sectors to erase\n");
+ }
+ return;
+ }
+
+ if ((info->flash_id == FLASH_UNKNOWN) ||
+ (info->flash_id > FLASH_AMD_COMP)) {
+ printf ("Can't erase unknown flash type - aborted\n");
+ return;
+ }
+
+ prot = 0;
+ for (sect=s_first; sect<=s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf ("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf ("\n");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+ if (info->flash_id & FLASH_MAN_SST)
+ {
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+ addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
+ udelay(30000); /* wait 30 ms */
+ }
+ else
+ addr[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
+ l_sect = sect;
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+
+ start = get_timer (0);
+ last = start;
+ addr = (FLASH_WORD_SIZE *)(info->start[l_sect]);
+ while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ serial_putc ('.');
+ last = now;
+ }
+ }
+
+DONE:
+ /* reset to read mode */
+ addr = (FLASH_WORD_SIZE *)info->start[0];
+ addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
+
+ printf (" done\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+flash_info_t *addr2info (ulong addr)
+{
+ flash_info_t *info;
+ int i;
+
+ for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
+ if ((addr >= info->start[0]) &&
+ (addr <= (info->start[0] + info->size - 1)) ) {
+ return (info);
+ }
+ }
+
+ return (NULL);
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ * Make sure all target addresses are within Flash bounds,
+ * and no protected sectors are hit.
+ * Returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 4 - target range includes protected sectors
+ * 8 - target address not in Flash memory
+ */
+int flash_write (uchar *src, ulong addr, ulong cnt)
+{
+ int i;
+ ulong end = addr + cnt - 1;
+ flash_info_t *info_first = addr2info (addr);
+ flash_info_t *info_last = addr2info (end );
+ flash_info_t *info;
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ if (!info_first || !info_last) {
+ return (8);
+ }
+
+ for (info = info_first; info <= info_last; ++info) {
+ ulong b_end = info->start[0] + info->size; /* bank end addr */
+ short s_end = info->sector_count - 1;
+ for (i=0; i<info->sector_count; ++i) {
+ ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
+
+ if ((end >= info->start[i]) && (addr < e_addr) &&
+ (info->protect[i] != 0) ) {
+ return (4);
+ }
+ }
+ }
+
+ /* finally write data to flash */
+ for (info = info_first; info <= info_last && cnt>0; ++info) {
+ ulong len;
+
+ len = info->start[0] + info->size - addr;
+ if (len > cnt)
+ len = cnt;
+ if ((i = write_buff(info, src, addr, len)) != 0) {
+ return (i);
+ }
+ cnt -= len;
+ addr += len;
+ src += len;
+ }
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+static int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i=0, cp=wp; i<l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+ for (; i<4 && cnt>0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt==0 && i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i=0; i<4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i<4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *)cp);
+ }
+
+ return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
+ volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
+ ulong start;
+ int flag;
+ int i;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((volatile FLASH_WORD_SIZE *)dest) &
+ (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
+ {
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+ addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+ addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
+
+ dest2[i] = data2[i];
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
+ (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <mpc8240.h>
+#include <asm/processor.h>
+
+
+/****************************************************************************/
+
+static __inline__ unsigned long get_msr(void)
+{
+ unsigned long msr;
+
+ asm volatile("mfmsr %0" : "=r" (msr) :);
+ return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+ asm volatile("mtmsr %0" : : "r" (msr));
+}
+
+static __inline__ unsigned long get_dec(void)
+{
+ unsigned long val;
+
+ asm volatile("mfdec %0" : "=r" (val) :);
+ return val;
+}
+
+
+static __inline__ void set_dec(unsigned long val)
+{
+ asm volatile("mtdec %0" : : "r" (val));
+}
+
+
+void enable_interrupts (void)
+{
+ set_msr (get_msr() | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int disable_interrupts (void)
+{
+ ulong msr = get_msr();
+ set_msr (msr & ~MSR_EE);
+ return ((msr & MSR_EE) != 0);
+}
+
+/****************************************************************************/
+
+void
+interrupt_init (bd_t *bd)
+{
+
+ set_msr (get_msr() | MSR_EE);
+}
+
+/****************************************************************************/
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt(struct pt_regs *regs)
+{
+
+}
+
+/****************************************************************************/
+
+/*
+ * blank int handlers.
+ */
+
+void
+irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+}
+
+void
+irq_free_handler(int vec)
+{
+
+}
+
+/*TODO: some handlers for winbond and 87308 interrupts
+ and what about generic pci inteerupts?
+ vga?
+ */
+
+volatile ulong timestamp = 0;
+
+void timer_interrupt(struct pt_regs *regs)
+{
+ timestamp++;
+}
+
+void reset_timer (void)
+{
+ timestamp = 0;
+}
+
+ulong get_timer (ulong base)
+{
+ return (timestamp - base);
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _INTERRUPTS_H_
+#define _INTERRUPTS_H_
+
+void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
+
+void irq_free_handler(int vec);
+
+#endif
--- /dev/null
+/*
+ * COM1 NS16550 support
+ * originally from linux source (arch/ppc/boot/ns16550.c)
+ * modified to use CFG_ISA_MEM and new defines
+ */
+
+#include <config.h>
+#include "ns16550.h"
+
+typedef struct NS16550 *NS16550_t;
+
+const NS16550_t COM_PORTS[] = { (NS16550_t) (CFG_ISA_IO + COM1),
+ (NS16550_t) (CFG_ISA_IO + COM2) };
+
+volatile struct NS16550 *
+NS16550_init(int chan, int baud_divisor)
+{
+ volatile struct NS16550 *com_port;
+ com_port = (struct NS16550 *) COM_PORTS[chan];
+ com_port->ier = 0x00;
+ com_port->lcr = LCR_BKSE; /* Access baud rate */
+ com_port->dll = baud_divisor & 0xff; /* 9600 baud */
+ com_port->dlm = (baud_divisor >> 8) & 0xff;
+ com_port->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */
+ com_port->mcr = MCR_DTR | MCR_RTS; /* RTS/DTR */
+ com_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR; /* Clear & enable FIFOs */
+ return (com_port);
+}
+
+void
+NS16550_reinit(volatile struct NS16550 *com_port, int baud_divisor)
+{
+ com_port->ier = 0x00;
+ com_port->lcr = LCR_BKSE; /* Access baud rate */
+ com_port->dll = baud_divisor & 0xff; /* 9600 baud */
+ com_port->dlm = (baud_divisor >> 8) & 0xff;
+ com_port->lcr = LCR_8N1; /* 8 data, 1 stop, no parity */
+ com_port->mcr = MCR_DTR | MCR_RTS; /* RTS/DTR */
+ com_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR; /* Clear & enable FIFOs */
+}
+
+void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
+{
+ while ((com_port->lsr & LSR_THRE) == 0) ;
+ com_port->thr = c;
+}
+
+unsigned char
+NS16550_getc(volatile struct NS16550 *com_port)
+{
+ while ((com_port->lsr & LSR_DR) == 0) ;
+ return (com_port->rbr);
+}
+
+int NS16550_tstc(volatile struct NS16550 *com_port)
+{
+ return ((com_port->lsr & LSR_DR) != 0);
+}
+
+
+
--- /dev/null
+/*
+ * NS16550 Serial Port
+ * originally from linux source (arch/ppc/boot/ns16550.h)
+ * modified slightly to
+ * have addresses as offsets from CFG_ISA_BASE
+ * added a few more definitions
+ * added prototypes for ns16550.c
+ * reduced no of com ports to 2
+ * modifications (c) Rob Taylor, Flying Pig Systems. 2000.
+ */
+
+
+struct NS16550
+ {
+ unsigned char rbr; /* 0 */
+ unsigned char ier; /* 1 */
+ unsigned char fcr; /* 2 */
+ unsigned char lcr; /* 3 */
+ unsigned char mcr; /* 4 */
+ unsigned char lsr; /* 5 */
+ unsigned char msr; /* 6 */
+ unsigned char scr; /* 7 */
+ };
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#define FCR_FIFO_EN 0x01 /*fifo enable*/
+#define FCR_RXSR 0x02 /*reciever soft reset*/
+#define FCR_TXSR 0x04 /*transmitter soft reset*/
+
+
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_DMA_EN 0x04
+#define MCR_TX_DFR 0x08
+
+
+#define LCR_WLS_MSK 0x03 /* character length slect mask*/
+#define LCR_WLS_5 0x00 /* 5 bit character length */
+#define LCR_WLS_6 0x01 /* 6 bit character length */
+#define LCR_WLS_7 0x02 /* 7 bit character length */
+#define LCR_WLS_8 0x03 /* 8 bit character length */
+#define LCR_STB 0x04 /* Number of stop Bits, off = 1, on = 1.5 or 2) */
+#define LCR_PEN 0x08 /* Parity eneble*/
+#define LCR_EPS 0x10 /* Even Parity Select*/
+#define LCR_STKP 0x20 /* Stick Parity*/
+#define LCR_SBRK 0x40 /* Set Break*/
+#define LCR_BKSE 0x80 /* Bank select enable*/
+
+#define LSR_DR 0x01 /* Data ready */
+#define LSR_OE 0x02 /* Overrun */
+#define LSR_PE 0x04 /* Parity error */
+#define LSR_FE 0x08 /* Framing error */
+#define LSR_BI 0x10 /* Break */
+#define LSR_THRE 0x20 /* Xmit holding register empty */
+#define LSR_TEMT 0x40 /* Xmitter empty */
+#define LSR_ERR 0x80 /* Error */
+
+/* useful defaults for LCR*/
+#define LCR_8N1 0x03
+
+
+#define COM1 0x03F8
+#define COM2 0x02F8
+
+volatile struct NS16550 * NS16550_init(int chan, int baud_divisor);
+void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c);
+unsigned char NS16550_getc(volatile struct NS16550 *com_port);
+int NS16550_tstc(volatile struct NS16550 *com_port);
+void NS16550_reinit(volatile struct NS16550 *com_port, int baud_divisor);
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#include <mpc8240.h>
+#include "ns87308.h"
+#include "ns16550.h" /*to configure the 87308's internal 16550's*/
+#include <asm/mc146818rtc.h> /* to configure 87308's RTC*/
+
+void initialise_ns87308 (void)
+{
+ PNP_SET_DEVICE_BASE(LDEV_UART1, COM1);
+ PNP_SET_DEVICE_BASE(LDEV_UART2, COM2);
+
+ PNP_SET_DEVICE_BASE(LDEV_RTC_APC, RTC_PORT(0));
+ PNP_ACTIVATE_DEVICE(LDEV_POWRMAN);
+
+ /* set up the NVRAM access registers
+ NVRAM's controlled by the configurable CS line from the 87308*/
+
+ PNP_PGCS_CSLINE_BASE(0, 0x76);
+ PNP_PGCS_CSLINE_CONF(0, 0x30);
+ PNP_PGCS_CSLINE_BASE(1, 0x75);
+ PNP_PGCS_CSLINE_CONF(1, 0x30);
+ PNP_PGCS_CSLINE_BASE(2, 0x74);
+ PNP_PGCS_CSLINE_CONF(2, 0x30);
+}
+/*
+void write_pnp_config(unsigned char index, unsigned char data)
+{
+ unsigned char *io_index = (unsigned char *) IO_INDEX;
+ unsigned char *io_data = (unsigned char *) IO_DATA;
+ *io_index = index;
+ *io_data = data;
+}
+
+void pnp_set_device(unsigned char dev)
+{
+ write_pnp_config(LOGICAL_DEVICE, dev);
+}
+*/
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _NS87308_H_
+#define _NS87308_H_
+
+#include <asm/pci_io.h>
+
+/* Note: I couldn't find a full data sheet for the ns87308, but the ns87307 seems to be pretty
+ functionally- (and pin-) equivalent to the 87308, but the 308 has better ir support. */
+
+/*PNP config registers:
+ * these depend on the stated of BADDR1 and BADDR0 on startup
+ * so there's three versions here with the last two digits indicating
+ * for which configuration their valid
+ * the 1st of the two digits indicates the state of BADDR1
+ * the 2st of the two digits indicates the state of BADDR0
+ */
+
+
+#define IO_INDEX_OFFSET_0x 0x0279 /* full PnP isa Mode */
+#define IO_INDEX_OFFSET_10 0x015C /* PnP motherboard mode */
+#define IO_INDEX_OFFSET_11 0x002E /* PnP motherboard mode */
+#define IO_DATA_OFFSET_0x 0x0A79 /* full PnP isa Mode */
+#define IO_DATA_OFFSET_10 0x015D /* PnP motherboard mode */
+#define IO_DATA_OFFSET_11 0x002F /* PnP motherboard mode */
+
+#if defined(CFG_NS87308_BADDR_0x)
+#define IO_INDEX (CFG_ISA_IO + IO_INDEX_OFFSET_0x)
+#define IO_DATA (CFG_ISA_IO + IO_DATA_OFFSET_0x)
+#elif defined(CFG_NS87308_BADDR_10)
+#define IO_INDEX (CFG_ISA_IO + IO_INDEX_OFFSET_10)
+#define IO_DATA (CFG_ISA_IO + IO_DATA_OFFSET_10)
+#elif defined(CFG_NS87308_BADDR_11)
+#define IO_INDEX (CFG_ISA_IO + IO_INDEX_OFFSET_11)
+#define IO_DATA (CFG_ISA_IO + IO_DATA_OFFSET_11)
+#endif
+
+/* PnP register definitions */
+
+#define SET_RD_DATA_PORT 0x00
+#define SERIAL_ISOLATION 0x01
+#define CONFIG_CONTROL 0x02
+#define WAKE_CSN 0x03
+#define RES_DATA 0x04
+#define STATUS 0x05
+#define SET_CSN 0x06
+#define LOGICAL_DEVICE 0x07
+/*vendor defined values */
+#define SID_REG 0x20
+#define SUPOERIO_CONF1 0x21
+#define SUPOERIO_CONF2 0x21
+#define PGCS_INDEX 0x22
+#define PGCS_DATA 0x22
+
+/* values above 30 are different for each logical device
+ but I can't be arsed to enter them all. the ones here
+ are pretty consistent between all logical devices
+ feel free to correct the situation if you want.. ;)
+ */
+#define ACTIVATE 0x30
+#define ACTIVATE_OFF 0x00
+#define ACTIVATE_ON 0x01
+
+#define BASE_ADDR_HIGH 0x60
+#define BASE_ADDR_LOW 0x61
+
+/* the logical devices*/
+#define LDEV_KBC1 0x00 /* 2 devices for keyboard and mouse controller*/
+#define LDEV_KBC2 0x01
+#define LDEV_RTC_APC 0x02 /*Real Time Clock and Advanced Power Control*/
+#define LDEV_FDC 0x03 /*floppy disk controller*/
+#define LDEV_PARP 0x04 /*Parallel port*/
+#define LDEV_UART1 0x05
+#define LDEV_UART2 0x06
+#define LDEV_GPIO 0x07 /*Gennerla Purpose IO and chip select output signals*/
+#define LDEV_POWRMAN 0x08 /*Power Managment*/
+
+/*some functions and macro's for doing configuration */
+
+static inline void write_pnp_config(unsigned char index, unsigned char data)
+{
+ pci_writeb(index,IO_INDEX);
+ pci_writeb(data, IO_DATA);
+}
+
+static inline void pnp_set_device(unsigned char dev)
+{
+ write_pnp_config(LOGICAL_DEVICE, dev);
+}
+
+
+/*void write_pnp_config(unsigned char index, unsigned char data);
+void pnp_set_device(unsigned char dev);
+*/
+
+#define PNP_SET_DEVICE_BASE(dev,base) \
+ pnp_set_device(dev); \
+ write_pnp_config(ACTIVATE, ACTIVATE_OFF); \
+ write_pnp_config(BASE_ADDR_HIGH, ((base) >> 8) & 0xff ); \
+ write_pnp_config(BASE_ADDR_LOW, (base) &0xff); \
+ write_pnp_config(ACTIVATE, ACTIVATE_ON);
+
+#define PNP_ACTIVATE_DEVICE(dev) \
+ pnp_set_device(dev); \
+ write_pnp_config(ACTIVATE, ACTIVATE_ON);
+
+#define PNP_DEACTIVATE_DEVICE(dev) \
+ pnp_set_device(dev); \
+ write_pnp_config(ACTIVATE, ACTIVATE_OFF);
+
+
+static inline void write_pgcs_config(unsigned char index, unsigned char data)
+{
+ write_pnp_config(PGCS_INDEX, index);
+ write_pnp_config(PGCS_DATA, data);
+}
+
+/* these macrose configure the 3 CS lines
+ on the sandpoint board these controll NVRAM
+ CS0 is connected to NVRAMCS
+ CS1 is connected to NVRAMAS0
+ CS2 is connected to NVRAMAS1
+ */
+#define PGCS_CS_ASSERT_ON_WRITE 0x10
+#define PGCS_CS_ASSERT_ON_READ 0x20
+
+#define PNP_PGCS_CSLINE_BASE(cs, base) \
+ write_pgcs_config((cs) << 2, ((base) >> 8) & 0xff ); \
+ write_pgcs_config(((cs) << 2) + 1, (base) & 0xff );
+
+#define PNP_PGCS_CSLINE_CONF(cs, conf) \
+ write_pgcs_config(((cs) << 2) + 2, (conf) );
+
+
+/* The following sections are for 87308 extensions to the standard compoents it emulates */
+
+/* extensions to 16550*/
+
+#define MCR_MDSL_MSK 0xe0 /*mode select mask*/
+#define MCR_MDSL_UART 0x00 /*uart, default*/
+#define MCR_MDSL_SHRPIR 0x02 /*Sharp IR*/
+#define MCR_MDSL_SIR 0x03 /*SIR*/
+#define MCR_MDSL_CIR 0x06 /*Consumer IR*/
+
+#define FCR_TXFTH0 0x10 /* these bits control threshod of data level in fifo */
+#define FCR_TXFTH1 0x20 /* for interrupt trigger */
+
+
+#endif /*_NS87308_H_*/
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems Ltd. robt@flyingpig.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+
+MEMORY {
+ ram (!rx) : org = 0x00000000 , LENGTH = 8M
+ code (!rx) : org = 0x00002000 , LENGTH = (4M - 0x2000)
+ rom (rx) : org = 0xfe000000 , LENGTH = (0x100000000 - 0xfe000000)
+}
+
+SECTIONS
+{
+ _f_init = .;
+ PROVIDE(_f_init = .);
+ _f_init_rom = .;
+ PROVIDE(_f_init_rom = .);
+
+ .init : {
+ mpc8240/start.o (.text)
+ *(.init)
+ } > ram
+ _init_size = SIZEOF(.init);
+ PROVIDE(_init_size = SIZEOF(.init));
+
+ ENTRY(_start)
+
+/* _ftext = .;
+ _ftext_rom = .;
+ _text_size = SIZEOF(.text);
+ */
+ .text : {
+ *(.text)
+ *(.got1)
+ } > ram
+ .rodata : { *(.rodata) } > ram
+ .dtors : { *(.dtors) } > ram
+ .data : { *(.data) } > ram
+ .sdata : { *(.sdata) } > ram
+ .sdata2 : { *(.sdata2)
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ } > ram
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .sbss : { *(.sbss) } > ram
+ .sbss2 : { *(.sbss2) } > ram
+ .bss : { *(.bss) } > ram
+ .debug : { *(.debug) } > ram
+ .line : { *(.line) } > ram
+ .symtab : { *(.symtab) } > ram
+ .shrstrtab : { *(.shstrtab) } > ram
+ .strtab : { *(.strtab) } > ram
+ /* .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ } > ram
+ */
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) } > ram
+ __stop___ex_table = .;
+
+
+ .ppcenv :
+ {
+ common/environment.o (.ppcenv)
+ } > ram
+
+ _end = . ;
+ PROVIDE (end = .);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems Ltd. robt@flyingpig.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+
+MEMORY {
+ ram (!rx) : org = 0x00000000 , LENGTH = 8M
+ code (!rx) : org = 0x00002000 , LENGTH = (4M - 0x2000)
+ rom (rx) : org = 0xfe000000 , LENGTH = (0x100000000 - 0xfe000000)
+}
+
+SECTIONS
+{
+ _f_init = .;
+ PROVIDE(_f_init = .);
+ _f_init_rom = .;
+ PROVIDE(_f_init_rom = .);
+
+ .init : {
+ mpc8240/start.o (.text)
+ *(.init)
+ } > ram
+ _init_size = SIZEOF(.init);
+ PROVIDE(_init_size = SIZEOF(.init));
+
+ ENTRY(_start)
+
+/* _ftext = .;
+ _ftext_rom = .;
+ _text_size = SIZEOF(.text);
+ */
+ .text : {
+ *(.text)
+ *(.got1)
+ } > ram
+ .rodata : { *(.rodata) } > ram
+ .dtors : { *(.dtors) } > ram
+ .data : { *(.data) } > ram
+ .sdata : { *(.sdata) } > ram
+ .sdata2 : { *(.sdata2)
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ } > ram
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .sbss : { *(.sbss) } > ram
+ .sbss2 : { *(.sbss2) } > ram
+ .bss : { *(.bss) } > ram
+ .debug : { *(.debug) } > ram
+ .line : { *(.line) } > ram
+ .symtab : { *(.symtab) } > ram
+ .shrstrtab : { *(.shstrtab) } > ram
+ .strtab : { *(.strtab) } > ram
+ /* .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ } > ram
+ */
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) } > ram
+ __stop___ex_table = .;
+
+
+ .ppcenv :
+ {
+ common/environment.o (.ppcenv)
+ } > ram
+
+ _end = . ;
+ PROVIDE (end = .);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+
+int checkboard (void)
+{
+ printf("Sandpoint ");
+ /*TODO: Check processor type*/
+ printf("8240 Unity ##Test not implemented yet##\n");
+ return 0;
+}
+
+int checkflash (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("8 MB ## Test not implemented yet ##\n");
+
+ return (0);
+}
+
+long int dram_size (int board_type)
+{
+ /* No actual initialisation to do - done when setting up PICRs MCCRs ME/SARs etc
+ * in cpu_init.c - done there to keep init sequence same as Dink. May be able to move some of
+ * it here and refine the configuration defines to be more high-level, but I haven't had time
+ * to investigate that yet
+ */
+ #if defined(CFG_MEM_TEST)
+
+ register unsigned long reg;
+
+ //write each mem addr with it's address
+ for (reg = CFG_MEM_TEST_START; reg < CGF_MEM_TEST_END; reg+=4
+ *reg = reg;
+
+ for (reg = CFG_MEM_TEST_START; reg < CGF_MEM_TEST_END; reg+=4
+ {
+ if (*reg != reg)
+ return -1;
+ }
+ #endif
+
+ //TODO: calculate amount of dram..for now just return MEMTEST_END
+ return CFG_MEMTEST_END;
+
+}
+
+long int initdram(int board_type)
+{
+return dram_size(board_type);
+}
+
+
+
+/*temporarlyily here: to be removed:*/
+
+
+int eth_init(bd_t *bis)
+{
+ /* Initialize the device */
+ return 0;
+}
+
+int eth_send(volatile void *packet, int length)
+{
+ /* Send a packet */
+ return 0;
+}
+
+int eth_rx(void)
+{
+ /* Check for received packets */
+ return 0;
+}
+
+void eth_halt(void)
+{
+ /* stop ethernet */
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "ns16550.h"
+
+void initialise_ns87308(void);
+
+/*
+ * Minimal serial functions needed to use one87308's UARTs
+ * as serial console interface.
+ */
+
+volatile struct NS16550 *console;
+
+void
+serial_init (unsigned long dummy, int baudrate)
+{
+ int clock_divisor = 115200/baudrate;
+ initialise_ns87308();
+ console = NS16550_init(0, clock_divisor);
+}
+
+void
+serial_putc(const char c)
+{
+ NS16550_putc(console, c);
+}
+
+void
+serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+
+int
+serial_getc(void)
+{
+ return NS16550_getc(console);
+}
+
+int
+serial_tstc(void)
+{
+ return NS16550_tstc(console);
+}
+
+void
+serial_setbrg (unsigned long dummy, int baudrate)
+{
+ int clock_divisor = 115200/baudrate;
+ NS16550_reinit(console, clock_divisor);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppcboot.h>
+#include <mpc8240.h>
+#include <asm/processor.h>
+#include "speed.h"
+
+/*use UART2 to measure bus speed*/
+#include "ns16550.h"
+
+
+/* Access functions for the Machine State Register */
+static __inline__ unsigned long get_msr(void)
+{
+ unsigned long msr;
+
+ asm volatile("mfmsr %0" : "=r" (msr) :);
+ return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+ asm volatile("mtmsr %0" : : "r" (msr));
+}
+
+/* ------------------------------------------------------------------------- */
+
+ulong get_bus_freq (ulong ignore)
+{
+ /* measure the bus frequency using UART2 */
+ /* 1st initilise it to run at 9600
+ it takes approx 10*(1/9600) us to sens an 8N1 character at 9600bps
+ but due to chrystal inaccuracies on sandpoint we use 1145us */
+
+ int count=0, start, end;
+ int i;
+ volatile struct NS16550 *uart2;
+
+ uart2=NS16550_init(1,115200/9600);
+
+
+ for (i =0; i< 10 ; i++)
+ {
+ NS16550_putc(uart2,0); /*send NUL*/
+ start=mfspr(DEC);
+ NS16550_putc(uart2,0); /*send NUL*/
+ end=mfspr(DEC);
+ count +=(start-end);
+ }
+
+ count /=10; /*average number of decrements per char send*/
+ count *=4; /*1 decrement per 4 bus cycles*/
+
+ /*time taken to do count cycles = 1145 us
+ therefore number of cycles per second is (1/(1145*10-6))*count
+ */
+ return (1000000/1145)*count;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Measure CPU clock speed
+ */
+
+/*table to convert pllratio to actual processor clock scaling factor (*10)*/
+/* if you are using a a different processor with your sandpoint,
+ have a look at pmc.c in the dink source for values, or
+ figure it out from the hardware book*/
+
+#ifdef CONFIG_MPC8240
+short pllratio_to_factor[] = {
+ 00, 00, 00, 10, 20, 20, 25, 00, 00, 00, 00, 00, 00, 00, 00, 00,
+ 00, 00, 00, 10, 00, 00, 00, 45, 30, 00, 40, 00, 00, 00, 35, 00,
+};
+#endif
+
+ulong get_gclk_freq (void)
+{
+ uint hid1;
+ hid1=mfspr(HID1);
+ #ifdef CONFIG_MPC8240
+ hid1=(hid1 >> (32-5)) & 0x1f; /* 5 bits for PLL ration on 8240*/
+ #else
+ hid1=(hid1 >> (32-4)) & 0xf; /* 4 bits on everythings else*/
+ #endif
+
+ return (pllratio_to_factor[hid1] * get_bus_freq(0))/10;
+
+}
+
+/* ------------------------------------------------------------------------- */
+
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*-----------------------------------------------------------------------
+ * Timer value for timer 2, ICLK = 10
+ *
+ * SPEED_FCOUNT2 = GCLK / (16 * (TIMER_TMR_PS + 1))
+ * SPEED_TMR3_PS = (GCLK / (16 * SPEED_FCOUNT3)) - 1
+ *
+ * SPEED_FCOUNT2 timer 2 counting frequency
+ * GCLK CPU clock
+ * SPEED_TMR2_PS prescaler
+ */
+#define SPEED_TMR2_PS (250 - 1) /* divide by 250 */
+
+/*-----------------------------------------------------------------------
+ * Timer value for PIT
+ *
+ * PIT_TIME = SPEED_PITC / PITRTCLK
+ * PITRTCLK = 8192
+ */
+#define SPEED_PITC (82 << 16) /* start counting from 82 */
+
+/*
+ * The new value for PTA is calculated from
+ *
+ * PTA = (gclk * Trefresh) / (2 ^ (2 * DFBRG) * PTP * NCS)
+ *
+ * gclk CPU clock (not bus clock !)
+ * Trefresh Refresh cycle * 4 (four word bursts used)
+ * DFBRG For normal mode (no clock reduction) always 0
+ * PTP Prescaler (already adjusted for no. of banks and 4K / 8K refresh)
+ * NCS Number of SDRAM banks (chip selects) on this UPM.
+ */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "w83c553f.h"
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* winbond access routines and defines*/
+
+/* from the winbond data sheet -
+ The W83C553F SIO controller with PCI arbiter is a multi-function PCI device.
+ Function 0 is the ISA bridge, and Function 1 is the bus master IDE controller.
+*/
+
+/*ISA bridge configuration space*/
+
+#define WINBOND_PCICONTR 0x40 /*pci control reg*/
+#define WINBOND_SGBAR 0x41 /*scatter/gather base address reg*/
+#define WINBOND_LBCR 0x42 /*Line Buffer Control reg*/
+#define WINBOND_IDEIRCR 0x43 /*IDE Interrupt Routing Control Reg*/
+#define WINBOND_PCIIRCR 0x44 /*PCI Interrupt Routing Control Reg*/
+#define WINBOND_BTBAR 0x46 /*BIOS Timer Base Address Register*/
+#define WINBOND_IPADCR 0x48 /*ISA to PCI Address Decoder Control Register*/
+#define WINBOND_IRADCR 0x49 /*ISA ROM Address Decoder Control Register*/
+#define WINBOND_IPMHSAR 0x4a /*ISA to PCI Memory Hole STart Address Register*/
+#define WINBOND_IPMHSR 0x4b /*ISA to PCI Memory Hols Size Register*/
+#define WINBOND_CDR 0x4c /*Clock Divisor Register*/
+#define WINBOND_CSCR 0x4d /*Chip Select Control Register*/
+#define WINBOND_ATSCR 0x4e /*AT System Control register*/
+#define WINBOND_ATBCR 0x4f /*AT Bus ControL Register*/
+#define WINBOND_IRQBEE0R 0x60 /*IRQ Break Event Enable 0 Register*/
+#define WINBOND_IRQBEE1R 0x61 /*IRQ Break Event Enable 1 Register*/
+#define WINBOND_ABEER 0x62 /*Additional Break Event Enable Register*/
+#define WINBOND_DMABEER 0x63 /*DMA Break Event Enable Register*/
+
+
CC = $(HOSTCC)
MAKEDEPEND = makedepend
+ifeq ($(OSTYPE),cygwin)
+all:
+.depend:
+else
all: $(BINS)
gdbsend: gdbsend.o error.o remote.o serial.o
-include .depend
#########################################################################
+
+endif # cygwin
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+
+/*nicked from gcc..*/
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+extern "C" {
+ void* alloca(size_t);
+}
+#endif /* alloca not defined. */
+
+
#include "serial.h"
#include "error.h"
#include "remote.h"
#include <string.h>
#include <elf.h>
#include <unistd.h>
+#include <errno.h>
extern int errno;
* Wolfgang Denk, wd@denx.de
* All rights reserved.
*
- * $Date: 2000/10/25 10:46:51 $
- * $Revision: 1.9 $
+ * $Date: 2000/11/16 20:16:58 $
+ * $Revision: 1.10 $
*/
#include <errno.h>
extern int errno;
+#ifndef MAP_FAILED
+#define MAP_FAILED -1
+#endif
+
char *cmdname;
extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len);
if (opt_type == IH_TYPE_MULTI) {
char *file = datafile;
- ulong size;
+ unsigned long size;
for (;;) {
char *sep = NULL;
if (hdr->ih_type == IH_TYPE_MULTI) {
int i;
- ulong *len_ptr = (ulong *)((ulong)hdr + sizeof(image_header_t));
+ unsigned long *len_ptr = (unsigned long *) (
+ (unsigned long)hdr + sizeof(image_header_t)
+ );
printf ("Contents:\n");
for (i=0; *len_ptr; ++i, ++len_ptr) {