Commit 327f7a020a3037ae8ef6c94488d5e9a3aa772943

Authored by wdenk
1 parent 12e4407c6a

Initial revision

Showing 27 changed files with 4866 additions and 0 deletions Side-by-side Diff

board/mousse/u-boot.lds.ram
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Rob Taylor, Flying Pig Systems Ltd. robt@flyingpig.com
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +OUTPUT_ARCH(powerpc)
  25 +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
  26 +
  27 +MEMORY {
  28 + ram (!rx) : org = 0x00000000 , LENGTH = 8M
  29 + code (!rx) : org = 0x00002000 , LENGTH = (4M - 0x2000)
  30 + rom (rx) : org = 0xfff00000 , LENGTH = 512K
  31 +}
  32 +
  33 +SECTIONS
  34 +{
  35 + _f_init = .;
  36 + PROVIDE(_f_init = .);
  37 + _f_init_rom = .;
  38 + PROVIDE(_f_init_rom = .);
  39 +
  40 + .init : {
  41 + cpu/mpc824x/start.o (.text)
  42 + *(.init)
  43 + } > ram
  44 + _init_size = SIZEOF(.init);
  45 + PROVIDE(_init_size = SIZEOF(.init));
  46 +
  47 + ENTRY(_start)
  48 +
  49 +/* _ftext = .;
  50 + _ftext_rom = .;
  51 + _text_size = SIZEOF(.text);
  52 + */
  53 + .text : {
  54 + *(.text)
  55 + *(.got1)
  56 + } > ram
  57 + .rodata : { *(.rodata) } > ram
  58 + .dtors : { *(.dtors) } > ram
  59 + .data : { *(.data) } > ram
  60 + .sdata : { *(.sdata) } > ram
  61 + .sdata2 : { *(.sdata2)
  62 + *(.got)
  63 + _GOT2_TABLE_ = .;
  64 + *(.got2)
  65 + _FIXUP_TABLE_ = .;
  66 + *(.fixup)
  67 + } > ram
  68 + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
  69 + __fixup_entries = (. - _FIXUP_TABLE_)>>2;
  70 +
  71 + .sbss : { *(.sbss) } > ram
  72 + .sbss2 : { *(.sbss2) } > ram
  73 + .bss : { *(.bss) } > ram
  74 + .debug : { *(.debug) } > ram
  75 + .line : { *(.line) } > ram
  76 + .symtab : { *(.symtab) } > ram
  77 + .shrstrtab : { *(.shstrtab) } > ram
  78 + .strtab : { *(.strtab) } > ram
  79 + /* .reloc :
  80 + {
  81 + *(.got)
  82 + _GOT2_TABLE_ = .;
  83 + *(.got2)
  84 + _FIXUP_TABLE_ = .;
  85 + *(.fixup)
  86 + } > ram
  87 + */
  88 + __start___ex_table = .;
  89 + __ex_table : { *(__ex_table) } > ram
  90 + __stop___ex_table = .;
  91 +
  92 +
  93 + .ppcenv :
  94 + {
  95 + common/environment.o (.ppcenv)
  96 + } > ram
  97 +
  98 + _end = . ;
  99 + PROVIDE (end = .);
  100 +}
board/sandpoint/early_init.S
  1 +/*
  2 + * (C) Copyright 2001
  3 + * Thomas Koeller, tkoeller@gmx.net
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +#ifndef __ASSEMBLY__
  25 +#define __ASSEMBLY__ 1
  26 +#endif
  27 +
  28 +#include <config.h>
  29 +#include <asm/processor.h>
  30 +#include <mpc824x.h>
  31 +#include <ppc_asm.tmpl>
  32 +
  33 +#if defined(USE_DINK32)
  34 + /* We are running from RAM, so do not clear the MCCR1_MEMGO bit! */
  35 + #define MCCR1VAL ((CFG_ROMNAL << MCCR1_ROMNAL_SHIFT) | (CFG_ROMFAL << MCCR1_ROMFAL_SHIFT) | MCCR1_MEMGO)
  36 +#else
  37 + #define MCCR1VAL (CFG_ROMNAL << MCCR1_ROMNAL_SHIFT) | (CFG_ROMFAL << MCCR1_ROMFAL_SHIFT)
  38 +#endif
  39 +
  40 + .text
  41 +
  42 + /* Values to program into memory controller registers */
  43 +tbl: .long MCCR1, MCCR1VAL
  44 + .long MCCR2, CFG_REFINT << MCCR2_REFINT_SHIFT
  45 + .long MCCR3
  46 + .long (((CFG_BSTOPRE & 0x000000f0) >> 4) << MCCR3_BSTOPRE2TO5_SHIFT) | \
  47 + (CFG_REFREC << MCCR3_REFREC_SHIFT) | \
  48 + (CFG_RDLAT << MCCR3_RDLAT_SHIFT)
  49 + .long MCCR4
  50 + .long (CFG_PRETOACT << MCCR4_PRETOACT_SHIFT) | (CFG_ACTTOPRE << MCCR4_ACTTOPRE_SHIFT) | \
  51 + (CFG_REGISTERD_TYPE_BUFFER << 20) | \
  52 + (((CFG_BSTOPRE & 0x00000300) >> 8) << MCCR4_BSTOPRE0TO1_SHIFT ) | \
  53 + ((CFG_SDMODE_CAS_LAT << 4) | (CFG_SDMODE_WRAP << 3) | \
  54 + (CFG_SDMODE_BURSTLEN) << MCCR4_SDMODE_SHIFT) | \
  55 + (CFG_ACTTORW << MCCR4_ACTTORW_SHIFT) | \
  56 + ((CFG_BSTOPRE & 0x0000000f) << MCCR4_BSTOPRE6TO9_SHIFT )
  57 + .long MSAR1
  58 + .long (((CFG_BANK0_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 0) | \
  59 + (((CFG_BANK1_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) | \
  60 + (((CFG_BANK2_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) | \
  61 + (((CFG_BANK3_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24)
  62 + .long EMSAR1
  63 + .long (((CFG_BANK0_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 0) | \
  64 + (((CFG_BANK1_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) | \
  65 + (((CFG_BANK2_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) | \
  66 + (((CFG_BANK3_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24)
  67 + .long MSAR2
  68 + .long (((CFG_BANK4_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 0) | \
  69 + (((CFG_BANK5_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) | \
  70 + (((CFG_BANK6_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) | \
  71 + (((CFG_BANK7_START & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24)
  72 + .long EMSAR2
  73 + .long (((CFG_BANK4_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 0) | \
  74 + (((CFG_BANK5_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) | \
  75 + (((CFG_BANK6_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) | \
  76 + (((CFG_BANK7_START & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24)
  77 + .long MEAR1
  78 + .long (((CFG_BANK0_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 0) | \
  79 + (((CFG_BANK1_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) | \
  80 + (((CFG_BANK2_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) | \
  81 + (((CFG_BANK3_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24)
  82 + .long EMEAR1
  83 + .long (((CFG_BANK0_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 0) | \
  84 + (((CFG_BANK1_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) | \
  85 + (((CFG_BANK2_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) | \
  86 + (((CFG_BANK3_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24)
  87 + .long MEAR2
  88 + .long (((CFG_BANK4_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 0) | \
  89 + (((CFG_BANK5_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 8) | \
  90 + (((CFG_BANK6_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 16) | \
  91 + (((CFG_BANK7_END & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT) << 24)
  92 + .long EMEAR2
  93 + .long (((CFG_BANK4_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 0) | \
  94 + (((CFG_BANK5_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 8) | \
  95 + (((CFG_BANK6_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 16) | \
  96 + (((CFG_BANK7_END & MICR_EADDR_MASK) >> MICR_EADDR_SHIFT) << 24)
  97 + .long 0
  98 +
  99 +
  100 +
  101 + /*
  102 + * Early CPU initialization. Set up memory controller, so we can access any RAM at all. This
  103 + * must be done in assembly, since we have no stack at this point.
  104 + */
  105 + .global early_init_f
  106 +early_init_f:
  107 + mflr r10
  108 +
  109 + /* basic memory controller configuration */
  110 + lis r3, CONFIG_ADDR_HIGH
  111 + lis r4, CONFIG_DATA_HIGH
  112 + bl lab
  113 +lab: mflr r5
  114 + lwzu r0, tbl - lab(r5)
  115 +loop: lwz r1, 4(r5)
  116 + stwbrx r0, 0, r3
  117 + eieio
  118 + stwbrx r1, 0, r4
  119 + eieio
  120 + lwzu r0, 8(r5)
  121 + cmpli cr0, 0, r0, 0
  122 + bne cr0, loop
  123 +
  124 + /* set bank enable bits */
  125 + lis r0, MBER@h
  126 + ori r0, 0, MBER@l
  127 + li r1, CFG_BANK_ENABLE
  128 + stwbrx r0, 0, r3
  129 + eieio
  130 + stb r1, 0(r4)
  131 + eieio
  132 +
  133 + /* delay loop */
  134 + lis r0, 0x0003
  135 + mtctr r0
  136 +delay: bdnz delay
  137 +
  138 + /* enable memory controller */
  139 + lis r0, MCCR1@h
  140 + ori r0, 0, MCCR1@l
  141 + stwbrx r0, 0, r3
  142 + eieio
  143 + lwbrx r0, 0, r4
  144 + oris r0, 0, MCCR1_MEMGO@h
  145 + stwbrx r0, 0, r4
  146 + eieio
  147 +
  148 + /* set up stack pointer */
  149 + lis r1, CFG_INIT_SP_OFFSET@h
  150 + ori r1, r1, CFG_INIT_SP_OFFSET@l
  151 +
  152 + mtlr r10
  153 + blr
board/sandpoint/u-boot.lds.mw.debug
  1 +/*
  2 + * (C) Copyright 2000
  3 + * Rob Taylor, Flying Pig Systems Ltd. robt@flyingpig.com
  4 + *
  5 + * See file CREDITS for list of people who contributed to this
  6 + * project.
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of
  11 + * the License, or (at your option) any later version.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +
  24 +OUTPUT_ARCH(powerpc)
  25 +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
  26 +
  27 +MEMORY {
  28 + ram (!rx) : org = 0x00000000 , LENGTH = 8M
  29 + code (!rx) : org = 0x00002000 , LENGTH = (4M - 0x2000)
  30 + rom (rx) : org = 0xfe000000 , LENGTH = (0x100000000 - 0xfe000000)
  31 +}
  32 +
  33 +SECTIONS
  34 +{
  35 + _f_init = .;
  36 + PROVIDE(_f_init = .);
  37 + _f_init_rom = .;
  38 + PROVIDE(_f_init_rom = .);
  39 +
  40 + .init : {
  41 + cpu/mpc824x/start.o (.text)
  42 + *(.init)
  43 + } > ram
  44 + _init_size = SIZEOF(.init);
  45 + PROVIDE(_init_size = SIZEOF(.init));
  46 +
  47 + ENTRY(_start)
  48 +
  49 +/* _ftext = .;
  50 + _ftext_rom = .;
  51 + _text_size = SIZEOF(.text);
  52 + */
  53 + .text : {
  54 + *(.text)
  55 + *(.got1)
  56 + } > ram
  57 + .rodata : { *(.rodata) } > ram
  58 + .dtors : { *(.dtors) } > ram
  59 + .data : { *(.data) } > ram
  60 + .sdata : { *(.sdata) } > ram
  61 + .sdata2 : { *(.sdata2)
  62 + *(.got)
  63 + _GOT2_TABLE_ = .;
  64 + *(.got2)
  65 + _FIXUP_TABLE_ = .;
  66 + *(.fixup)
  67 + } > ram
  68 + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
  69 + __fixup_entries = (. - _FIXUP_TABLE_)>>2;
  70 +
  71 + .sbss : { *(.sbss) } > ram
  72 + .sbss2 : { *(.sbss2) } > ram
  73 + .bss : { *(.bss) } > ram
  74 + .debug : { *(.debug) } > ram
  75 + .line : { *(.line) } > ram
  76 + .symtab : { *(.symtab) } > ram
  77 + .shrstrtab : { *(.shstrtab) } > ram
  78 + .strtab : { *(.strtab) } > ram
  79 + /* .reloc :
  80 + {
  81 + *(.got)
  82 + _GOT2_TABLE_ = .;
  83 + *(.got2)
  84 + _FIXUP_TABLE_ = .;
  85 + *(.fixup)
  86 + } > ram
  87 + */
  88 + __start___ex_table = .;
  89 + __ex_table : { *(__ex_table) } > ram
  90 + __stop___ex_table = .;
  91 +
  92 +
  93 + .ppcenv :
  94 + {
  95 + common/environment.o (.ppcenv)
  96 + } > ram
  97 +
  98 + _end = . ;
  99 + PROVIDE (end = .);
  100 +}
cpu/mpc824x/drivers/dma/Makefile
  1 +##########################################################################
  2 +#
  3 +# Copyright Motorola, Inc. 1997
  4 +# ALL RIGHTS RESERVED
  5 +#
  6 +# You are hereby granted a copyright license to use, modify, and
  7 +# distribute the SOFTWARE so long as this entire notice is retained
  8 +# without alteration in any modified and/or redistributed versions,
  9 +# and that such modified versions are clearly identified as such.
  10 +# No licenses are granted by implication, estoppel or otherwise under
  11 +# any patents or trademarks of Motorola, Inc.
  12 +#
  13 +# The SOFTWARE is provided on an "AS IS" basis and without warranty.
  14 +# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  15 +# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  16 +# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  17 +# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  18 +# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  19 +# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  20 +#
  21 +# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  22 +# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  23 +# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  24 +# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  25 +# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  26 +# INABILITY TO USE THE SOFTWARE.
  27 +#
  28 +############################################################################
  29 +TARGET = libdma.a
  30 +
  31 +DEBUG = -DDMADBG
  32 +LST = -Hanno -S
  33 +OPTIM =
  34 +CC = /risc/tools/pkgs/metaware/bin/hcppc
  35 +CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
  36 +CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
  37 +PREP = $(CC) $(CFLAGS) -P
  38 +
  39 +# Assembler used to build the .s files (for the board version)
  40 +
  41 +ASOPT = -big_si -c
  42 +ASDEBUG = -l -fm
  43 +AS = /risc/tools/pkgs/metaware/bin/asppc
  44 +
  45 +# Linker to bring .o files together into an executable.
  46 +
  47 +LKOPT = -Bbase=0 -q -r -Qn
  48 +LKCMD =
  49 +LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
  50 +
  51 +# DOS Utilities
  52 +
  53 +DEL = rm
  54 +COPY = cp
  55 +LIST = ls
  56 +
  57 +OBJECTS = dma1.o dma2.o
  58 +
  59 +all: $(TARGET)
  60 +
  61 +$(TARGET): $(OBJECTS)
  62 + $(LINK) $(OBJECTS) -o $@
  63 +
  64 +objects: dma1.o
  65 +
  66 +clean:
  67 + $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
  68 +
  69 +.s.o:
  70 + $(DEL) -f $*.i
  71 + $(PREP) -Hasmcpp $<
  72 + $(AS) $(ASOPT) $*.i
  73 +# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
  74 +
  75 +.c.o:
  76 + $(CCobj) $<
  77 +
  78 +.c.s:
  79 + $(CCobj) $(LST) $<
  80 +
  81 +dma1.o: dma_export.h dma.h dma1.c
  82 +
  83 +dma2.o: dma.h dma2.s
cpu/mpc824x/drivers/dma/Makefile_pc
  1 +##########################################################################
  2 +#
  3 +# makefile_pc for use with mksnt tools drivers/dma
  4 +#
  5 +# Copyright Motorola, Inc. 1997
  6 +# ALL RIGHTS RESERVED
  7 +#
  8 +# You are hereby granted a copyright license to use, modify, and
  9 +# distribute the SOFTWARE so long as this entire notice is retained
  10 +# without alteration in any modified and/or redistributed versions,
  11 +# and that such modified versions are clearly identified as such.
  12 +# No licenses are granted by implication, estoppel or otherwise under
  13 +# any patents or trademarks of Motorola, Inc.
  14 +#
  15 +# The SOFTWARE is provided on an "AS IS" basis and without warranty.
  16 +# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  17 +# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  18 +# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  19 +# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  20 +# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  21 +# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  22 +#
  23 +# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  24 +# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  25 +# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  26 +# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  27 +# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  28 +# INABILITY TO USE THE SOFTWARE.
  29 +#
  30 +############################################################################
  31 +TARGET = libdma.a
  32 +
  33 +DEBUG = -DDMADBG
  34 +LST = -Hanno -S
  35 +OPTIM =
  36 +CC = m:/old_tools/tools/hcppc/bin/hcppc
  37 +CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
  38 +CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
  39 +PREP = $(CC) $(CFLAGS) -P
  40 +
  41 +# Assembler used to build the .s files (for the board version)
  42 +
  43 +ASOPT = -big_si -c
  44 +ASDEBUG = -l -fm
  45 +AS = m:/old_tools/tools/hcppc/bin/asppc
  46 +
  47 +# Linker to bring .o files together into an executable.
  48 +
  49 +LKOPT = -Bbase=0 -q -r -Qn
  50 +LKCMD =
  51 +LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
  52 +
  53 +# DOS Utilities
  54 +
  55 +DEL = rm
  56 +COPY = cp
  57 +LIST = ls
  58 +
  59 +OBJECTS = dma1.o dma2.o
  60 +
  61 +all: $(TARGET)
  62 +
  63 +$(TARGET): $(OBJECTS)
  64 + $(LINK) $(OBJECTS) -o $@
  65 +
  66 +objects: dma1.o
  67 +
  68 +clean:
  69 + $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
  70 +
  71 +.s.o:
  72 + $(DEL) -f $*.i
  73 + $(PREP) -Hasmcpp $<
  74 + $(AS) $(ASOPT) $*.i
  75 +# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
  76 +
  77 +.c.o:
  78 + $(CCobj) $<
  79 +
  80 +.c.s:
  81 + $(CCobj) $(LST) $<
  82 +
  83 +dma1.o: dma_export.h dma.h dma1.c
  84 + $(CCobj) $<
  85 +
  86 +dma2.o: dma.h dma2.s
  87 + $(DEL) -f $*.i
  88 + $(PREP) -Hasmcpp $<
  89 + $(AS) $(ASOPT) $*.i
cpu/mpc824x/drivers/dma/README
  1 +CONTENT:
  2 +
  3 + dma.h
  4 + dma1.c
  5 + dma2.s
  6 +
  7 +WHAT ARE THESE FILES:
  8 +
  9 +These files contain MPC8240 (Kahlua) DMA controller
  10 +driver routines. The driver routines are not
  11 +written for any specific operating system.
  12 +They serves the purpose of code sample, and
  13 +jump-start for using the MPC8240 DMA controller.
  14 +
  15 +For the reason of correctness of C language
  16 +syntax, these files are compiled by Metaware
  17 +C compiler and assembler.
  18 +
  19 +ENDIAN NOTATION:
  20 +
  21 +The algorithm is designed for big-endian mode,
  22 +software is responsible for byte swapping.
  23 +
  24 +USAGE:
  25 +
  26 +1. The host system that is running on MPC8240
  27 + or using MPC8240 as I/O device shall link
  28 + the files listed here. The memory location
  29 + of driver routines shall take into account of
  30 + that driver routines need to run in supervisor
  31 + mode and they process DMA controller interrupt.
  32 +
  33 +2. The host system is responsible for configuring
  34 + the MPC8240 including Embedded Utilities Memory
  35 + Block. Since the DMA controller on MPC8240 can
  36 + be accessed by either local 603e core or the host
  37 + that MPC8240 serves as I/O processor through host
  38 + PCI configuration, it is important that the local
  39 + processor uses EUMBBAR to access its local DMA
  40 + controller while the PCI master uses I/O
  41 + processor's PCSRBAR to access the DMA controller
  42 + on I/O device.
  43 +
  44 + To qualify whether is EUMBBAR or PCSRBAR, one
  45 + additional parameter is requied from the host
  46 + system, LOCAL or REMOTE so that the base value
  47 + can be correctly interpreted.
  48 +
  49 +3. If the host system is also using the EPIC unit
  50 + on MPC8240, the system can register the
  51 + DMA_ISR with the EPIC including other
  52 + desired resources.
  53 +
  54 + If the host system does not using the EPIC unit
  55 + on MPC8240, DMA_ISR function can be called for
  56 + each desired time interval.
  57 +
  58 + In both cases, the host system is free to
  59 + provide its own interrupt service routine.
  60 +
  61 +4. To start a direct mode DMA transaction,
  62 + use DMA_Bld_Curr with the start parameter
  63 + set to 1.
  64 +
  65 + To start a chaining mode DMA transaction,
  66 + the application shall build descriptors
  67 + in memory first, next, use DMA_Bld_Desp
  68 + with the start parameter set to 1.
  69 +
  70 +5. DMA_Start function clears, then sets the CS
  71 + bit of DMA mode register.
  72 +
  73 + DMA_Halt function clears the CS bit of DMA
  74 + mode register.
  75 +
  76 + These functions can be used to start and
  77 + halt the DMA transaction.
  78 +
  79 + If the chaining descriptors has been
  80 + modified since the last time a DMA
  81 + transaction started, use DMA_Chn_Cnt
  82 + function to let DMA controller process
  83 + the modified descriptor chain without
  84 + stopping or disturbing the current DMA
  85 + transaction.
  86 +
  87 + It is the host system's responsibility of
  88 + setting up the correct DMA transfer mode
  89 + and pass the correct memory address parameters.
  90 +
  91 +6. It is the host system's responsibility of
  92 + queueing the DMA I/O request. The host
  93 + system can call the DMA_ISR with its own
  94 + desired interrupt service subroutines to
  95 + handle each individual interrupt and queued
  96 + DMA I/O requests.
  97 +
  98 +7. The DMA driver routines contains a set
  99 + of utilities, Set and Get, for host system
  100 + to query and modify the desired DMA registers.
cpu/mpc824x/drivers/dma/dma.h
  1 +#ifndef DMA_H
  2 +#define DMA_H
  3 +/*******************************************************
  4 + *
  5 + * copyright @ Motorola 1999
  6 + *
  7 + *******************************************************/
  8 +#define NUM_DMA_REG 7
  9 +#define DMA_MR_REG 0
  10 +#define DMA_SR_REG 1
  11 +#define DMA_CDAR_REG 2
  12 +#define DMA_SAR_REG 3
  13 +#define DMA_DAR_REG 4
  14 +#define DMA_BCR_REG 5
  15 +#define DMA_NDAR_REG 6
  16 +
  17 +typedef enum _dmastatus
  18 +{
  19 + DMASUCCESS = 0x1000,
  20 + DMALMERROR,
  21 + DMAPERROR,
  22 + DMACHNBUSY,
  23 + DMAEOSINT,
  24 + DMAEOCAINT,
  25 + DMAINVALID,
  26 + DMANOEVENT,
  27 +} DMAStatus;
  28 +
  29 +typedef enum _location
  30 +{
  31 + LOCAL = 0, /* local processor accesses on board DMA,
  32 + local processor's eumbbar is required */
  33 + REMOTE = 1, /* PCI master accesses DMA on I/O board,
  34 + I/O processor's pcsrbar is required */
  35 +} LOCATION;
  36 +
  37 +typedef enum dma_mr_bit
  38 +{
  39 + IRQS = 0x00080000,
  40 + PDE = 0x00040000,
  41 + DAHTS = 0x00030000,
  42 + SAHTS = 0x0000c000,
  43 + DAHE = 0x00002000,
  44 + SAHE = 0x00001000,
  45 + PRC = 0x00000c00,
  46 + EIE = 0x00000080,
  47 + EOTIE = 0x00000040,
  48 + DL = 0x00000008,
  49 + CTM = 0x00000004,
  50 + CC = 0x00000002,
  51 + CS = 0x00000001,
  52 +} DMA_MR_BIT;
  53 +
  54 +typedef enum dma_sr_bit
  55 +{
  56 + LME = 0x00000080,
  57 + PE = 0x00000010,
  58 + CB = 0x00000004,
  59 + EOSI = 0x00000002,
  60 + EOCAI = 0x00000001,
  61 +} DMA_SR_BIT;
  62 +
  63 +/* structure for DMA Mode Register */
  64 +typedef struct _dma_mr
  65 +{
  66 + unsigned int reserved0 : 12;
  67 + unsigned int irqs : 1;
  68 + unsigned int pde : 1;
  69 + unsigned int dahts : 2;
  70 + unsigned int sahts : 2;
  71 + unsigned int dahe : 1;
  72 + unsigned int sahe : 1;
  73 + unsigned int prc : 2;
  74 + unsigned int reserved1 : 1;
  75 + unsigned int eie : 1;
  76 + unsigned int eotie : 1;
  77 + unsigned int reserved2 : 3;
  78 + unsigned int dl : 1;
  79 + unsigned int ctm : 1;
  80 + /* if chaining mode is enabled, any time, user can modify the
  81 + * descriptor and does not need to halt the current DMA transaction.
  82 + * Set CC bit, enable DMA to process the modified descriptors
  83 + * Hardware will clear this bit each time, DMA starts.
  84 + */
  85 + unsigned int cc : 1;
  86 + /* cs bit has dua role, halt the current DMA transaction and
  87 + * (re)start DMA transaction. In chaining mode, if the descriptor
  88 + * needs modification, cs bit shall be used not the cc bit.
  89 + * Hardware will not set/clear this bit each time DMA transaction
  90 + * stops or starts. Software shall do it.
  91 + *
  92 + * cs bit shall not be used to halt chaining DMA transaction for
  93 + * modifying the descriptor. That is the role of CC bit.
  94 + */
  95 + unsigned int cs : 1;
  96 +} DMA_MR;
  97 +
  98 +/* structure for DMA Status register */
  99 +typedef struct _dma_sr
  100 +{
  101 + unsigned int reserved0 : 24;
  102 + unsigned int lme : 1;
  103 + unsigned int reserved1 : 2;
  104 + unsigned int pe : 1;
  105 + unsigned int reserved2 : 1;
  106 + unsigned int cb : 1;
  107 + unsigned int eosi : 1;
  108 + unsigned int eocai : 1;
  109 +} DMA_SR;
  110 +
  111 +/* structure for DMA current descriptor address register */
  112 +typedef struct _dma_cdar
  113 +{
  114 + unsigned int cda : 27;
  115 + unsigned int snen : 1;
  116 + unsigned int eosie : 1;
  117 + unsigned int ctt : 2;
  118 + unsigned int eotd : 1;
  119 +} DMA_CDAR;
  120 +
  121 +/* structure for DMA byte count register */
  122 +typedef struct _dma_bcr
  123 +{
  124 + unsigned int reserved : 6;
  125 + unsigned int bcr : 26;
  126 +} DMA_BCR;
  127 +
  128 +/* structure for DMA Next Descriptor Address register */
  129 +typedef struct _dma_ndar
  130 +{
  131 + unsigned int nda : 27;
  132 + unsigned int ndsnen : 1;
  133 + unsigned int ndeosie: 1;
  134 + unsigned int ndctt : 2;
  135 + unsigned int eotd : 1;
  136 +} DMA_NDAR;
  137 +
  138 +/* structure for DMA current transaction info */
  139 +typedef struct _dma_curr
  140 +{
  141 + unsigned int src_addr;
  142 + unsigned int dest_addr;
  143 + unsigned int byte_cnt;
  144 +} DMA_CURR;
  145 +
  146 +/************************* Kernel API********************
  147 + * Kernel APIs are used to interface with O.S. kernel.
  148 + * They are the functions required by O.S. kernel to
  149 + * provide I/O service.
  150 + ********************************************************/
  151 +
  152 +/**************DMA Device Control Functions ********/
  153 +
  154 +/**
  155 + * Note:
  156 + *
  157 + * In all following functions, the host (KAHLUA) processor has a
  158 + * choice of accessing on board local DMA (LOCAL),
  159 + * or DMA on a distributed KAHLUA (REMOTE). In either case,
  160 + * the caller shall pass the configured embedded utility memory
  161 + * block base address relative to the DMA. If LOCAL DMA is used,
  162 + * this parameter shall be EUMBBAR, if REMOTE is used, the
  163 + * parameter shall be the corresponding PCSRBAR.
  164 + **/
  165 +
  166 +/**************************************************************
  167 + * function: DMA_Get_Stat
  168 + *
  169 + * description: return the content of status register of
  170 + * the given DMA channel
  171 + * if error, return DMAINVALID. Otherwise return
  172 + * DMASUCCESS.
  173 + *
  174 + **************************************************************/
  175 +static DMAStatus DMA_Get_Stat( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_SR * );
  176 +
  177 +/**************************************************************
  178 + * function: DMA_Get_Mode
  179 + *
  180 + * description: return the content of mode register of the
  181 + * given DMA channel
  182 + * if error, return DMAINVALID. Otherwise return DMASUCCESS.
  183 + *
  184 + **************************************************************/
  185 +static DMAStatus DMA_Get_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR * );
  186 +
  187 +/**************************************************************
  188 + * function: DMA_Set_Mode
  189 + *
  190 + * description: Set a new mode to a given DMA channel
  191 + * return DMASUCCESS if success, otherwise return DMACHNINVALID
  192 + *
  193 + * note: It is not a good idea of changing the DMA mode during
  194 + * the middle of a transaction.
  195 + **************************************************************/
  196 +static DMAStatus DMA_Set_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR mode );
  197 +
  198 +/*************************************************************
  199 + * function: DMA_ISR
  200 + *
  201 + * description: DMA interrupt service routine
  202 + * return DMAStatus based on the status
  203 + *
  204 + *************************************************************/
  205 +static DMAStatus DMA_ISR( unsigned int eumbbar,
  206 + unsigned int channel,
  207 + DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
  208 + DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
  209 + DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
  210 + DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ));
  211 +
  212 +static DMAStatus dma_error_func( unsigned int, unsigned int, DMAStatus );
  213 +
  214 +/********************* DMA I/O function ********************/
  215 +
  216 +/************************************************************
  217 + * function: DMA_Start
  218 + *
  219 + * description: start a given DMA channel transaction
  220 + * return DMASUCCESS if success, otherwise return DMACHNINVALID
  221 + *
  222 + * note: this function will clear DMA_MR(CC) first, then
  223 + * set DMA_MR(CC).
  224 + ***********************************************************/
  225 +static DMAStatus DMA_Start( LOCATION, unsigned int eumbbar,unsigned int channel );
  226 +
  227 +/***********************************************************
  228 + * function: DMA_Halt
  229 + *
  230 + * description: halt the current dma transaction on the specified
  231 + * channel.
  232 + * return DMASUCCESS if success, otherwise return DMACHNINVALID
  233 + *
  234 + * note: if the specified DMA channel is idle, nothing happens
  235 + *************************************************************/
  236 +static DMAStatus DMA_Halt( LOCATION, unsigned int eumbbar,unsigned int channel );
  237 +
  238 +/*************************************************************
  239 + * function: DMA_Chn_Cnt
  240 + *
  241 + * description: set the DMA_MR(CC) bit for a given channel
  242 + * that is in chaining mode.
  243 + * return DMASUCCESS if successfule, otherwise return DMACHNINVALID
  244 + *
  245 + * note: if the given channel is not in chaining mode, nothing
  246 + * happen.
  247 + *
  248 + *************************************************************/
  249 +static DMAStatus DMA_Chn_Cnt( LOCATION, unsigned int eumbbar,unsigned int channel );
  250 +
  251 +/*********************** App. API ***************************
  252 + * App. API are the APIs Kernel provides for the application
  253 + * level program
  254 + ************************************************************/
  255 +/**************************************************************
  256 + * function: DMA_Bld_Curr
  257 + *
  258 + * description: set current src, dest, byte count registers
  259 + * according to the desp for a given channel
  260 + *
  261 + * if the given channel is busy, no change made,
  262 + * return DMACHNBUSY.
  263 + *
  264 + * otherwise return DMASUCCESS.
  265 + *
  266 + * note:
  267 + **************************************************************/
  268 +static DMAStatus DMA_Bld_Curr( LOCATION,
  269 + unsigned int eumbbar,
  270 + unsigned int channel,
  271 + DMA_CURR desp );
  272 +
  273 +/**************************************************************
  274 + * function: DMA_Poke_Curr
  275 + *
  276 + * description: poke the current src, dest, byte count registers
  277 + * for a given channel.
  278 + *
  279 + * return DMASUCCESS if no error otherwise return DMACHNERROR
  280 + *
  281 + * note: Due to the undeterministic parallelism, in chaining
  282 + * mode, the value returned by this function shall
  283 + * be taken as reference when the query is made rather
  284 + * than the absolute snapshot when the value is returned.
  285 + **************************************************************/
  286 +static DMAStatus DMA_Poke_Curr( LOCATION,
  287 + unsigned int eumbbar,
  288 + unsigned int channel,
  289 + DMA_CURR* desp );
  290 +
  291 +/**************************************************************
  292 + * function: DMA_Bld_Desp
  293 + *
  294 + * description: set current descriptor address register
  295 + * according to the desp for a given channel
  296 + *
  297 + * if the given channel is busy return DMACHNBUSY
  298 + * and no change made, otherwise return DMASUCCESS.
  299 + *
  300 + * note:
  301 + **************************************************************/
  302 +static DMAStatus DMA_Bld_Desp( LOCATION host,
  303 + unsigned int eumbbar,
  304 + unsigned int channel,
  305 + DMA_CDAR desp );
  306 +
  307 +/**************************************************************
  308 + * function: DMA_Poke_Desp
  309 + *
  310 + * description: poke the current descriptor address register
  311 + * for a given channel
  312 + *
  313 + * return DMASUCCESS if no error otherwise return
  314 + * DMAINVALID
  315 + *
  316 + * note: Due to the undeterministic parallellism of DMA operation,
  317 + * the value returned by this function shall be taken as
  318 + * the most recently used descriptor when the last time
  319 + * DMA starts a chaining mode operation.
  320 + **************************************************************/
  321 +static DMAStatus DMA_Poke_Desp( LOCATION,
  322 + unsigned int eumbbar,
  323 + unsigned int channel,
  324 + DMA_CDAR *desp );
  325 +
  326 +#endif
cpu/mpc824x/drivers/dma/dma1.c
  1 +/************************************************************
  2 + *
  3 + * copyright @ Motorola, 1999
  4 + *
  5 + * App. API
  6 + *
  7 + * App. API are the APIs Kernel provides for the application
  8 + * level program
  9 + *
  10 + ************************************************************/
  11 +#include "dma_export.h"
  12 +#include "dma.h"
  13 +
  14 +/* Define a macro to use an optional application-layer print function, if
  15 + * one was passed to the library during initialization. If there was no
  16 + * function pointer passed, this protects against referencing a NULL pointer.
  17 + * Also define The global variable that holds the passed pointer.
  18 + */
  19 +#define PRINT if ( app_print ) app_print
  20 +static int (*app_print)(char *,...);
  21 +
  22 +/* Set by call to get_eumbbar during DMA_Initialize.
  23 + * This could be globally available to the library, but there is
  24 + * an advantage to passing it as a parameter: it is already in a register
  25 + * and doesn't have to be loaded from memory. Also, that is the way the
  26 + * library was already implemented and I don't want to change it without
  27 + * a more detailed analysis.
  28 + * It is being set as a global variable during initialization to hide it from
  29 + * the DINK application layer, because it is Kahlua-specific. I think that
  30 + * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
  31 + * a Kahlua-specific library dealing with the embedded utilities memory block.
  32 + * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
  33 + * defined in dink32/drivers/i2c/i2c2.s, drivers/dma/dma2.s, etc.
  34 + */
  35 +static unsigned int Global_eumbbar = 0;
  36 +extern unsigned int get_eumbbar();
  37 +
  38 +
  39 +extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
  40 +#pragma Alias( load_runtime_reg, "load_runtime_reg" );
  41 +
  42 +extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
  43 +#pragma Alias( store_runtime_reg, "store_runtime_reg" );
  44 +
  45 +unsigned int dma_reg_tb[][14] = {
  46 + /* local DMA registers */
  47 + {
  48 + /* DMA_0_MR */ 0x00001100,
  49 + /* DMA_0_SR */ 0x00001104,
  50 + /* DMA_0_CDAR */ 0x00001108,
  51 + /* DMA_0_SAR */ 0x00001110,
  52 + /* DMA_0_DAR */ 0x00001118,
  53 + /* DMA_0_BCR */ 0x00001120,
  54 + /* DMA_0_NDAR */ 0x00001124,
  55 + /* DMA_1_MR */ 0x00001200,
  56 + /* DMA_1_SR */ 0x00001204,
  57 + /* DMA_1_CDAR */ 0x00001208,
  58 + /* DMA_1_SAR */ 0x00001210,
  59 + /* DMA_1_DAR */ 0x00001218,
  60 + /* DMA_1_BCR */ 0x00001220,
  61 + /* DMA_1_NDAR */ 0x00001224,
  62 + },
  63 + /* remote DMA registers */
  64 + {
  65 + /* DMA_0_MR */ 0x00000100,
  66 + /* DMA_0_SR */ 0x00000104,
  67 + /* DMA_0_CDAR */ 0x00000108,
  68 + /* DMA_0_SAR */ 0x00000110,
  69 + /* DMA_0_DAR */ 0x00000118,
  70 + /* DMA_0_BCR */ 0x00000120,
  71 + /* DMA_0_NDAR */ 0x00000124,
  72 + /* DMA_1_MR */ 0x00000200,
  73 + /* DMA_1_SR */ 0x00000204,
  74 + /* DMA_1_CDAR */ 0x00000208,
  75 + /* DMA_1_SAR */ 0x00000210,
  76 + /* DMA_1_DAR */ 0x00000218,
  77 + /* DMA_1_BCR */ 0x00000220,
  78 + /* DMA_1_NDAR */ 0x00000224,
  79 + },
  80 +};
  81 +
  82 +/* API functions */
  83 +
  84 +/* Initialize DMA unit with the following:
  85 + * optional pointer to application layer print function
  86 + *
  87 + * These parameters may be added:
  88 + * ???
  89 + * Interrupt enables, modes, etc. are set for each transfer.
  90 + *
  91 + * This function must be called before DMA unit can be used.
  92 + */
  93 +extern
  94 +DMA_Status DMA_Initialize( int (*p)(char *,...))
  95 +{
  96 + DMAStatus status;
  97 + /* establish the pointer, if there is one, to the application's "printf" */
  98 + app_print = p;
  99 +
  100 + /* If this is the first call, get the embedded utilities memory block
  101 + * base address. I'm not sure what to do about error handling here:
  102 + * if a non-zero value is returned, accept it.
  103 + */
  104 + if ( Global_eumbbar == 0)
  105 + Global_eumbbar = get_eumbbar();
  106 + if ( Global_eumbbar == 0)
  107 + {
  108 + PRINT( "DMA_Initialize: can't find EUMBBAR\n" );
  109 + return DMA_ERROR;
  110 + }
  111 +
  112 + return DMA_SUCCESS;
  113 +}
  114 +
  115 +
  116 +/* Perform the DMA transfer, only direct mode is currently implemented.
  117 + * At this point, I think it would be better to define a different
  118 + * function for chaining mode.
  119 + * Also, I'm not sure if it is appropriate to have the "generic" API
  120 + * accept snoop and int_steer parameters. The DINK user interface allows
  121 + * them, so for now I'll leave them.
  122 + *
  123 + * int_steer controls DMA interrupt steering to PCI or local processor
  124 + * type is the type of transfer: M2M, M2P, P2M, P2P
  125 + * source is the source address of the data
  126 + * dest is the destination address of the data
  127 + * len is the length of data to transfer
  128 + * channel is the DMA channel to use for the transfer
  129 + * snoop is the snoop enable control
  130 + */
  131 +extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
  132 + DMA_TRANSFER_TYPE type,
  133 + unsigned int source,
  134 + unsigned int dest,
  135 + unsigned int len,
  136 + DMA_CHANNEL channel,
  137 + DMA_SNOOP_MODE snoop)
  138 +{
  139 + DMA_MR md;
  140 + DMA_CDAR cdar;
  141 + /* it's inappropriate for curr to be a struct, but I'll leave it */
  142 + DMA_CURR curr;
  143 +
  144 + DMAStatus stat;
  145 +
  146 + /* The rest of this code was moved from device.c test_dma to here.
  147 + * It needs to be cleaned up and validated, but at least it is removed
  148 + * from the application and API. Most of the mode is left hard coded.
  149 + * This should be changed after the final API is defined and the user
  150 + * application has a way to control the transfer.
  151 + *
  152 + */
  153 +
  154 + if ( DMA_Get_Mode( LOCAL, Global_eumbbar, channel, &md ) != DMASUCCESS )
  155 + {
  156 + return DMA_ERROR;
  157 + }
  158 +
  159 + md.irqs = int_steer;
  160 + md.pde = 0;
  161 + md.dahts = 3; /* 8 - byte */
  162 + md.sahts = 3; /* 8 - byte */
  163 + md.dahe = 0;
  164 + md.sahe = 0;
  165 + md.prc = 0;
  166 + /* if steering interrupts to local processor, use polling mode */
  167 + if ( int_steer == DMA_INT_STEER_PCI )
  168 + {
  169 + md.eie = 1;
  170 + md.eotie = 1;
  171 + } else {
  172 + md.eie = 0;
  173 + md.eotie = 0;
  174 + }
  175 + md.dl = 0;
  176 + md.ctm = 1; /* direct mode */
  177 + md.cc = 0;
  178 +
  179 + /* validate the length range */
  180 + if (len > 0x3ffffff )
  181 + {
  182 + PRINT( "dev DMA: length of transfer too large: %d\n", len );
  183 + return DMA_ERROR;
  184 + }
  185 +
  186 + /* inappropriate to use a struct, but leave as is for now */
  187 + curr.src_addr = source;
  188 + curr.dest_addr = dest;
  189 + curr.byte_cnt = len;
  190 +
  191 + (void)DMA_Poke_Desp( LOCAL, Global_eumbbar, channel, &cdar );
  192 + cdar.snen = snoop;
  193 + cdar.ctt = type;
  194 +
  195 + if ( ( stat = DMA_Bld_Desp( LOCAL, Global_eumbbar, channel, cdar ))
  196 + != DMASUCCESS ||
  197 + ( stat = DMA_Bld_Curr( LOCAL, Global_eumbbar, channel, curr ))
  198 + != DMASUCCESS ||
  199 + ( stat = DMA_Set_Mode( LOCAL, Global_eumbbar, channel, md ))
  200 + != DMASUCCESS ||
  201 + ( stat = DMA_Start( LOCAL, Global_eumbbar, channel ))
  202 + != DMASUCCESS )
  203 + {
  204 + if ( stat == DMACHNBUSY )
  205 + {
  206 + PRINT( "dev DMA: channel %d busy.\n", channel );
  207 + }
  208 + else
  209 + {
  210 + PRINT( "dev DMA: invalid channel request.\n", channel );
  211 + }
  212 +
  213 + return DMA_ERROR;
  214 + }
  215 +
  216 +/* Since we are interested at the DMA performace right now,
  217 + we are going to do as less as possible to burden the
  218 + 603e core.
  219 +
  220 + if you have epic enabled or don't care the return from
  221 + DMA operation, you can just return SUCCESS.
  222 +
  223 + if you don't have epic enabled and care the DMA result,
  224 + you can use the polling method below.
  225 +
  226 + Note: I'll attempt to activate the code for handling polling.
  227 + */
  228 +
  229 +#if 0
  230 + /* if steering interrupt to local processor, let it handle results */
  231 + if ( int_steer == DMA_INT_STEER_LOCAL )
  232 + {
  233 + return DMA_SUCCESS;
  234 + }
  235 +
  236 + /* polling since interrupt goes to PCI */
  237 + do
  238 + {
  239 + stat = DMA_ISR( Global_eumbbar, channel, dma_error_func,
  240 + dma_error_func, dma_error_func, dma_error_func );
  241 + }
  242 + while ( stat == DMANOEVENT );
  243 +#endif
  244 +
  245 + return DMA_SUCCESS;
  246 +}
  247 +
  248 +/* DMA library internal functions */
  249 +
  250 +/**
  251 + * Note:
  252 + *
  253 + * In all following functions, the host (KAHLUA) processor has a
  254 + * choice of accessing on board local DMA (LOCAL),
  255 + * or DMA on a distributed KAHLUA (REMOTE). In either case,
  256 + * the caller shall pass the configured embedded utility memory
  257 + * block base address relative to the DMA. If LOCAL DMA is used,
  258 + * this parameter shall be EUMBBAR, if REMOTE is used, the
  259 + * parameter shall be the corresponding PCSRBAR.
  260 + **/
  261 +
  262 +/**************************************************************
  263 + * function: DMA_Get_Stat
  264 + *
  265 + * description: return the content of status register of
  266 + * the given DMA channel
  267 + *
  268 + * if error, reserved0 field all 1s.
  269 + **************************************************************/
  270 +static
  271 +DMAStatus DMA_Get_Stat( LOCATION host, unsigned int eumbbar, unsigned int channel, DMA_SR *stat )
  272 +{
  273 + unsigned int tmp;
  274 +
  275 + if ( channel != 0 && channel != 1 || stat == 0 )
  276 + {
  277 + return DMAINVALID;
  278 + }
  279 +
  280 + tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG] );
  281 +#ifdef DMADBG0
  282 + PRINT( "%s(%d): %s DMA %d (0x%08x) stat = 0x%08x\n", __FILE__, __LINE__,
  283 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG], tmp );
  284 +#endif
  285 +
  286 + stat->reserved0 = ( tmp & 0xffffff00 ) >> 8;
  287 + stat->lme = ( tmp & 0x00000080 ) >> 7;
  288 + stat->reserved1 = ( tmp & 0x00000060 ) >> 5;
  289 + stat->pe = ( tmp & 0x00000010 ) >> 4;
  290 + stat->reserved2 = ( tmp & 0x00000008 ) >> 3;
  291 + stat->cb = ( tmp & 0x00000004 ) >> 2;
  292 + stat->eosi = ( tmp & 0x00000002 ) >> 1;
  293 + stat->eocai = ( tmp & 0x00000001 );
  294 +
  295 + return DMASUCCESS;
  296 +}
  297 +
  298 +/**************************************************************
  299 + * function: DMA_Get_Mode
  300 + *
  301 + * description: return the content of mode register of the
  302 + * given DMA channel
  303 + *
  304 + * if error, return DMAINVALID, otherwise return
  305 + * DMASUCCESS
  306 + **************************************************************/
  307 +static
  308 +DMAStatus DMA_Get_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR *mode )
  309 +{
  310 + unsigned int tmp;
  311 + if ( channel != 0 && channel != 1 || mode == 0 )
  312 + {
  313 + return DMAINVALID;
  314 + }
  315 +
  316 + tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG] );
  317 +
  318 +#ifdef DMADBG0
  319 + PRINT( "%s(%d): %s DMA %d (0x%08x) mode = 0x%08x\n", __FILE__, __LINE__,
  320 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG], tmp );
  321 +#endif
  322 +
  323 + mode->reserved0 = (tmp & 0xfff00000) >> 20;
  324 + mode->irqs = (tmp & 0x00080000) >> 19;
  325 + mode->pde = (tmp & 0x00040000) >> 18;
  326 + mode->dahts = (tmp & 0x00030000) >> 16;
  327 + mode->sahts = (tmp & 0x0000c000) >> 14;
  328 + mode->dahe = (tmp & 0x00002000) >> 13;
  329 + mode->sahe = (tmp & 0x00001000) >> 12;
  330 + mode->prc = (tmp & 0x00000c00) >> 10;
  331 + mode->reserved1 = (tmp & 0x00000200) >> 9;
  332 + mode->eie = (tmp & 0x00000100) >> 8;
  333 + mode->eotie = (tmp & 0x00000080) >> 7;
  334 + mode->reserved2 = (tmp & 0x00000070) >> 4;
  335 + mode->dl = (tmp & 0x00000008) >> 3;
  336 + mode->ctm = (tmp & 0x00000004) >> 2;
  337 + mode->cc = (tmp & 0x00000002) >> 1;
  338 + mode->cs = (tmp & 0x00000001);
  339 +
  340 + return DMASUCCESS;
  341 +}
  342 +
  343 +/**************************************************************
  344 + * function: DMA_Set_Mode
  345 + *
  346 + * description: Set a new mode to a given DMA channel
  347 + *
  348 + * note: It is not a good idea of changing the DMA mode during
  349 + * the middle of a transaction.
  350 + **************************************************************/
  351 +static
  352 +DMAStatus DMA_Set_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR mode )
  353 +{
  354 + unsigned int tmp;
  355 + if ( channel != 0 && channel != 1 )
  356 + {
  357 + return DMAINVALID;
  358 + }
  359 +
  360 + tmp = ( mode.reserved0 & 0xfff ) << 20;
  361 + tmp |= ( ( mode.irqs & 0x1 ) << 19);
  362 + tmp |= ( ( mode.pde & 0x1 ) << 18 );
  363 + tmp |= ( ( mode.dahts & 0x3 ) << 16 );
  364 + tmp |= ( ( mode.sahts & 0x3 ) << 14 );
  365 + tmp |= ( ( mode.dahe & 0x1 ) << 13 );
  366 + tmp |= ( ( mode.sahe & 0x1 ) << 12 );
  367 + tmp |= ( ( mode.prc & 0x3 ) << 10 );
  368 + tmp |= ( ( mode.reserved1 & 0x1 ) << 9 );
  369 + tmp |= ( ( mode.eie & 0x1 ) << 8 );
  370 + tmp |= ( ( mode.eotie & 0x1 ) << 7 );
  371 + tmp |= ( ( mode.reserved2 & 0x7 ) << 4 );
  372 + tmp |= ( ( mode.dl & 0x1 ) << 3 );
  373 + tmp |= ( ( mode.ctm & 0x1 ) << 2 );
  374 + tmp |= ( ( mode.cc & 0x1 ) << 1 ) ;
  375 + tmp |= ( mode.cs & 0x1 );
  376 +
  377 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], tmp );
  378 + return DMASUCCESS;
  379 +}
  380 +
  381 +/************************************************************
  382 + * function: DMA_Start
  383 + *
  384 + * description: start a given DMA channel transaction
  385 + * return DMASUCCESS if success otherwise return
  386 + * DMAStatus value
  387 + *
  388 + * note: this function will clear DMA_MR(CC) first, then
  389 + * set DMA_MR(CC).
  390 + ***********************************************************/
  391 +static
  392 +DMAStatus DMA_Start( LOCATION host, unsigned int eumbbar, unsigned int channel )
  393 +{
  394 + DMA_SR stat;
  395 + unsigned int mode;
  396 +
  397 + if ( channel != 0 && channel != 1 )
  398 + {
  399 + return DMAINVALID;
  400 + }
  401 +
  402 + if ( DMA_Get_Stat( host, eumbbar, channel, &stat ) != DMASUCCESS )
  403 + {
  404 + return DMAINVALID;
  405 + }
  406 +
  407 + if ( stat.cb == 1 )
  408 + {
  409 + /* DMA is not free */
  410 + return DMACHNBUSY;
  411 + }
  412 +
  413 + mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG] );
  414 + /* clear DMA_MR(CS) */
  415 + mode &= 0xfffffffe;
  416 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
  417 +
  418 + /* set DMA_MR(CS) */
  419 + mode |= CS;
  420 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
  421 + return DMASUCCESS;
  422 +}
  423 +
  424 +/***********************************************************
  425 + * function: DMA_Halt
  426 + *
  427 + * description: halt the current dma transaction on the specified
  428 + * channel.
  429 + * return DMASUCCESS if success otherwise return DMAINVALID
  430 + *
  431 + * note: if the specified DMA channel is idle, nothing happens
  432 + *************************************************************/
  433 +static
  434 +DMAStatus DMA_Halt( LOCATION host, unsigned int eumbbar, unsigned int channel )
  435 +{
  436 + unsigned int mode;
  437 + if ( channel != 0 && channel != 1 )
  438 + {
  439 + return DMAINVALID;
  440 + }
  441 +
  442 + mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG]);
  443 +
  444 + /* clear DMA_MR(CS) */
  445 + mode &= 0xfffffffe;
  446 + store_runtime_reg(eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
  447 + return DMASUCCESS;
  448 +}
  449 +
  450 +/*************************************************************
  451 + * function: DMA_Chn_Cnt
  452 + *
  453 + * description: set the DMA_MR(CC) bit for a given channel
  454 + * that is in chaining mode.
  455 + * return DMASUCCESS if successfule, otherwise return
  456 + * DMAINVALID.
  457 + *
  458 + * note: if the given channel is not in chaining mode, nothing
  459 + * happen.
  460 + *
  461 + *************************************************************/
  462 +static
  463 +DMAStatus DMA_Chn_Cnt( LOCATION host, unsigned int eumbbar, unsigned int channel )
  464 +{
  465 + DMA_MR mode;
  466 + if ( channel != 0 && channel != 1 )
  467 + {
  468 + return DMAINVALID;
  469 + }
  470 +
  471 + if ( DMA_Get_Mode( host, eumbbar, channel, &mode ) != DMASUCCESS )
  472 + {
  473 + return DMAINVALID;
  474 + }
  475 +
  476 + if ( mode.ctm == 0 )
  477 + {
  478 + /* either illegal mode or not chaining mode */
  479 + return DMAINVALID;
  480 + }
  481 +
  482 + mode.cc = 1;
  483 + return DMA_Set_Mode( host, eumbbar, channel, mode );
  484 +}
  485 +
  486 +/**************************************************************
  487 + * function: DMA_Bld_Desp
  488 + *
  489 + * description: set current descriptor address register
  490 + * according to the desp for a given channel
  491 + *
  492 + * if the given channel is busy return DMACHNBUSY
  493 + * and no change made, otherwise return DMASUCCESS.
  494 + *
  495 + * note:
  496 + **************************************************************/
  497 +static
  498 +DMAStatus DMA_Bld_Desp( LOCATION host,
  499 + unsigned int eumbbar,
  500 + unsigned int channel,
  501 + DMA_CDAR desp )
  502 +{
  503 + DMA_SR status;
  504 + unsigned int temp;
  505 +
  506 + if ( channel != 0 && channel != 1 )
  507 + {
  508 + /* channel number out of range */
  509 + return DMAINVALID;
  510 + }
  511 +
  512 + if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
  513 + {
  514 + return DMAINVALID;
  515 + }
  516 +
  517 + if ( status.cb == 1 )
  518 + {
  519 + /* channel busy */
  520 + return DMACHNBUSY;
  521 + }
  522 +
  523 + temp = ( desp.cda & 0x7ffffff ) << 5;
  524 + temp |= (( desp.snen & 0x1 ) << 4 );
  525 + temp |= (( desp.eosie & 0x1 ) << 3 );
  526 + temp |= (( desp.ctt & 0x3 ) << 1 );
  527 + temp |= ( desp.eotd & 0x1 );
  528 +
  529 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
  530 +
  531 +#ifdef DMADBG0
  532 + PRINT( "%s(%d): %s DMA %d (0x%08x) cdar := 0x%08x\n", __FILE__, __LINE__,
  533 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
  534 +#endif
  535 +
  536 + return DMASUCCESS;
  537 +}
  538 +
  539 +/**************************************************************
  540 + * function: DMA_Poke_Desp
  541 + *
  542 + * description: poke the current descriptor address register
  543 + * for a given channel
  544 + *
  545 + * return DMASUCCESS if no error
  546 + *
  547 + * note: Due to the undeterministic parallellism of DMA operation,
  548 + * the value returned by this function shall be taken as
  549 + * the most recently used descriptor when the last time
  550 + * DMA starts a chaining mode operation.
  551 + **************************************************************/
  552 +static
  553 +DMAStatus DMA_Poke_Desp( LOCATION host,
  554 + unsigned int eumbbar,
  555 + unsigned int channel,
  556 + DMA_CDAR *desp )
  557 +{
  558 + unsigned int cdar;
  559 + if ( channel != 0 && channel != 1 || desp == 0 )
  560 + {
  561 + return DMAINVALID;
  562 + }
  563 +
  564 + cdar = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG] );
  565 +
  566 +#ifdef DMADBG0
  567 + PRINT( "%s(%d): %s DMA %d (0x%08x) cdar : 0x%08x\n", __FILE__, __LINE__,
  568 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], cdar );
  569 +#endif
  570 +
  571 +
  572 + desp->cda = ( cdar & 0xffffffe0 ) >> 5;
  573 + desp->snen = ( cdar & 0x00000010 ) >> 4;
  574 + desp->eosie = ( cdar & 0x00000008 ) >> 3;
  575 + desp->ctt = ( cdar & 0x00000006 ) >> 1;
  576 + desp->eotd = ( cdar & 0x00000001 );
  577 +
  578 + return DMASUCCESS;
  579 +}
  580 +
  581 +/**************************************************************
  582 + * function: DMA_Bld_Curr
  583 + *
  584 + * description: set current src, dest, byte count registers
  585 + * according to the desp for a given channel
  586 + * return DMASUCCESS if no error.
  587 + *
  588 + * note:
  589 + **************************************************************/
  590 +static
  591 +DMAStatus DMA_Bld_Curr( LOCATION host,
  592 + unsigned int eumbbar,
  593 + unsigned int channel,
  594 + DMA_CURR desp )
  595 +{
  596 + DMA_SR status;
  597 + if ( channel != 0 && channel != 1 )
  598 + {
  599 + /* channel number out of range */
  600 + return DMAINVALID;
  601 + }
  602 +
  603 + if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
  604 + {
  605 + return DMAINVALID;
  606 + }
  607 +
  608 + if ( status.cb == 1 )
  609 + {
  610 + /* channel busy */
  611 + return DMACHNBUSY;
  612 + }
  613 +
  614 + desp.byte_cnt &= 0x03ffffff; /* upper 6-bits are 0s */
  615 +
  616 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG], desp.src_addr );
  617 +#ifdef DMADBG0
  618 + PRINT( "%s(%d): %s DMA %d (0x%08x) src := 0x%08x\n", __FILE__, __LINE__,
  619 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.src_addr );
  620 +#endif
  621 +
  622 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG], desp.dest_addr );
  623 +#ifdef DMADBG0
  624 + PRINT( "%s(%d): %s DMA %d (0x%08x) dest := 0x%08x\n", __FILE__, __LINE__,
  625 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.dest_addr );
  626 +#endif
  627 +
  628 + store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG], desp.byte_cnt );
  629 +#ifdef DMADBG0
  630 + PRINT( "%s(%d): %s DMA %d (0x%08x) count := 0x%08x\n", __FILE__, __LINE__,
  631 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.byte_cnt );
  632 +#endif
  633 +
  634 +
  635 + return DMASUCCESS;
  636 +
  637 +}
  638 +
  639 +/**************************************************************
  640 + * function: DMA_Poke_Curr
  641 + *
  642 + * description: poke the current src, dest, byte count registers
  643 + * for a given channel.
  644 + *
  645 + * return DMASUCCESS if no error
  646 + *
  647 + * note: Due to the undeterministic parallelism, in chaining
  648 + * mode, the value returned by this function shall
  649 + * be taken as reference when the query is made rather
  650 + * than the absolute snapshot when the value is returned.
  651 + **************************************************************/
  652 +static
  653 +DMAStatus DMA_Poke_Curr( LOCATION host,
  654 + unsigned int eumbbar,
  655 + unsigned int channel,
  656 + DMA_CURR* desp )
  657 +{
  658 + if ( channel != 0 && channel != 1 || desp == 0 )
  659 + {
  660 + return DMAINVALID;
  661 + }
  662 +
  663 + desp->src_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG] );
  664 +#ifdef DMADBG0
  665 + PRINT( "%s(%d): %s DMA %d (0x%08x) src : 0x%08x\n", __FILE__, __LINE__,
  666 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->src_addr );
  667 +#endif
  668 +
  669 + desp->dest_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG] );
  670 +#ifdef DMADBG0
  671 + PRINT( "%s(%d): %s DMA %d (0x%08x) dest : 0x%08x\n", __FILE__, __LINE__,
  672 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->dest_addr );
  673 +#endif
  674 +
  675 + desp->byte_cnt = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG] );
  676 +#ifdef DMADBG0
  677 + PRINT( "%s(%d): %s DMA %d (0x%08x) count : 0x%08x\n", __FILE__, __LINE__,
  678 + ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->byte_cnt );
  679 +#endif
  680 +
  681 +
  682 + return DMASUCCESS;
  683 +}
  684 +
  685 +/*****************************************************************
  686 + * function: dma_error_func
  687 + *
  688 + * description: display the error information
  689 + *
  690 + * note: This seems like a highly convoluted way to handle messages,
  691 + * but I'll leave it as it was in device.c when I moved it into the
  692 + * DMA library source.
  693 + ****************************************************************/
  694 +static
  695 +DMAStatus dma_error_func( unsigned int eumbbar, unsigned int chn, DMAStatus err)
  696 +{
  697 + unsigned char *msg[] =
  698 + {
  699 + "Local Memory Error",
  700 + "PCI Error",
  701 + "Channel Busy",
  702 + "End-of-Segment Interrupt",
  703 + "End-of-Chain/Direct Interrupt",
  704 + };
  705 +
  706 + if ( err >= DMALMERROR && err <= DMAEOCAINT )
  707 + {
  708 + PRINT( "DMA Status: channel %d %s\n", chn, msg[err-DMASUCCESS-1] );
  709 + }
  710 +
  711 + return err;
  712 +
  713 +}
  714 +
  715 +/*************************************************************
  716 + * function: DMA_ISR
  717 + *
  718 + * description: DMA interrupt service routine
  719 + * return DMAStatus value based on
  720 + * the status
  721 + *
  722 + *************************************************************/
  723 +static
  724 +DMAStatus DMA_ISR( unsigned int eumbbar,
  725 + unsigned int channel,
  726 + DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
  727 + DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
  728 + DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
  729 + DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ))
  730 +{
  731 +
  732 + DMA_SR stat;
  733 + DMAStatus rval = DMANOEVENT;
  734 + unsigned int temp;
  735 +
  736 + if ( channel != 0 && channel != 1 )
  737 + {
  738 + return DMAINVALID;
  739 + }
  740 +
  741 + if ( DMA_Get_Stat( LOCAL, eumbbar, channel, &stat ) != DMASUCCESS )
  742 + {
  743 + return DMAINVALID;
  744 + }
  745 +
  746 + if ( stat.lme == 1 )
  747 + {
  748 + /* local memory error */
  749 + rval = DMALMERROR;
  750 + if ( lme_func != 0 )
  751 + {
  752 + rval = (*lme_func)(eumbbar, channel, DMALMERROR );
  753 + }
  754 +
  755 + }
  756 + else if ( stat.pe == 1 )
  757 + {
  758 + /* PCI error */
  759 + rval = DMAPERROR;
  760 + if ( pe_func != 0 )
  761 + {
  762 + rval = (*pe_func)(eumbbar, channel, DMAPERROR );
  763 + }
  764 +
  765 + }
  766 + else if ( stat.eosi == 1 )
  767 + {
  768 + /* end-of-segment interrupt */
  769 + rval = DMAEOSINT;
  770 + if ( eosi_func != 0 )
  771 + {
  772 + rval = (*eosi_func)(eumbbar, channel, DMAEOSINT );
  773 + }
  774 + }
  775 + else
  776 + {
  777 + /* End-of-chain/direct interrupt */
  778 + rval = DMAEOCAINT;
  779 + if ( eocai_func != 0 )
  780 + {
  781 + rval = (*eocai_func)(eumbbar, channel, DMAEOCAINT );
  782 + }
  783 + }
  784 +
  785 + temp = ( stat.reserved0 & 0xffffff ) << 8;
  786 + temp |= ( ( stat.lme & 0x1 ) << 7 ); /* write one to clear */
  787 + temp |= ( ( stat.reserved1 & 0x3 ) << 5 );
  788 + temp |= ( ( stat.pe & 0x1 ) << 4 ); /* write one to clear */
  789 + temp |= ( ( stat.reserved2 & 0x1 ) << 3 );
  790 + temp |= ( ( stat.cb & 0x1 ) << 2 ); /* write one to clear */
  791 + temp |= ( ( stat.eosi & 0x1 ) << 1 ); /* write one to clear */
  792 + temp |= ( stat.eocai & 0x1 ); /* write one to clear */
  793 +
  794 + store_runtime_reg( eumbbar, dma_reg_tb[LOCAL][channel*NUM_DMA_REG + DMA_SR_REG], temp );
  795 +
  796 +#ifdef DMADBG0
  797 + PRINT( "%s(%d): DMA channel %d SR := 0x%08x\n", __FILE__, __LINE__, channel, temp );
  798 +#endif
  799 +
  800 + return rval;
  801 +}
cpu/mpc824x/drivers/dma/dma2.S
  1 +/**************************************
  2 + *
  3 + * copyright @ Motorola, 1999
  4 + *
  5 + **************************************/
  6 +
  7 +/**********************************************************
  8 + * function: load_runtime_reg
  9 + *
  10 + * input: r3 - value of eumbbar
  11 + * r4 - register offset in embedded utility space
  12 + *
  13 + * output: r3 - register content
  14 + **********************************************************/
  15 + .text
  16 + .align 2
  17 + .global load_runtime_reg
  18 +
  19 +load_runtime_reg:
  20 +
  21 + lwbrx r3,r4,r3
  22 + sync
  23 +
  24 + bclr 20, 0
  25 +
  26 +/****************************************************************
  27 + * function: store_runtime_reg
  28 + *
  29 + * input: r3 - value of eumbbar
  30 + * r4 - register offset in embedded utility space
  31 + * r5 - new value to be stored
  32 + *
  33 + ****************************************************************/
  34 + .text
  35 + .align 2
  36 + .global store_runtime_reg
  37 +store_runtime_reg:
  38 +
  39 + stwbrx r5, r4, r3
  40 + sync
  41 +
  42 + bclr 20,0
cpu/mpc824x/drivers/dma/dma_export.h
  1 +#ifndef DMA_EXPORT_H
  2 +#define DMA_EXPORT_H
  3 +
  4 +/****************************************************
  5 + * $Id:
  6 + *
  7 + * Copyright Motorola 1999
  8 + *
  9 + * $Log:
  10 + *
  11 + ****************************************************/
  12 +
  13 +/* These are the defined return values for the DMA_* functions.
  14 + * Any non-zero value indicates failure. Failure modes can be added for
  15 + * more detailed error reporting.
  16 + */
  17 +typedef enum _dma_status
  18 +{
  19 + DMA_SUCCESS = 0,
  20 + DMA_ERROR,
  21 +} DMA_Status;
  22 +
  23 +/* These are the defined channel transfer types. */
  24 +typedef enum _dma_transfer_types
  25 +{
  26 + DMA_M2M = 0, /* local memory to local memory */
  27 + DMA_M2P = 1, /* local memory to PCI */
  28 + DMA_P2M = 2, /* PCI to local memory */
  29 + DMA_P2P = 3, /* PCI to PCI */
  30 +} DMA_TRANSFER_TYPE;
  31 +
  32 +typedef enum _dma_interrupt_steer
  33 +{
  34 + DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
  35 + DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
  36 +} DMA_INTERRUPT_STEER;
  37 +
  38 +typedef enum _dma_channel
  39 +{
  40 + DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
  41 + DMA_CHN_1 = 1,
  42 +} DMA_CHANNEL;
  43 +
  44 +typedef enum _dma_snoop_mode
  45 +{
  46 + DMA_SNOOP_DISABLE = 0,
  47 + DMA_SNOOP_ENABLE = 1,
  48 +} DMA_SNOOP_MODE;
  49 +
  50 +/******************** App. API ********************
  51 + * The application API is for user level application
  52 + * to use the functionality provided by DMA driver.
  53 + * This is a "generic" DMA interface, it should contain
  54 + * nothing specific to the Kahlua implementation.
  55 + * Only the generic functions are exported by the library.
  56 + *
  57 + * Note: Its App.s responsibility to swap the data
  58 + * byte. In our API, we currently transfer whatever
  59 + * we are given - Big/Little Endian. This could
  60 + * become part of the DMA config, though.
  61 + **************************************************/
  62 +
  63 +
  64 +/* Initialize DMA unit with the following:
  65 + * optional pointer to application layer print function
  66 + *
  67 + * These parameters may be added:
  68 + * ???
  69 + * Interrupt enables, modes, etc. are set for each transfer.
  70 + *
  71 + * This function must be called before DMA unit can be used.
  72 + */
  73 +extern DMA_Status DMA_Initialize(
  74 + int (*app_print_function)(char *,...)); /* pointer to optional "printf"
  75 + * provided by application
  76 + */
  77 +
  78 +/* Perform the DMA transfer, only direct mode is currently implemented.
  79 + * At this point, I think it would be better to define a different
  80 + * function for chaining mode.
  81 + * Also, I'm not sure if it is appropriate to have the "generic" API
  82 + * accept snoop and int_steer parameters. The DINK user interface allows
  83 + * them, so for now I'll leave them.
  84 + *
  85 + * int_steer controls DMA interrupt steering to PCI or local processor
  86 + * type is the type of transfer: M2M, M2P, P2M, P2P
  87 + * source is the source address of the data
  88 + * dest is the destination address of the data
  89 + * len is the length of data to transfer
  90 + * channel is the DMA channel to use for the transfer
  91 + * snoop is the snoop enable control
  92 + */
  93 +extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
  94 + DMA_TRANSFER_TYPE type,
  95 + unsigned int source,
  96 + unsigned int dest,
  97 + unsigned int len,
  98 + DMA_CHANNEL channel,
  99 + DMA_SNOOP_MODE snoop);
  100 +#endif
cpu/mpc824x/drivers/dma_export.h
  1 +#ifndef DMA_EXPORT_H
  2 +#define DMA_EXPORT_H
  3 +
  4 +/****************************************************
  5 + * $Id:
  6 + *
  7 + * Copyright Motorola 1999
  8 + *
  9 + * $Log:
  10 + *
  11 + ****************************************************/
  12 +
  13 +/* These are the defined return values for the DMA_* functions.
  14 + * Any non-zero value indicates failure. Failure modes can be added for
  15 + * more detailed error reporting.
  16 + */
  17 +typedef enum _dma_status
  18 +{
  19 + DMA_SUCCESS = 0,
  20 + DMA_ERROR,
  21 +} DMA_Status;
  22 +
  23 +/* These are the defined channel transfer types. */
  24 +typedef enum _dma_transfer_types
  25 +{
  26 + DMA_M2M = 0, /* local memory to local memory */
  27 + DMA_M2P = 1, /* local memory to PCI */
  28 + DMA_P2M = 2, /* PCI to local memory */
  29 + DMA_P2P = 3, /* PCI to PCI */
  30 +} DMA_TRANSFER_TYPE;
  31 +
  32 +typedef enum _dma_interrupt_steer
  33 +{
  34 + DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
  35 + DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
  36 +} DMA_INTERRUPT_STEER;
  37 +
  38 +typedef enum _dma_channel
  39 +{
  40 + DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
  41 + DMA_CHN_1 = 1,
  42 +} DMA_CHANNEL;
  43 +
  44 +typedef enum _dma_snoop_mode
  45 +{
  46 + DMA_SNOOP_DISABLE = 0,
  47 + DMA_SNOOP_ENABLE = 1,
  48 +} DMA_SNOOP_MODE;
  49 +
  50 +/******************** App. API ********************
  51 + * The application API is for user level application
  52 + * to use the functionality provided by DMA driver.
  53 + * This is a "generic" DMA interface, it should contain
  54 + * nothing specific to the Kahlua implementation.
  55 + * Only the generic functions are exported by the library.
  56 + *
  57 + * Note: Its App.s responsibility to swap the data
  58 + * byte. In our API, we currently transfer whatever
  59 + * we are given - Big/Little Endian. This could
  60 + * become part of the DMA config, though.
  61 + **************************************************/
  62 +
  63 +
  64 +/* Initialize DMA unit with the following:
  65 + * optional pointer to application layer print function
  66 + *
  67 + * These parameters may be added:
  68 + * ???
  69 + * Interrupt enables, modes, etc. are set for each transfer.
  70 + *
  71 + * This function must be called before DMA unit can be used.
  72 + */
  73 +extern DMA_Status DMA_Initialize(
  74 + int (*app_print_function)(char *,...)); /* pointer to optional "printf"
  75 + * provided by application
  76 + */
  77 +
  78 +/* Perform the DMA transfer, only direct mode is currently implemented.
  79 + * At this point, I think it would be better to define a different
  80 + * function for chaining mode.
  81 + * Also, I'm not sure if it is appropriate to have the "generic" API
  82 + * accept snoop and int_steer parameters. The DINK user interface allows
  83 + * them, so for now I'll leave them.
  84 + *
  85 + * int_steer controls DMA interrupt steering to PCI or local processor
  86 + * type is the type of transfer: M2M, M2P, P2M, P2P
  87 + * source is the source address of the data
  88 + * dest is the destination address of the data
  89 + * len is the length of data to transfer
  90 + * channel is the DMA channel to use for the transfer
  91 + * snoop is the snoop enable control
  92 + */
  93 +extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
  94 + DMA_TRANSFER_TYPE type,
  95 + unsigned int source,
  96 + unsigned int dest,
  97 + unsigned int len,
  98 + DMA_CHANNEL channel,
  99 + DMA_SNOOP_MODE snoop);
  100 +#endif
cpu/mpc824x/drivers/epic.h
  1 +#include "epic/epic.h"
cpu/mpc824x/drivers/epic/README
  1 +CONTENT:
  2 +
  3 + epic.h
  4 + epic1.c
  5 + epic2.s
  6 +
  7 +WHAT ARE THESE FILES:
  8 +
  9 +These files contain MPC8240 (Kahlua) EPIC
  10 +driver routines. The driver routines are not
  11 +written for any specific operating system.
  12 +They serves the purpose of code sample, and
  13 +jump-start for using the MPC8240 EPIC unit.
  14 +
  15 +For the reason of correctness of C language
  16 +syntax, these files are compiled by Metaware
  17 +C compiler and assembler.
  18 +
  19 +ENDIAN NOTATION:
  20 +
  21 +The algorithm is designed for big-endian mode,
  22 +software is responsible for byte swapping.
  23 +
  24 +USAGE:
  25 +
  26 +1. The host system that is running on MPC8240
  27 + shall link the files listed here. The memory
  28 + location of driver routines shall take into
  29 + account of that driver routines need to run
  30 + in supervisor mode and they process external
  31 + interrupts.
  32 +
  33 + The routine epic_exception shall be called by
  34 + exception vector at location 0x500, i.e.,
  35 + 603e core external exception vector.
  36 +
  37 +2. The host system is responsible for configuring
  38 + the MPC8240 including Embedded Utilities Memory
  39 + Block. All EPIC driver functions require the
  40 + content of Embedded Utilities Memory Block
  41 + Base Address Register, EUMBBAR, as the first
  42 + parameter.
  43 +
  44 +3. Before EPIC unit of MPC8240 can be used,
  45 + initialize EPIC unit by calling epicInit
  46 + with the corresponding parameters.
  47 +
  48 + The initialization shall disable the 603e
  49 + core External Exception by calling CoreExtIntDisable( ).
  50 + Next, call epicInit( ). Last, enable the 603e core
  51 + External Exception by calling CoreExtIntEnable( ).
  52 +
  53 +4. After EPIC unit has been successfully initialized,
  54 + epicIntSourceSet( ) shall be used to register each
  55 + external interrupt source. Anytime, an external
  56 + interrupt source can be disabled or enabled by
  57 + calling corresponding function, epicIntDisable( ),
  58 + or epicIntEnable( ).
  59 +
  60 + Global Timers' resource, base count and frequency,
  61 + can be changed by calling epicTmFrequencySet( )
  62 + and epicTmBaseSet( ).
  63 +
  64 + To stop counting a specific global timer, use
  65 + the function, epicTmInhibit while epicTmEnable
  66 + can be used to start counting a timer.
  67 +
  68 +5. To mask a set of external interrupts that are
  69 + are certain level below, epicIntPrioritySet( )
  70 + can be used. For example, if the processor's
  71 + current task priority register is set to 0x7,
  72 + only interrupts of priority 0x8 or higher will
  73 + be passed to the processor.
  74 +
  75 + Be careful when using this function. It may
  76 + corrupt the current interrupt pending, selector,
  77 + and request registers, resulting an invalid vetor.
  78 +
  79 + After enabling an interrupt, disable it may also
  80 + cause an invalid vector. User may consider using
  81 + the spurious vector interrupt service routine to
  82 + handle this case.
  83 +
  84 +6. The EPIC driver routines contains a set
  85 + of utilities, Set and Get, for host system
  86 + to query and modify the desired EPIC source
  87 + registers.
  88 +
  89 +7. Each external interrupt source shall register
  90 + its interrupt service routine. The routine
  91 + shall contain all interrupt source specific
  92 + processes and keep as short as possible.
  93 +
  94 + Special customized end of interrupt routine
  95 + is optional. If it is needed, it shall contain
  96 + the external interrupt source specific end of
  97 + interrupt process.
  98 +
  99 + External interrupt exception vector at 0x500
  100 + shall always call the epicEOI just before
  101 + rfi instruction. Refer to the routine,
  102 + epic_exception, for a code sample.
cpu/mpc824x/drivers/epic/epic2.S
  1 +/**************************************
  2 + *
  3 + * copyright @ Motorola, 1999
  4 + *
  5 + **************************************/
  6 +
  7 +#include <ppc_asm.tmpl>
  8 +#include <ppc_defs.h>
  9 +#include <asm/processor.h>
  10 +
  11 +/*********************************************
  12 + * function: CoreExtIntEnable
  13 + *
  14 + * description: Enable 603e core external interrupt
  15 + *
  16 + * note: mtmsr is context-synchronization
  17 + **********************************************/
  18 + .text
  19 + .align 2
  20 + .global CoreExtIntEnable
  21 +CoreExtIntEnable:
  22 + mfmsr r3
  23 +
  24 + ori r3,r3,0x8000 /* enable external interrupt */
  25 + mtmsr r3
  26 +
  27 + bclr 20, 0
  28 +
  29 +/*******************************************
  30 + * function: CoreExtIntDisable
  31 + *
  32 + * description: Disable 603e core external interrupt
  33 + *
  34 + * note:
  35 + *******************************************/
  36 + .text
  37 + .align 2
  38 + .global CoreExtIntDisable
  39 +CoreExtIntDisable:
  40 + mfmsr r4
  41 +
  42 + xor r3,r3,r3
  43 + or r3,r3,r4
  44 +
  45 + andis. r4,r4,0xffff
  46 + andi. r3,r3,0x7fff /* disable external interrupt */
  47 +
  48 + or r3,r3,r4
  49 + mtmsr r3
  50 +
  51 + bclr 20, 0
  52 +
  53 +/*********************************************************
  54 + * function: epicEOI
  55 + *
  56 + * description: signal the EOI and restore machine status
  57 + * Input: r3 - value of eumbbar
  58 + * Output: r3 - value of eumbbar
  59 + * r4 - ISR vector value
  60 + * note:
  61 + ********************************************************/
  62 + .text
  63 + .align 2
  64 + .global epicEOI
  65 +epicEOI:
  66 + lis r5,0x0006 /* Build End Of Interrupt Register offset */
  67 + ori r5,r5,0x00b0
  68 + xor r7,r7,r7 /* Clear r7 */
  69 + stwbrx r7,r5,r3 /* Save r7, writing to this register will
  70 + * intidate the end of processing the
  71 + * highest interrupt.
  72 + */
  73 + sync
  74 +
  75 + /* ---RESTORE MACHINE STATE */
  76 + mfmsr r13 /* Clear Recoverable Interrupt bit in MSR */
  77 + or r7,r7,r13
  78 +
  79 + andis. r7,r7,0xffff
  80 + andi. r13,r13,0x7ffd /* (and disable interrupts) */
  81 + or r13,r13,r7
  82 + mtmsr r13
  83 +
  84 + lwz r13,0x1c(r1) /* pull ctr */
  85 + mtctr r13
  86 +
  87 + lwz r13,0x18(r1) /* pull xer */
  88 + mtctr r13
  89 +
  90 + lwz r13,0x14(r1) /* pull lr */
  91 + mtctr r13
  92 +
  93 + lwz r13,0x10(r1) /* Pull SRR1 from stack */
  94 + mtspr SRR1,r13 /* Restore SRR1 */
  95 +
  96 + lwz r13,0xc(r1) /* Pull SRR0 from stack */
  97 + mtspr SRR0,r13 /* Restore SRR0 */
  98 +
  99 + lwz r13,0x8(r1) /* Pull User stack pointer from stack */
  100 + mtspr SPRG1,r13 /* Restore SPRG1 */
  101 +
  102 + lwz r4,0x4(r1) /* vector value */
  103 + lwz r3,0x0(r1) /* eumbbar */
  104 + sync
  105 +
  106 + addi r1,r1,0x20 /* Deallocate stack */
  107 + mtspr SPRG0,r1 /* Save updated Supervisor stack pointer */
  108 + mfspr r1,SPRG1 /* Restore User stack pointer */
  109 +
  110 + bclr 20,0
  111 +
  112 +/***********************************************************
  113 + * function: exception routine called by exception vector
  114 + * at 0x500, external interrupt
  115 + *
  116 + * description: Kahlua EPIC controller
  117 + *
  118 + * input: r3 - content of eumbbar
  119 + * output: r3 - ISR return value
  120 + * r4 - Interrupt vector number
  121 + * note:
  122 + ***********************************************************/
  123 +
  124 + .text
  125 + .align 2
  126 + .global epic_exception
  127 +
  128 +epic_exception:
  129 +
  130 + /*---SAVE MACHINE STATE TO A STACK */
  131 + mtspr SPRG1,r1 /* Save User stack pointer to SPRG1 */
  132 + mfspr r1,SPRG0 /* Load Supervisor stack pointer into r1 */
  133 +
  134 + stwu r3,-0x20(r1) /* Push the value of eumbbar onto stack */
  135 +
  136 + mfspr r3,SPRG1 /* Push User stack pointer onto stack */
  137 + stw r3,0x8(r1)
  138 + mfspr r3,SRR0 /* Push SRR0 onto stack */
  139 + stw r1,0xc(r1)
  140 + mfspr r3,SRR1 /* Push SRR1 onto stack */
  141 + stw r3,0x10(r1)
  142 + mflr r3
  143 + stw r3,0x14(r1) /* Push LR */
  144 + mfxer r3
  145 + stw r3,0x18(r1) /* Push Xer */
  146 + mfctr r3
  147 + stw r3,0x1c(r1) /* Push CTR */
  148 +
  149 + mtspr SPRG0,r1 /* Save updated Supervisor stack pointer
  150 + * value to SPRG0
  151 + */
  152 + mfmsr r3
  153 + ori r3,r3,0x0002 /* Set Recoverable Interrupt bit in MSR */
  154 + mtmsr r3
  155 +
  156 + /* ---READ IN THE EUMBAR REGISTER */
  157 + lwz r6,0(r1) /* this is eumbbar */
  158 + sync
  159 +
  160 + /* ---READ EPIC REGISTER: PROCESSOR INTERRUPT ACKNOWLEDGE REGISTER */
  161 + lis r5,0x0006 /* Build Interrupt Acknowledge Register
  162 + * offset
  163 + */
  164 + ori r5,r5,0x00a0
  165 + lwbrx r7,r5,r6 /* Load interrupt vector into r7 */
  166 + sync
  167 +
  168 + /* --MASK OFF ALL BITS EXCEPT THE VECTOR */
  169 + xor r3,r3,r3
  170 + xor r4,r4,r4
  171 + or r3, r3, r6 /* eumbbar in r3 */
  172 + andi. r4,r7,0x00ff /* Mask off bits, vector in r4 */
  173 +
  174 + stw r4,0x04(r1) /* save the vector value */
  175 +
  176 + lis r5,epicISR@ha
  177 + ori r5,r5,epicISR@l
  178 + mtlr r5
  179 + blrl
  180 +
  181 + xor r30,r30,r30
  182 + or r30,r30,r3 /* save the r3 which containts the return value from epicISR */
  183 +
  184 + /* ---READ IN THE EUMBAR REGISTER */
  185 + lwz r3,0(r1)
  186 + sync
  187 +
  188 + lis r5,epicEOI@ha
  189 + ori r5,r5,epicEOI@l
  190 + mtlr r5
  191 + blrl
  192 +
  193 + xor r3,r3,r3
  194 + or r3,r3,r30 /* restore the ISR return value */
  195 +
  196 + bclr 20,0
cpu/mpc824x/drivers/epic/epicutil.S
  1 +/**************************************
  2 + *
  3 + * copyright @ Motorola, 1999
  4 + *
  5 + *
  6 + * This file contains two commonly used
  7 + * lower level utility routines.
  8 + *
  9 + * The utility routines are also in other
  10 + * Kahlua device driver libraries. The
  11 + * need to be linked in only once.
  12 + **************************************/
  13 +
  14 +#include <ppc_asm.tmpl>
  15 +#include <ppc_defs.h>
  16 +
  17 +/**********************************************************
  18 + * function: load_runtime_reg
  19 + *
  20 + * input: r3 - value of eumbbar
  21 + * r4 - register offset in embedded utility space
  22 + *
  23 + * output: r3 - register content
  24 + **********************************************************/
  25 + .text
  26 + .align 2
  27 + .global load_runtime_reg
  28 +
  29 +load_runtime_reg:
  30 +
  31 + xor r5,r5,r5
  32 + or r5,r5,r3 /* save eumbbar */
  33 +
  34 + lwbrx r3,r4,r5
  35 + sync
  36 +
  37 + bclr 20, 0
  38 +
  39 +/****************************************************************
  40 + * function: store_runtime_reg
  41 + *
  42 + * input: r3 - value of eumbbar
  43 + * r4 - register offset in embedded utility space
  44 + * r5 - new value to be stored
  45 + *
  46 + ****************************************************************/
  47 + .text
  48 + .align 2
  49 + .global store_runtime_reg
  50 +store_runtime_reg:
  51 +
  52 + xor r0,r0,r0
  53 +
  54 + stwbrx r5, r4, r3
  55 + sync
  56 +
  57 + bclr 20,0
cpu/mpc824x/drivers/errors.h
  1 +/* Copyright Motorola, Inc. 1993, 1994
  2 + ALL RIGHTS RESERVED
  3 +
  4 + You are hereby granted a copyright license to use, modify, and
  5 + distribute the SOFTWARE so long as this entire notice is retained
  6 + without alteration in any modified and/or redistributed versions,
  7 + and that such modified versions are clearly identified as such.
  8 + No licenses are granted by implication, estoppel or otherwise under
  9 + any patents or trademarks of Motorola, Inc.
  10 +
  11 + The SOFTWARE is provided on an "AS IS" basis and without warranty.
  12 + To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  13 + ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  14 + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  15 + PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  16 + REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  17 + THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  18 +
  19 + To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  20 + MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  21 + (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  22 + BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  23 + INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  24 + INABILITY TO USE THE SOFTWARE. Motorola assumes no responsibility
  25 + for the maintenance and support of the SOFTWARE.
  26 +
  27 +*/
  28 +
  29 +
  30 +#include "config.h"
  31 +
  32 +/*
  33 + 1 2 3 4 5 6 7 8
  34 +01234567890123456789012345678901234567890123456789012345678901234567890123456789
  35 +*/
  36 +/* List define statements here */
  37 +
  38 +/* These are for all the toolboxes and functions to use. These will help
  39 +to standardize the error handling in the current project */
  40 +
  41 + /* this is the "data type" for the error
  42 + messages in the system */
  43 +#define STATUS unsigned int
  44 +
  45 + /* this is a success status code */
  46 +#define SUCCESS 1
  47 +
  48 + /* likewise this is failure */
  49 +#define FAILURE 0
  50 +
  51 +#define NUM_ERRORS 47
  52 +
  53 +/* This first section of "defines" are for error codes ONLY. The called
  54 + routine will return one of these error codes to the caller. If the final
  55 + returned code is "VALID", then everything is a-okay. However, if one
  56 + of the functions returns a non-valid status, that error code should be
  57 + propogated back to all the callers. At the end, the last caller will
  58 + call an error_processing function, and send in the status which was
  59 + returned. It's up to the error_processing function to determine which
  60 + error occured (as indicated by the status), and print an appropriate
  61 + message back to the user.
  62 +*/
  63 +/*----------------------------------------------------------------------*/
  64 +/* these are specifically for the parser routines */
  65 +
  66 +#define UNKNOWN_COMMAND 0xfb00 /* "unrecognized command " */
  67 +#define UNKNOWN_REGISTER 0xfb01 /* "unknown register "*/
  68 +#define ILLEGAL_RD_STAGE 0xfb02 /* cannot specify reg. family in range*/
  69 +#define ILLEGAL_REG_FAMILY 0xfb03 /* "cannot specify a range of special
  70 + or miscellaneous registers"*/
  71 +#define RANGE_CROSS_FAMILY 0xfb04 /* "cannot specify a range across
  72 + register families" */
  73 +#define UNIMPLEMENTED_STAGE 0xfb05 /* invalid rd or rmm parameter format */
  74 +#define REG_NOT_WRITEABLE 0xfb06 /* "unknown operator in arguements"*/
  75 +#define INVALID_FILENAME 0xfb07 /* "invalid download filename" */
  76 +#define INVALID_BAUD_RATE 0xfb08 /* invalid baud rate from sb command */
  77 +#define UNSUPPORTED_REGISTER 0xfb09 /* Special register is not supported */
  78 +#define FOR_BOARD_ONLY 0xfb0a /* "Not available for Unix." */
  79 +
  80 +
  81 +
  82 +/*----------------------------------------------------------------------*/
  83 +/* these are for the error checking toolbox */
  84 +
  85 +#define INVALID 0xfd00 /* NOT valid */
  86 +#define VALID 0xfd01 /* valid */
  87 +
  88 + /* This error is found in the fcn:
  89 + is_right_size_input() to indicate
  90 + that the input was not 8 characters
  91 + long. */
  92 +#define INVALID_SIZE 0xfd02
  93 +
  94 + /* This error is found in the fcn:
  95 + is_valid_address_range() to indicate
  96 + that the address given falls outside
  97 + of valid memory defined by MEM_START
  98 + to MEM_END.
  99 + */
  100 +#define OUT_OF_BOUNDS_ADDRESS 0xfd03
  101 +
  102 + /* This error is found in the fcn:
  103 + is_valid_hex_input() to indicate that
  104 + one of more of the characters entered
  105 + are not valid hex characters. Valid
  106 + hex characters are 0-9, A-F, a-f.
  107 + */
  108 +#define INVALID_HEX_INPUT 0xfd04
  109 +
  110 + /* This error is found in the fcn:
  111 + is_valid_register_number() to indicate
  112 + that a given register does not exist.
  113 + */
  114 +#define REG_NOT_READABLE 0xfd05
  115 +
  116 + /* This error is found in the fcn:
  117 + is_word_aligned_address() to indicate
  118 + that the given address is not word-
  119 + aligned. A word-aligned address ends
  120 + in 0x0,0x4,0x8,0xc.
  121 + */
  122 +#define NOT_WORD_ALIGNED 0xfd07
  123 +
  124 + /* This error is found in the fcn:
  125 + is_valid_address_range() to indicate
  126 + that the starting address is greater
  127 + than the ending address.
  128 + */
  129 +#define REVERSED_ADDRESS 0xfd08
  130 +
  131 + /* this error tells us that the address
  132 + specified as the destination is within
  133 + the source addresses */
  134 +#define RANGE_OVERLAP 0xfd09
  135 +
  136 +
  137 +#define ERROR 0xfd0a /* An error occured */
  138 +#define INVALID_PARAM 0xfd0b /* "invalid input parameter " */
  139 +
  140 +
  141 +#define INVALID_FLAG 0xfd0c /* invalid flag */
  142 +
  143 +/*----------------------------------------------------------------------*/
  144 +/* these are for the getarg toolbox */
  145 +
  146 +#define INVALID_NUMBER_ARGS 0xFE00 /* invalid number of commd arguements */
  147 +#define UNKNOWN_PARAMETER 0xFE01 /* "unknown type of parameter "*/
  148 +
  149 +
  150 +
  151 +
  152 +
  153 +/*----------------------------------------------------------------------*/
  154 +/* these are for the tokenizer toolbox */
  155 +
  156 +#define ILLEGAL_CHARACTER 0xFF00 /* unrecognized char. in input stream*/
  157 +#define TTL_NOT_SORTED 0xFF01 /* token translation list not sorted */
  158 +#define TTL_NOT_DEFINED 0xFF02 /* token translation list not assigned*/
  159 +#define INVALID_STRING 0xFF03 /* unable to extract string from input */
  160 +#define BUFFER_EMPTY 0xFF04 /* "input buffer is empty" */
  161 +#define INVALID_MODE 0xFF05 /* input buf is in an unrecognized mode*/
  162 +#define TOK_INTERNAL_ERROR 0xFF06 /* "internal tokenizer error" */
  163 +#define TOO_MANY_IBS 0xFF07 /* "too many open input buffers" */
  164 +#define NO_OPEN_IBS 0xFF08 /* "no open input buffers" */
  165 +
  166 +
  167 +
  168 +/* these are for the read from screen toolbox */
  169 +
  170 +#define RESERVED_WORD 0xFC00 /* used a reserved word as an arguement*/
  171 +
  172 +
  173 +/* these are for the breakpoint routines */
  174 +
  175 +#define FULL_BPDS 0xFA00 /* breakpoint data structure is full */
  176 +
  177 +
  178 +
  179 +/* THESE are for the downloader */
  180 +
  181 +#define NOT_IN_S_RECORD_FORMAT 0xf900 /* "not in S-Record Format" */
  182 +#define UNREC_RECORD_TYPE 0xf901 /* "unrecognized record type" */
  183 +#define CONVERSION_ERROR 0xf902 /* "ascii to int conversion error" */
  184 +#define INVALID_MEMORY 0xf903 /* "bad s-record memory address " */
  185 +
  186 +
  187 +/* these are for the compression and decompression stuff */
  188 +
  189 +#define COMP_UNK_CHARACTER 0xf800 /* "unknown compressed character " */
  190 +
  191 +#define COMP_UNKNOWN_STATE 0xf801 /* "unknown binary state" */
  192 +
  193 +#define NOT_IN_COMPRESSED_FORMAT 0xf802 /* not in compressed S-Record format */
  194 +
  195 +
  196 +/* these are for the DUART handling things */
  197 +
  198 + /* "unrecognized serial port configuration" */
  199 +#define UNKNOWN_PORT_STATE 0xf700
  200 +
  201 +
  202 +/* these are for the register toolbox */
  203 +
  204 + /* "cannot find register in special
  205 + purpose register file " */
  206 +#define SPR_NOT_FOUND 0xf600
  207 +
  208 +
  209 +/* these are for the duart specific stuff */
  210 +
  211 + /* "transparent mode needs access to
  212 + two serial ports" */
  213 +#define TM_NEEDS_BOTH_PORTS 0xf500
  214 +
  215 +
  216 +/*----------------------------------------------------------------------*/
  217 +/* these are specifically for the flash routines */
  218 +#define FLASH_ERROR 0xf100 /* general flash error */
cpu/mpc824x/drivers/i2c/Makefile
  1 +##########################################################################
  2 +#
  3 +# Copyright Motorola, Inc. 1997
  4 +# ALL RIGHTS RESERVED
  5 +#
  6 +# You are hereby granted a copyright license to use, modify, and
  7 +# distribute the SOFTWARE so long as this entire notice is retained
  8 +# without alteration in any modified and/or redistributed versions,
  9 +# and that such modified versions are clearly identified as such.
  10 +# No licenses are granted by implication, estoppel or otherwise under
  11 +# any patents or trademarks of Motorola, Inc.
  12 +#
  13 +# The SOFTWARE is provided on an "AS IS" basis and without warranty.
  14 +# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  15 +# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  16 +# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  17 +# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  18 +# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  19 +# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  20 +#
  21 +# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  22 +# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  23 +# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  24 +# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  25 +# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  26 +# INABILITY TO USE THE SOFTWARE.
  27 +#
  28 +############################################################################
  29 +TARGET = libi2c.a
  30 +
  31 +#DEBUG = -g
  32 +DEBUG = -DI2CDBG
  33 +LST = -Hanno -S
  34 +OPTIM =
  35 +CC = /risc/tools/pkgs/metaware/bin/hcppc
  36 +CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
  37 +CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
  38 +PREP = $(CC) $(CFLAGS) -P
  39 +
  40 +# Assembler used to build the .s files (for the board version)
  41 +
  42 +ASOPT = -big_si -c
  43 +ASDEBUG = -l -fm
  44 +AS = /risc/tools/pkgs/metaware/bin/asppc
  45 +
  46 +# Linker to bring .o files together into an executable.
  47 +
  48 +LKOPT = -Bbase=0 -q -Qn -r
  49 +LKCMD =
  50 +LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
  51 +
  52 +# DOS Utilities
  53 +
  54 +DEL = rm
  55 +COPY = cp
  56 +LIST = ls
  57 +
  58 +OBJECTS = i2c1.o i2c2.o
  59 +
  60 +all: $(TARGET)
  61 +
  62 +objects: $(OBJECTS)
  63 +
  64 +$(TARGET): $(OBJECTS)
  65 + $(LINK) $(OBJECTS) -o $@
  66 +
  67 +clean:
  68 + $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
  69 +
  70 +.s.o:
  71 + $(DEL) -f $*.i
  72 + $(PREP) -Hasmcpp $<
  73 + $(AS) $(ASOPT) $*.i
  74 +# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
  75 +
  76 +.c.o:
  77 + $(CCobj) $<
  78 +
  79 +.c.s:
  80 + $(CCobj) $(LST) $<
  81 +
  82 +i2c1.o: i2c_export.h i2c.h i2c1.c
  83 +
  84 +i2c2.o: i2c.h i2c2.s
cpu/mpc824x/drivers/i2c/Makefile_pc
  1 +##########################################################################
  2 +#
  3 +# makefile_pc for use with PC mksnt tools dink32/drivers/i2c
  4 +#
  5 +# Copyright Motorola, Inc. 1997
  6 +# ALL RIGHTS RESERVED
  7 +#
  8 +# You are hereby granted a copyright license to use, modify, and
  9 +# distribute the SOFTWARE so long as this entire notice is retained
  10 +# without alteration in any modified and/or redistributed versions,
  11 +# and that such modified versions are clearly identified as such.
  12 +# No licenses are granted by implication, estoppel or otherwise under
  13 +# any patents or trademarks of Motorola, Inc.
  14 +#
  15 +# The SOFTWARE is provided on an "AS IS" basis and without warranty.
  16 +# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  17 +# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  18 +# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  19 +# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  20 +# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  21 +# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  22 +#
  23 +# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  24 +# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  25 +# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  26 +# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  27 +# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  28 +# INABILITY TO USE THE SOFTWARE.
  29 +#
  30 +############################################################################
  31 +TARGET = libi2c.a
  32 +
  33 +#DEBUG = -g
  34 +DEBUG = -DI2CDBG
  35 +LST = -Hanno -S
  36 +OPTIM =
  37 +CC = m:/old_tools/tools/hcppc/bin/hcppc
  38 +CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
  39 +CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
  40 +PREP = $(CC) $(CFLAGS) -P
  41 +
  42 +# Assembler used to build the .s files (for the board version)
  43 +
  44 +ASOPT = -big_si -c
  45 +ASDEBUG = -l -fm
  46 +AS = m:/old_tools/tools/hcppc/bin/asppc
  47 +
  48 +# Linker to bring .o files together into an executable.
  49 +
  50 +LKOPT = -Bbase=0 -q -Qn -r
  51 +LKCMD =
  52 +LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
  53 +
  54 +# DOS Utilities
  55 +
  56 +DEL = rm
  57 +COPY = cp
  58 +LIST = ls
  59 +
  60 +OBJECTS = i2c1.o i2c2.o
  61 +
  62 +all: $(TARGET)
  63 +
  64 +objects: $(OBJECTS)
  65 +
  66 +$(TARGET): $(OBJECTS)
  67 + $(LINK) $(OBJECTS) -o $@
  68 +
  69 +clean:
  70 + $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
  71 +
  72 +.s.o:
  73 + $(DEL) -f $*.i
  74 + $(PREP) -Hasmcpp $<
  75 + $(AS) $(ASOPT) $*.i
  76 +# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
  77 +
  78 +.c.o:
  79 + $(CCobj) $<
  80 +
  81 +.c.s:
  82 + $(CCobj) $(LST) $<
  83 +
  84 +i2c1.o: i2c_export.h i2c.h i2c1.c
  85 + $(CCobj) $<
  86 +
  87 +
  88 +i2c2.o: i2c.h i2c2.s
  89 + $(DEL) -f $*.i
  90 + $(PREP) -Hasmcpp $<
  91 + $(AS) $(ASOPT) $*.i
cpu/mpc824x/drivers/i2c/README
  1 +CONTENT:
  2 +
  3 + i2c.h
  4 + i2c1.c
  5 + i2c2.s
  6 +
  7 +WHAT ARE THESE FILES:
  8 +
  9 +These files contain MPC8240 (Kahlua) I2C
  10 +driver routines. The driver routines are not
  11 +written for any specific operating system.
  12 +They serves the purpose of code sample, and
  13 +jump-start for using the MPC8240 I2C unit.
  14 +
  15 +For the reason of correctness of C language
  16 +syntax, these files are compiled by Metaware
  17 +C compiler and assembler.
  18 +
  19 +ENDIAN NOTATION:
  20 +
  21 +The algorithm is designed for big-endian mode,
  22 +software is responsible for byte swapping.
  23 +
  24 +USAGE:
  25 +
  26 +1. The host system that is running on MPC8240
  27 + shall link the files listed here. The memory
  28 + location of driver routines shall take into
  29 + account of that driver routines need to run
  30 + in supervisor mode and they process I2C
  31 + interrupt.
  32 +
  33 +2. The host system is responsible for configuring
  34 + the MPC8240 including Embedded Utilities Memory
  35 + Block. All I2C driver functions require the
  36 + content of Embedded Utilities Memory Block
  37 + Base Address Register, EUMBBAR, as the first
  38 + parameter.
  39 +
  40 +3. Before I2C unit of MPC8240 can be used,
  41 + initialize I2C unit by calling I2C_Init
  42 + with the corresponding parameters.
  43 +
  44 + Note that the I2CFDR register shall be written
  45 + once during the initialization. If it is written
  46 + in the midst of transers, or after I2C STOPs or
  47 + REPEAT STATRs, depending on the data written,
  48 + a long reset time may be encountered.
  49 +
  50 +4. After I2C unit has been successfully initialized,
  51 + use the Application level API to send data or
  52 + receive data upon the desired mode, Master or
  53 + Slave.
  54 +
  55 +5. If the host system is also using the EPIC unit
  56 + on MPC8240, the system can register the
  57 + I2C_ISR with the EPIC including other
  58 + desired resources.
  59 +
  60 + If the host system does not using the EPIC unit
  61 + on MPC8240, I2C_Timer_Event function can
  62 + be called for each desired time interval.
  63 +
  64 + In both cases, the host system is free to provide
  65 + its own timer event handler and interrupt service
  66 + routine.
  67 +
  68 +6. The I2C driver routines contains a set
  69 + of utilities, Set and Get, for host system
  70 + to query and modify the desired I2C registers.
  71 +
  72 +7. It is the host system's responsibility of
  73 + queueing the I2C I/O request. The host
  74 + system shall check the I2C_ISR return code
  75 + for I2C I/O status. If I2C_ISR returns
  76 + I2CBUFFEMPTY or I2CBUFFFULL, it means
  77 + I2C unit has completed a I/O request
  78 + stated by the Application API.
  79 +
  80 +8. If the host system has more than one master
  81 + mode I2C unit I/O requests but doesn't want
  82 + to be intervented by being addressed as slave,
  83 + the host system can use the master mode
  84 + Application API with stop_flag set to 0 in
  85 + conjunction with is_cnt flag set to 1.
  86 + The first API call sets both stop_flag and
  87 + is_cnt to 0, indicating a START condition
  88 + shall be generated but when the end of
  89 + transaction is reached, do not generate a
  90 + STOP condition. Once the host system is
  91 + informed that the transaction has been
  92 + completed, the next Application API call
  93 + shall set is_cnt flag to 1, indicating a
  94 + repeated START condition shall be generated.
  95 + The last Application API call shall set
  96 + stop_flag
  97 + to 1.
  98 +
  99 +9. The I2C_Timer_Event function containes
  100 + a user defined function pointer. It
  101 + serves the purpose of providing the
  102 + host system a way to use its own event
  103 + handler instead of the I2C_ISR provided
  104 + here.
cpu/mpc824x/drivers/i2c/i2c_export.h
  1 +#ifndef I2C_EXPORT_H
  2 +#define I2C_EXPORT_H
  3 +
  4 +/****************************************************
  5 + *
  6 + * Copyright Motrola 1999
  7 + *
  8 + ****************************************************/
  9 +
  10 +/* These are the defined return values for the I2C_do_transaction function.
  11 + * Any non-zero value indicates failure. Failure modes can be added for
  12 + * more detailed error reporting.
  13 + */
  14 +typedef enum _i2c_status
  15 +{
  16 + I2C_SUCCESS = 0,
  17 + I2C_ERROR,
  18 +} I2C_Status;
  19 +
  20 +/* These are the defined tasks for I2C_do_transaction.
  21 + * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
  22 + */
  23 +typedef enum _i2c_transaction_mode
  24 +{
  25 + I2C_MASTER_RCV = 0,
  26 + I2C_MASTER_XMIT = 1,
  27 +} I2C_TRANSACTION_MODE;
  28 +
  29 +typedef enum _i2c_interrupt_mode
  30 +{
  31 + I2C_INT_DISABLE = 0,
  32 + I2C_INT_ENABLE = 1,
  33 +} I2C_INTERRUPT_MODE;
  34 +
  35 +typedef enum _i2c_stop
  36 +{
  37 + I2C_NO_STOP = 0,
  38 + I2C_STOP = 1,
  39 +} I2C_STOP_MODE;
  40 +
  41 +typedef enum _i2c_restart
  42 +{
  43 + I2C_NO_RESTART = 0,
  44 + I2C_RESTART = 1,
  45 +} I2C_RESTART_MODE;
  46 +
  47 +/******************** App. API ********************
  48 + * The application API is for user level application
  49 + * to use the functionality provided by I2C driver.
  50 + * This is a "generic" I2C interface, it should contain
  51 + * nothing specific to the Kahlua implementation.
  52 + * Only the generic functions are exported by the library.
  53 + *
  54 + * Note: Its App.s responsibility to swap the data
  55 + * byte. In our API, we just transfer whatever
  56 + * we are given
  57 + **************************************************/
  58 +
  59 +
  60 +/* Initialize I2C unit with the following:
  61 + * driver's slave address
  62 + * interrupt enabled
  63 + * optional pointer to application layer print function
  64 + *
  65 + * These parameters may be added:
  66 + * desired clock rate
  67 + * digital filter frequency sampling rate
  68 + *
  69 + * This function must be called before I2C unit can be used.
  70 + */
  71 +extern I2C_Status I2C_Initialize(
  72 + unsigned char addr, /* driver's I2C slave address */
  73 + I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
  74 + * 0 - disable I2C interrupt
  75 + */
  76 + int (*app_print_function)(char *,...)); /* pointer to optional "printf"
  77 + * provided by application
  78 + */
  79 +
  80 +/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
  81 + * are implemented. Both are only in polling mode.
  82 + *
  83 + * en_int controls interrupt/polling mode
  84 + * act is the type of transaction
  85 + * addr is the I2C address of the slave device
  86 + * len is the length of data to send or receive
  87 + * buffer is the address of the data buffer
  88 + * stop = I2C_NO_STOP, don't signal STOP at end of transaction
  89 + * I2C_STOP, signal STOP at end of transaction
  90 + * retry is the timeout retry value, currently ignored
  91 + * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
  92 + * I2C_RESTART, this is a continuation of existing transaction
  93 + */
  94 +extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
  95 + I2C_TRANSACTION_MODE act,
  96 + unsigned char i2c_addr,
  97 + unsigned char data_addr,
  98 + int len,
  99 + char *buffer,
  100 + I2C_STOP_MODE stop,
  101 + int retry,
  102 + I2C_RESTART_MODE rsta);
  103 +#endif
cpu/mpc824x/drivers/i2c_export.h
  1 +#ifndef I2C_EXPORT_H
  2 +#define I2C_EXPORT_H
  3 +
  4 +/****************************************************
  5 + *
  6 + * Copyright Motrola 1999
  7 + *
  8 + ****************************************************/
  9 +
  10 +/* These are the defined return values for the I2C_do_transaction function.
  11 + * Any non-zero value indicates failure. Failure modes can be added for
  12 + * more detailed error reporting.
  13 + */
  14 +typedef enum _i2c_status
  15 +{
  16 + I2C_SUCCESS = 0,
  17 + I2C_ERROR,
  18 +} I2C_Status;
  19 +
  20 +/* These are the defined tasks for I2C_do_transaction.
  21 + * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
  22 + */
  23 +typedef enum _i2c_transaction_mode
  24 +{
  25 + I2C_MASTER_RCV = 0,
  26 + I2C_MASTER_XMIT = 1,
  27 +} I2C_TRANSACTION_MODE;
  28 +
  29 +typedef enum _i2c_interrupt_mode
  30 +{
  31 + I2C_INT_DISABLE = 0,
  32 + I2C_INT_ENABLE = 1,
  33 +} I2C_INTERRUPT_MODE;
  34 +
  35 +typedef enum _i2c_stop
  36 +{
  37 + I2C_NO_STOP = 0,
  38 + I2C_STOP = 1,
  39 +} I2C_STOP_MODE;
  40 +
  41 +typedef enum _i2c_restart
  42 +{
  43 + I2C_NO_RESTART = 0,
  44 + I2C_RESTART = 1,
  45 +} I2C_RESTART_MODE;
  46 +
  47 +/******************** App. API ********************
  48 + * The application API is for user level application
  49 + * to use the functionality provided by I2C driver.
  50 + * This is a "generic" I2C interface, it should contain
  51 + * nothing specific to the Kahlua implementation.
  52 + * Only the generic functions are exported by the library.
  53 + *
  54 + * Note: Its App.s responsibility to swap the data
  55 + * byte. In our API, we just transfer whatever
  56 + * we are given
  57 + **************************************************/
  58 +
  59 +
  60 +/* Initialize I2C unit with the following:
  61 + * driver's slave address
  62 + * interrupt enabled
  63 + * optional pointer to application layer print function
  64 + *
  65 + * These parameters may be added:
  66 + * desired clock rate
  67 + * digital filter frequency sampling rate
  68 + *
  69 + * This function must be called before I2C unit can be used.
  70 + */
  71 +extern I2C_Status I2C_Initialize(
  72 + unsigned char addr, /* driver's I2C slave address */
  73 + I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
  74 + * 0 - disable I2C interrupt
  75 + */
  76 + int (*app_print_function)(char *,...)); /* pointer to optional "printf"
  77 + * provided by application
  78 + */
  79 +
  80 +/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
  81 + * are implemented. Both are only in polling mode.
  82 + *
  83 + * en_int controls interrupt/polling mode
  84 + * act is the type of transaction
  85 + * addr is the I2C address of the slave device
  86 + * len is the length of data to send or receive
  87 + * buffer is the address of the data buffer
  88 + * stop = I2C_NO_STOP, don't signal STOP at end of transaction
  89 + * I2C_STOP, signal STOP at end of transaction
  90 + * retry is the timeout retry value, currently ignored
  91 + * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
  92 + * I2C_RESTART, this is a continuation of existing transaction
  93 + */
  94 +extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
  95 + I2C_TRANSACTION_MODE act,
  96 + unsigned char i2c_addr,
  97 + unsigned char data_addr,
  98 + int len,
  99 + char *buffer,
  100 + I2C_STOP_MODE stop,
  101 + int retry,
  102 + I2C_RESTART_MODE rsta);
  103 +#endif
cpu/mpc824x/drivers/i2o.h
  1 +#ifndef I2O_H
  2 +#define I2O_H
  3 +/*********************************************************
  4 + *
  5 + * copyright @ Motorola, 1999
  6 + *********************************************************/
  7 +
  8 +#define I2O_REG_OFFSET 0x0004
  9 +
  10 +#define PCI_CFG_CLA 0x0B
  11 +#define PCI_CFG_SCL 0x0A
  12 +#define PCI_CFG_PIC 0x09
  13 +
  14 +#define I2O_IMR0 0x0050
  15 +#define I2O_IMR1 0x0054
  16 +#define I2O_OMR0 0x0058
  17 +#define I2O_OMR1 0x005C
  18 +
  19 +#define I2O_ODBR 0x0060
  20 +#define I2O_IDBR 0x0068
  21 +
  22 +#define I2O_OMISR 0x0030
  23 +#define I2O_OMIMR 0x0034
  24 +#define I2O_IMISR 0x0100
  25 +#define I2O_IMIMR 0x0104
  26 +
  27 +/* accessable to PCI master but local processor */
  28 +#define I2O_IFQPR 0x0040
  29 +#define I2O_OFQPR 0x0044
  30 +
  31 +/* accessable to local processor */
  32 +#define I2O_IFHPR 0x0120
  33 +#define I2O_IFTPR 0x0128
  34 +#define I2O_IPHPR 0x0130
  35 +#define I2O_IPTPR 0x0138
  36 +#define I2O_OFHPR 0x0140
  37 +#define I2O_OFTPR 0x0148
  38 +#define I2O_OPHPR 0x0150
  39 +#define I2O_OPTPR 0x0158
  40 +#define I2O_MUCR 0x0164
  41 +#define I2O_QBAR 0x0170
  42 +
  43 +#define I2O_NUM_MSG 2
  44 +
  45 +typedef enum _i2o_status
  46 +{
  47 + I2OSUCCESS = 0,
  48 + I2OINVALID,
  49 + I2OMSGINVALID,
  50 + I2ODBINVALID,
  51 + I2OQUEINVALID,
  52 + I2OQUEEMPTY,
  53 + I2OQUEFULL,
  54 + I2ONOEVENT,
  55 +} I2OSTATUS;
  56 +
  57 +typedef enum _queue_size
  58 +{
  59 + QSIZE_4K = 0x02,
  60 + QSIZE_8K = 0x04,
  61 + QSIZE_16K = 0x08,
  62 + QSIZE_32K = 0x10,
  63 + QSIZe_64K = 0x20,
  64 +} QUEUE_SIZE;
  65 +
  66 +typedef enum _location
  67 +{
  68 + LOCAL = 0, /* used by local processor to access its own on board device,
  69 + local processor's eumbbar is required */
  70 + REMOTE, /* used by PCI master to access the devices on its PCI device,
  71 + device's pcsrbar is required */
  72 +} LOCATION;
  73 +
  74 +/* door bell */
  75 +typedef enum _i2o_in_db
  76 +{
  77 + IN_DB = 1,
  78 + MC, /* machine check */
  79 +} I2O_IN_DB;
  80 +
  81 +/* I2O PCI configuration identification */
  82 +typedef struct _i2o_iop
  83 +{
  84 + unsigned int base_class : 8;
  85 + unsigned int sub_class : 8;
  86 + unsigned int prg_code : 8;
  87 +} I2OIOP;
  88 +
  89 +/* I2O Outbound Message Interrupt Status Register */
  90 +typedef struct _i2o_om_stat
  91 +{
  92 + unsigned int rsvd0 : 26;
  93 + unsigned int opqi : 1;
  94 + unsigned int rsvd1 : 1;
  95 + unsigned int odi : 1;
  96 + unsigned int rsvd2 : 1;
  97 + unsigned int om1i : 1;
  98 + unsigned int om0i : 1;
  99 +} I2OOMSTAT;
  100 +
  101 +/* I2O inbound Message Interrupt Status Register */
  102 +typedef struct _i2o_im_stat
  103 +{
  104 + unsigned int rsvd0 : 23;
  105 + unsigned int ofoi : 1;
  106 + unsigned int ipoi : 1;
  107 + unsigned int rsvd1 : 1;
  108 + unsigned int ipqi : 1;
  109 + unsigned int mci : 1;
  110 + unsigned int idi : 1;
  111 + unsigned int rsvd2 : 1;
  112 + unsigned int im1i : 1;
  113 + unsigned int im0i : 1;
  114 +} I2OIMSTAT;
  115 +
  116 +/**
  117 + Enable the interrupt associated with in/out bound msg
  118 +
  119 + Inbound message interrupt generated by PCI master and serviced by local processor
  120 + local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
  121 +
  122 + Outbound message interrupt generated by local processor and serviced by PCI master
  123 + PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
  124 + **/
  125 +extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
  126 + unsigned int base, /* pcsrbar/eumbbar */
  127 + unsigned char n ); /* b'1' - msg 0
  128 + * b'10'- msg 1
  129 + * b'11'- both
  130 + */
  131 +
  132 +/**
  133 + Disable the interrupt associated with in/out bound msg
  134 +
  135 + local processor needs to disable its inbound interrupts it is not interested (LOCAL)
  136 +
  137 + PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
  138 + **/
  139 +extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
  140 + unsigned int base, /* pcsrbar/eumbbar */
  141 + unsigned char n ); /* b'1' - msg 0
  142 + * b'10'- msg 1
  143 + * b'11'- both
  144 + */
  145 +
  146 +/**
  147 + Read the msg register either from local inbound msg 0/1,
  148 + or an outbound msg 0/1 of devices.
  149 +
  150 + If it is not local, pcsrbar must be passed to the function.
  151 + Otherwise eumbbar is passed.
  152 +
  153 + If it is remote, outbound msg of the device is read.
  154 + Otherwise local inbound msg is read.
  155 + **/
  156 +extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
  157 + unsigned int base, /*pcsrbar/eumbbar */
  158 + unsigned int n, /* 0 or 1 */
  159 + unsigned int *msg );
  160 +
  161 +/**
  162 + Write to nth Msg register either on local outbound msg 0/1,
  163 + or aninbound msg 0/1 of devices
  164 +
  165 + If it is not local, pcsrbar must be passed to the function.
  166 + Otherwise eumbbar is passed.
  167 +
  168 + If it is remote, inbound msg on the device is written.
  169 + Otherwise local outbound msg is written.
  170 + **/
  171 +extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
  172 + unsigned int base, /*pcsrbar/eumbbar */
  173 + unsigned int n, /* 0 or 1 */
  174 + unsigned int msg );
  175 +
  176 +/**
  177 + Enable the In/Out DoorBell Interrupt
  178 +
  179 + InDoorBell interrupt is generated by PCI master and serviced by local processor
  180 + local processor needs to enable its inbound doorbell interrupts it wants to handle
  181 +
  182 + OutDoorbell interrupt is generated by local processor and serviced by PCI master
  183 + PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
  184 + **/
  185 +extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
  186 + unsigned int base, /* pcsrbar/eumbbar */
  187 + unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
  188 +
  189 +/**
  190 + Disable the In/Out DoorBell Interrupt
  191 +
  192 + local processor needs to disable its inbound doorbell interrupts it is not interested
  193 +
  194 + PCI master needs to disable outbound doorbell interrupts of devices it is not interested
  195 +
  196 + **/
  197 +extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
  198 + unsigned int base, /* pcsrbar/eumbbar */
  199 + unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
  200 +
  201 +/**
  202 + Read a local indoorbell register, or an outdoorbell of devices.
  203 + Reading a doorbell register, the register will be cleared.
  204 +
  205 + If it is not local, pcsrbar must be passed to the function.
  206 + Otherwise eumbbar is passed.
  207 +
  208 + If it is remote, outdoorbell register on the device is read.
  209 + Otherwise local in doorbell is read
  210 + **/
  211 +extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
  212 + unsigned int base); /* pcsrbar/eumbbar */
  213 +
  214 +/**
  215 + Write to a local outdoorbell register, or an indoorbell register of devices.
  216 +
  217 + If it is not local, pcsrbar must be passed to the function.
  218 + Otherwise eumbbar is passed.
  219 +
  220 + If it is remote, in doorbell register on the device is written.
  221 + Otherwise local out doorbell is written
  222 + **/
  223 +extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
  224 + unsigned int base, /* pcsrbar/eumbbar */
  225 + unsigned int msg ); /* in / out */
  226 +
  227 +/**
  228 + Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
  229 + the register will be cleared.
  230 +
  231 + The outbound interrupt status is AND with the outbound
  232 + interrupt mask. The result is returned.
  233 +
  234 + PCI master must pass the pcsrbar to the function.
  235 + **/
  236 +extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
  237 +
  238 +/**
  239 + Read the inbound msg unit interrupt status. Reading an interrupt status register,
  240 + the register will be cleared.
  241 +
  242 + The inbound interrupt status is AND with the inbound
  243 + interrupt mask. The result is returned.
  244 +
  245 + Local process must pass its eumbbar to the function.
  246 +**/
  247 +extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
  248 +
  249 +/**
  250 + Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
  251 + MUCR.
  252 + **/
  253 +extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
  254 + QUEUE_SIZE,
  255 + unsigned int qba);/* queue base address that must be aligned at 1M */
  256 +/**
  257 + Enable the circular queue
  258 + **/
  259 +extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
  260 +
  261 +/**
  262 + Disable the circular queue
  263 + **/
  264 +extern void I2OFIFODisable( unsigned int eumbbar );
  265 +
  266 +/**
  267 + Enable the circular queue interrupt
  268 + PCI master enables outbound FIFO interrupt of device
  269 + Device enables its inbound FIFO interrupt
  270 + **/
  271 +extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
  272 +
  273 +/**
  274 + Disable the circular queue interrupt
  275 + PCI master disables outbound FIFO interrupt of device
  276 + Device disables its inbound FIFO interrupt
  277 + **/
  278 +extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
  279 +
  280 +/**
  281 + Enable the circular queue overflow interrupt
  282 + **/
  283 +extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
  284 +
  285 +/**
  286 + Disable the circular queue overflow interrupt
  287 + **/
  288 +extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
  289 +
  290 +/**
  291 + Allocate a free msg frame from free FIFO.
  292 +
  293 + PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
  294 + while local processor allocates a free msg frame from outbound free queue(OFTPR)
  295 +
  296 + Unless both free queues are initialized, allocating a free MF will return 0xffffffff
  297 + **/
  298 +extern I2OSTATUS I2OFIFOAlloc( LOCATION,
  299 + unsigned int base,
  300 + void **pMsg);
  301 +/**
  302 + Free a used msg frame back to free queue
  303 + PCI Master frees a MFA through outbound queue port of device(OFQPR)
  304 + while local processor frees a MFA into its inbound free queue(IFHPR)
  305 +
  306 + Used msg frame does not need to be recycled in the order they
  307 + read
  308 +
  309 + This function has to be called by PCI master to initialize Inbound free queue
  310 + and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
  311 + **/
  312 +extern I2OSTATUS I2OFIFOFree( LOCATION,
  313 + unsigned int base,
  314 + void *pMsg );
  315 +
  316 +/**
  317 + Post a msg into FIFO
  318 + PCI Master posts a msg through inbound queue port of device(IFQPR)
  319 + while local processor post a msg into its outbound post queue(OPHPR)
  320 +
  321 + The total number of msg must be less than the max size of the queue
  322 + Otherwise queue overflow interrupt will assert.
  323 + **/
  324 +extern I2OSTATUS I2OFIFOPost( LOCATION,
  325 + unsigned int base,
  326 + void *pMsg );
  327 +
  328 +/**
  329 + Read a msg from FIFO
  330 + PCI Master reads a msg through outbound queue port of device(OFQPR)
  331 + while local processor reads a msg from its inbound post queue(IPTPR)
  332 + **/
  333 +extern I2OSTATUS I2OFIFOGet( LOCATION,
  334 + unsigned int base,
  335 + void **pMsg );
  336 +
  337 +/**
  338 + Get the I2O PCI configuration identification register
  339 + **/
  340 +extern I2OSTATUS I2OPCIConfigGet( LOCATION,
  341 + unsigned int base,
  342 + I2OIOP *);
  343 +
  344 +#endif
cpu/mpc824x/drivers/i2o/Makefile
  1 +##########################################################################
  2 +#
  3 +# Copyright Motorola, Inc. 1997
  4 +# ALL RIGHTS RESERVED
  5 +#
  6 +# You are hereby granted a copyright license to use, modify, and
  7 +# distribute the SOFTWARE so long as this entire notice is retained
  8 +# without alteration in any modified and/or redistributed versions,
  9 +# and that such modified versions are clearly identified as such.
  10 +# No licenses are granted by implication, estoppel or otherwise under
  11 +# any patents or trademarks of Motorola, Inc.
  12 +#
  13 +# The SOFTWARE is provided on an "AS IS" basis and without warranty.
  14 +# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  15 +# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  16 +# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  17 +# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  18 +# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  19 +# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  20 +#
  21 +# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  22 +# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  23 +# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  24 +# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  25 +# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  26 +# INABILITY TO USE THE SOFTWARE.
  27 +#
  28 +############################################################################
  29 +TARGET = libi2o.a
  30 +
  31 +#DEBUG = -g
  32 +DEBUG =
  33 +LST = -Hanno -S
  34 +OPTIM =
  35 +CC = /risc/tools/pkgs/metaware/bin/hcppc
  36 +CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
  37 +CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
  38 +PREP = $(CC) $(CFLAGS) -P
  39 +
  40 +# Assembler used to build the .s files (for the board version)
  41 +
  42 +ASOPT = -big_si -c
  43 +ASDEBUG = -l -fm
  44 +AS = /risc/tools/pkgs/metaware/bin/asppc
  45 +
  46 +# Linker to bring .o files together into an executable.
  47 +
  48 +LKOPT = -Bbase=0 -Qn -q -r
  49 +LKCMD =
  50 +LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
  51 +
  52 +# DOS Utilities
  53 +
  54 +DEL = rm
  55 +COPY = cp
  56 +LIST = ls
  57 +
  58 +OBJECTS = i2o1.o i2o2.o
  59 +
  60 +all: $(TARGET)
  61 +
  62 +$(TARGET): $(OBJECTS)
  63 + $(LINK) $(OBJECTS) -o $@
  64 +
  65 +objects: i2o1.o
  66 +
  67 +clean:
  68 + $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
  69 +
  70 +.s.o:
  71 + $(DEL) -f $*.i
  72 + $(PREP) -Hasmcpp $<
  73 + $(AS) $(ASOPT) $*.i
  74 +# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
  75 +
  76 +.c.o:
  77 + $(CCobj) $<
  78 +
  79 +.c.s:
  80 + $(CCobj) $(LST) $<
  81 +
  82 +i2o1.o: i2o.h i2o1.c
  83 +
  84 +i2o2.o: i2o.h i2o2.s
cpu/mpc824x/drivers/i2o/Makefile_pc
  1 +##########################################################################
  2 +#
  3 +# makefile_pc for use with PC mksnt tools dink32/drivers/i2o
  4 +#
  5 +# Copyright Motorola, Inc. 1997
  6 +# ALL RIGHTS RESERVED
  7 +#
  8 +# You are hereby granted a copyright license to use, modify, and
  9 +# distribute the SOFTWARE so long as this entire notice is retained
  10 +# without alteration in any modified and/or redistributed versions,
  11 +# and that such modified versions are clearly identified as such.
  12 +# No licenses are granted by implication, estoppel or otherwise under
  13 +# any patents or trademarks of Motorola, Inc.
  14 +#
  15 +# The SOFTWARE is provided on an "AS IS" basis and without warranty.
  16 +# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
  17 +# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
  18 +# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
  19 +# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
  20 +# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
  21 +# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
  22 +#
  23 +# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
  24 +# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
  25 +# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
  26 +# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
  27 +# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
  28 +# INABILITY TO USE THE SOFTWARE.
  29 +#
  30 +############################################################################
  31 +TARGET = libi2o.a
  32 +
  33 +#DEBUG = -g
  34 +DEBUG =
  35 +LST = -Hanno -S
  36 +OPTIM =
  37 +CC = m:/old_tools/tools/hcppc/bin/hcppc
  38 +CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
  39 +CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
  40 +PREP = $(CC) $(CFLAGS) -P
  41 +
  42 +# Assembler used to build the .s files (for the board version)
  43 +
  44 +ASOPT = -big_si -c
  45 +ASDEBUG = -l -fm
  46 +AS = m:/old_tools/tools/hcppc/bin/asppc
  47 +
  48 +# Linker to bring .o files together into an executable.
  49 +
  50 +LKOPT = -Bbase=0 -Qn -q -r
  51 +LKCMD =
  52 +LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
  53 +
  54 +# DOS Utilities
  55 +
  56 +DEL = rm
  57 +COPY = cp
  58 +LIST = ls
  59 +
  60 +OBJECTS = i2o1.o i2o2.o
  61 +
  62 +all: $(TARGET)
  63 +
  64 +$(TARGET): $(OBJECTS)
  65 + $(LINK) $(OBJECTS) -o $@
  66 +
  67 +objects: i2o1.o
  68 +
  69 +clean:
  70 + $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
  71 +
  72 +.s.o:
  73 + $(DEL) -f $*.i
  74 + $(PREP) -Hasmcpp $<
  75 + $(AS) $(ASOPT) $*.i
  76 +# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
  77 +
  78 +.c.o:
  79 + $(CCobj) $<
  80 +
  81 +.c.s:
  82 + $(CCobj) $(LST) $<
  83 +
  84 +i2o1.o: i2o.h i2o1.c
  85 + $(CCobj) $<
  86 +
  87 +i2o2.o: i2o.h i2o2.s
  88 + $(DEL) -f $*.i
  89 + $(PREP) -Hasmcpp $<
  90 + $(AS) $(ASOPT) $*.i
cpu/mpc824x/drivers/i2o/i2o.h
  1 +#ifndef I2O_H
  2 +#define I2O_H
  3 +/*********************************************************
  4 + *
  5 + * copyright @ Motorola, 1999
  6 + *
  7 + *********************************************************/
  8 +
  9 +#define I2O_REG_OFFSET 0x0004
  10 +
  11 +#define PCI_CFG_CLA 0x0B
  12 +#define PCI_CFG_SCL 0x0A
  13 +#define PCI_CFG_PIC 0x09
  14 +
  15 +#define I2O_IMR0 0x0050
  16 +#define I2O_IMR1 0x0054
  17 +#define I2O_OMR0 0x0058
  18 +#define I2O_OMR1 0x005C
  19 +
  20 +#define I2O_ODBR 0x0060
  21 +#define I2O_IDBR 0x0068
  22 +
  23 +#define I2O_OMISR 0x0030
  24 +#define I2O_OMIMR 0x0034
  25 +#define I2O_IMISR 0x0100
  26 +#define I2O_IMIMR 0x0104
  27 +
  28 +/* accessable to PCI master but local processor */
  29 +#define I2O_IFQPR 0x0040
  30 +#define I2O_OFQPR 0x0044
  31 +
  32 +/* accessable to local processor */
  33 +#define I2O_IFHPR 0x0120
  34 +#define I2O_IFTPR 0x0128
  35 +#define I2O_IPHPR 0x0130
  36 +#define I2O_IPTPR 0x0138
  37 +#define I2O_OFHPR 0x0140
  38 +#define I2O_OFTPR 0x0148
  39 +#define I2O_OPHPR 0x0150
  40 +#define I2O_OPTPR 0x0158
  41 +#define I2O_MUCR 0x0164
  42 +#define I2O_QBAR 0x0170
  43 +
  44 +#define I2O_NUM_MSG 2
  45 +
  46 +typedef enum _i2o_status
  47 +{
  48 + I2OSUCCESS = 0,
  49 + I2OINVALID,
  50 + I2OMSGINVALID,
  51 + I2ODBINVALID,
  52 + I2OQUEINVALID,
  53 + I2OQUEEMPTY,
  54 + I2OQUEFULL,
  55 + I2ONOEVENT,
  56 +} I2OSTATUS;
  57 +
  58 +typedef enum _queue_size
  59 +{
  60 + QSIZE_4K = 0x02,
  61 + QSIZE_8K = 0x04,
  62 + QSIZE_16K = 0x08,
  63 + QSIZE_32K = 0x10,
  64 + QSIZe_64K = 0x20,
  65 +} QUEUE_SIZE;
  66 +
  67 +typedef enum _location
  68 +{
  69 + LOCAL = 0, /* used by local processor to access its own on board device,
  70 + local processor's eumbbar is required */
  71 + REMOTE, /* used by PCI master to access the devices on its PCI device,
  72 + device's pcsrbar is required */
  73 +} LOCATION;
  74 +
  75 +/* door bell */
  76 +typedef enum _i2o_in_db
  77 +{
  78 + IN_DB = 1,
  79 + MC, /* machine check */
  80 +} I2O_IN_DB;
  81 +
  82 +/* I2O PCI configuration identification */
  83 +typedef struct _i2o_iop
  84 +{
  85 + unsigned int base_class : 8;
  86 + unsigned int sub_class : 8;
  87 + unsigned int prg_code : 8;
  88 +} I2OIOP;
  89 +
  90 +/* I2O Outbound Message Interrupt Status Register */
  91 +typedef struct _i2o_om_stat
  92 +{
  93 + unsigned int rsvd0 : 26;
  94 + unsigned int opqi : 1;
  95 + unsigned int rsvd1 : 1;
  96 + unsigned int odi : 1;
  97 + unsigned int rsvd2 : 1;
  98 + unsigned int om1i : 1;
  99 + unsigned int om0i : 1;
  100 +} I2OOMSTAT;
  101 +
  102 +/* I2O inbound Message Interrupt Status Register */
  103 +typedef struct _i2o_im_stat
  104 +{
  105 + unsigned int rsvd0 : 23;
  106 + unsigned int ofoi : 1;
  107 + unsigned int ipoi : 1;
  108 + unsigned int rsvd1 : 1;
  109 + unsigned int ipqi : 1;
  110 + unsigned int mci : 1;
  111 + unsigned int idi : 1;
  112 + unsigned int rsvd2 : 1;
  113 + unsigned int im1i : 1;
  114 + unsigned int im0i : 1;
  115 +} I2OIMSTAT;
  116 +
  117 +/**
  118 + Enable the interrupt associated with in/out bound msg
  119 +
  120 + Inbound message interrupt generated by PCI master and serviced by local processor
  121 + local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
  122 +
  123 + Outbound message interrupt generated by local processor and serviced by PCI master
  124 + PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
  125 + **/
  126 +extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
  127 + unsigned int base, /* pcsrbar/eumbbar */
  128 + unsigned char n ); /* b'1' - msg 0
  129 + * b'10'- msg 1
  130 + * b'11'- both
  131 + */
  132 +
  133 +/**
  134 + Disable the interrupt associated with in/out bound msg
  135 +
  136 + local processor needs to disable its inbound interrupts it is not interested (LOCAL)
  137 +
  138 + PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
  139 + **/
  140 +extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
  141 + unsigned int base, /* pcsrbar/eumbbar */
  142 + unsigned char n ); /* b'1' - msg 0
  143 + * b'10'- msg 1
  144 + * b'11'- both
  145 + */
  146 +
  147 +/**
  148 + Read the msg register either from local inbound msg 0/1,
  149 + or an outbound msg 0/1 of devices.
  150 +
  151 + If it is not local, pcsrbar must be passed to the function.
  152 + Otherwise eumbbar is passed.
  153 +
  154 + If it is remote, outbound msg of the device is read.
  155 + Otherwise local inbound msg is read.
  156 + **/
  157 +extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
  158 + unsigned int base, /*pcsrbar/eumbbar */
  159 + unsigned int n, /* 0 or 1 */
  160 + unsigned int *msg );
  161 +
  162 +/**
  163 + Write to nth Msg register either on local outbound msg 0/1,
  164 + or aninbound msg 0/1 of devices
  165 +
  166 + If it is not local, pcsrbar must be passed to the function.
  167 + Otherwise eumbbar is passed.
  168 +
  169 + If it is remote, inbound msg on the device is written.
  170 + Otherwise local outbound msg is written.
  171 + **/
  172 +extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
  173 + unsigned int base, /*pcsrbar/eumbbar */
  174 + unsigned int n, /* 0 or 1 */
  175 + unsigned int msg );
  176 +
  177 +/**
  178 + Enable the In/Out DoorBell Interrupt
  179 +
  180 + InDoorBell interrupt is generated by PCI master and serviced by local processor
  181 + local processor needs to enable its inbound doorbell interrupts it wants to handle
  182 +
  183 + OutDoorbell interrupt is generated by local processor and serviced by PCI master
  184 + PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
  185 + **/
  186 +extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
  187 + unsigned int base, /* pcsrbar/eumbbar */
  188 + unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
  189 +
  190 +/**
  191 + Disable the In/Out DoorBell Interrupt
  192 +
  193 + local processor needs to disable its inbound doorbell interrupts it is not interested
  194 +
  195 + PCI master needs to disable outbound doorbell interrupts of devices it is not interested
  196 +
  197 + **/
  198 +extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
  199 + unsigned int base, /* pcsrbar/eumbbar */
  200 + unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
  201 +
  202 +/**
  203 + Read a local indoorbell register, or an outdoorbell of devices.
  204 + Reading a doorbell register, the register will be cleared.
  205 +
  206 + If it is not local, pcsrbar must be passed to the function.
  207 + Otherwise eumbbar is passed.
  208 +
  209 + If it is remote, outdoorbell register on the device is read.
  210 + Otherwise local in doorbell is read
  211 + **/
  212 +extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
  213 + unsigned int base); /* pcsrbar/eumbbar */
  214 +
  215 +/**
  216 + Write to a local outdoorbell register, or an indoorbell register of devices.
  217 +
  218 + If it is not local, pcsrbar must be passed to the function.
  219 + Otherwise eumbbar is passed.
  220 +
  221 + If it is remote, in doorbell register on the device is written.
  222 + Otherwise local out doorbell is written
  223 + **/
  224 +extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
  225 + unsigned int base, /* pcsrbar/eumbbar */
  226 + unsigned int msg ); /* in / out */
  227 +
  228 +/**
  229 + Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
  230 + the register will be cleared.
  231 +
  232 + The outbound interrupt status is AND with the outbound
  233 + interrupt mask. The result is returned.
  234 +
  235 + PCI master must pass the pcsrbar to the function.
  236 + **/
  237 +extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
  238 +
  239 +/**
  240 + Read the inbound msg unit interrupt status. Reading an interrupt status register,
  241 + the register will be cleared.
  242 +
  243 + The inbound interrupt status is AND with the inbound
  244 + interrupt mask. The result is returned.
  245 +
  246 + Local process must pass its eumbbar to the function.
  247 +**/
  248 +extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
  249 +
  250 +/**
  251 + Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
  252 + MUCR.
  253 + **/
  254 +extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
  255 + QUEUE_SIZE,
  256 + unsigned int qba);/* queue base address that must be aligned at 1M */
  257 +/**
  258 + Enable the circular queue
  259 + **/
  260 +extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
  261 +
  262 +/**
  263 + Disable the circular queue
  264 + **/
  265 +extern void I2OFIFODisable( unsigned int eumbbar );
  266 +
  267 +/**
  268 + Enable the circular queue interrupt
  269 + PCI master enables outbound FIFO interrupt of device
  270 + Device enables its inbound FIFO interrupt
  271 + **/
  272 +extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
  273 +
  274 +/**
  275 + Disable the circular queue interrupt
  276 + PCI master disables outbound FIFO interrupt of device
  277 + Device disables its inbound FIFO interrupt
  278 + **/
  279 +extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
  280 +
  281 +/**
  282 + Enable the circular queue overflow interrupt
  283 + **/
  284 +extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
  285 +
  286 +/**
  287 + Disable the circular queue overflow interrupt
  288 + **/
  289 +extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
  290 +
  291 +/**
  292 + Allocate a free msg frame from free FIFO.
  293 +
  294 + PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
  295 + while local processor allocates a free msg frame from outbound free queue(OFTPR)
  296 +
  297 + Unless both free queues are initialized, allocating a free MF will return 0xffffffff
  298 + **/
  299 +extern I2OSTATUS I2OFIFOAlloc( LOCATION,
  300 + unsigned int base,
  301 + void **pMsg);
  302 +/**
  303 + Free a used msg frame back to free queue
  304 + PCI Master frees a MFA through outbound queue port of device(OFQPR)
  305 + while local processor frees a MFA into its inbound free queue(IFHPR)
  306 +
  307 + Used msg frame does not need to be recycled in the order they
  308 + read
  309 +
  310 + This function has to be called by PCI master to initialize Inbound free queue
  311 + and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
  312 + **/
  313 +extern I2OSTATUS I2OFIFOFree( LOCATION,
  314 + unsigned int base,
  315 + void *pMsg );
  316 +
  317 +/**
  318 + Post a msg into FIFO
  319 + PCI Master posts a msg through inbound queue port of device(IFQPR)
  320 + while local processor post a msg into its outbound post queue(OPHPR)
  321 +
  322 + The total number of msg must be less than the max size of the queue
  323 + Otherwise queue overflow interrupt will assert.
  324 + **/
  325 +extern I2OSTATUS I2OFIFOPost( LOCATION,
  326 + unsigned int base,
  327 + void *pMsg );
  328 +
  329 +/**
  330 + Read a msg from FIFO
  331 + PCI Master reads a msg through outbound queue port of device(OFQPR)
  332 + while local processor reads a msg from its inbound post queue(IPTPR)
  333 + **/
  334 +extern I2OSTATUS I2OFIFOGet( LOCATION,
  335 + unsigned int base,
  336 + void **pMsg );
  337 +
  338 +/**
  339 + Get the I2O PCI configuration identification register
  340 + **/
  341 +extern I2OSTATUS I2OPCIConfigGet( LOCATION,
  342 + unsigned int base,
  343 + I2OIOP *);
  344 +
  345 +#endif
cpu/mpc824x/drivers/i2o/i2o1.c
  1 +/*********************************************************
  2 + * $Id
  3 + *
  4 + * copyright @ Motorola, 1999
  5 + *********************************************************/
  6 +#include "i2o.h"
  7 +
  8 +extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
  9 +#pragma Alias( load_runtime_reg, "load_runtime_reg" );
  10 +
  11 +extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
  12 +#pragma Alias( store_runtime_reg, "store_runtime_reg" );
  13 +
  14 +typedef struct _fifo_stat
  15 +{
  16 + QUEUE_SIZE qsz;
  17 + unsigned int qba;
  18 +} FIFOSTAT;
  19 +
  20 +FIFOSTAT fifo_stat = { QSIZE_4K, 0xffffffff };
  21 +
  22 +/**********************************************************************************
  23 + * function: I2OMsgEnable
  24 + *
  25 + * description: Enable the interrupt associated with in/out bound msg
  26 + * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
  27 + *
  28 + * All previously enabled interrupts are preserved.
  29 + * note:
  30 + * Inbound message interrupt generated by PCI master and serviced by local processor
  31 + * Outbound message interrupt generated by local processor and serviced by PCI master
  32 + *
  33 + * local processor needs to enable its inbound interrupts it wants to handle(LOCAL)
  34 + * PCI master needs to enable the outbound interrupts of devices it wants to handle(REMOTE)
  35 + ************************************************************************************/
  36 +I2OSTATUS I2OMsgEnable ( LOCATION loc, /* REMOTE/LOCAL */
  37 + unsigned int base, /* pcsrbar/eumbbar */
  38 + unsigned char n ) /* b'1' - msg 0
  39 + * b'10'- msg 1
  40 + * b'11'- both
  41 + */
  42 +{
  43 + unsigned int reg, val;
  44 + if ( ( n & 0x3 ) == 0 )
  45 + {
  46 + /* neither msg 0, nor msg 1 */
  47 + return I2OMSGINVALID;
  48 + }
  49 +
  50 + n = (~n) & 0x3;
  51 + /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
  52 + * LOCAL : enable local inbound message, eumbbar as base
  53 + */
  54 + reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
  55 + val = load_runtime_reg( base, reg );
  56 +
  57 + val &= 0xfffffffc; /* masked out the msg interrupt bits */
  58 + val |= n; /* LSB are the one we want */
  59 + store_runtime_reg( base, reg, val );
  60 +
  61 + return I2OSUCCESS;
  62 +}
  63 +
  64 +/*********************************************************************************
  65 + * function: I2OMsgDisable
  66 + *
  67 + * description: Disable the interrupt associated with in/out bound msg
  68 + * Other previously enabled interrupts are preserved.
  69 + * return I2OSUCCESS if no error otherwise return I2OMSGINVALID
  70 + *
  71 + * note:
  72 + * local processor needs to disable its inbound interrupts it is not interested(LOCAL)
  73 + * PCI master needs to disable outbound interrupts of devices it is not interested(REMOTE)
  74 + *********************************************************************************/
  75 +I2OSTATUS I2OMsgDisable( LOCATION loc, /* REMOTE/LOCAL */
  76 + unsigned int base, /* pcsrbar/eumbbar */
  77 + unsigned char n ) /* b'1' - msg 0
  78 + * b'10'- msg 1
  79 + * b'11'- both
  80 + */
  81 +{
  82 + unsigned int reg, val;
  83 +
  84 + if ( ( n & 0x3 ) == 0 )
  85 + {
  86 + /* neither msg 0, nor msg 1 */
  87 + return I2OMSGINVALID;
  88 + }
  89 +
  90 + /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
  91 + * LOCAL : disable local inbound message interrupt, eumbbar as base
  92 + */
  93 + reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
  94 + val = load_runtime_reg( base, reg );
  95 +
  96 + val &= 0xfffffffc; /* masked out the msg interrupt bits */
  97 + val |= ( n & 0x3 );
  98 + store_runtime_reg( base, reg, val );
  99 +
  100 + return I2OSUCCESS;
  101 +
  102 +}
  103 +
  104 +/**************************************************************************
  105 + * function: I2OMsgGet
  106 + *
  107 + * description: Local processor reads the nth Msg register from its inbound msg,
  108 + * or a PCI Master reads nth outbound msg from device
  109 + *
  110 + * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
  111 + *
  112 + * note:
  113 + * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
  114 + * If it is remote, outbound msg on the device is read; otherwise local inbound msg is read
  115 + *************************************************************************/
  116 +I2OSTATUS I2OMsgGet ( LOCATION loc, /* REMOTE/LOCAL */
  117 + unsigned int base, /*pcsrbar/eumbbar */
  118 + unsigned int n, /* 0 or 1 */
  119 + unsigned int *msg )
  120 +{
  121 + if ( n >= I2O_NUM_MSG || msg == 0 )
  122 + {
  123 + return I2OMSGINVALID;
  124 + }
  125 +
  126 + if ( loc == REMOTE )
  127 + {
  128 + /* read the outbound msg of the device, pcsrbar as base */
  129 + *msg = load_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET );
  130 + }
  131 + else
  132 + {
  133 + /* read the inbound msg sent by PCI master, eumbbar as base */
  134 + *msg = load_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET );
  135 + }
  136 +
  137 + return I2OSUCCESS;
  138 +}
  139 +
  140 +/***************************************************************
  141 + * function: I2OMsgPost
  142 + *
  143 + * description: Kahlua writes to its nth outbound msg register
  144 + * PCI master writes to nth inbound msg register of device
  145 + *
  146 + * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
  147 + *
  148 + * note:
  149 + * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
  150 + *
  151 + * If it is remote, inbound msg on the device is written; otherwise local outbound msg is written
  152 + ***************************************************************/
  153 +I2OSTATUS I2OMsgPost( LOCATION loc, /* REMOTE/LOCAL */
  154 + unsigned int base, /*pcsrbar/eumbbar */
  155 + unsigned int n, /* 0 or 1 */
  156 + unsigned int msg )
  157 +{
  158 + if ( n >= I2O_NUM_MSG )
  159 + {
  160 + return I2OMSGINVALID;
  161 + }
  162 +
  163 + if ( loc == REMOTE )
  164 + {
  165 + /* write to the inbound msg register of the device, pcsrbar as base */
  166 + store_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET, msg );
  167 + }
  168 + else
  169 + {
  170 + /* write to the outbound msg register for PCI master to read, eumbbar as base */
  171 + store_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET, msg );
  172 + }
  173 +
  174 + return I2OSUCCESS;
  175 +}
  176 +
  177 +/***********************************************************************
  178 + * function: I2ODBEnable
  179 + *
  180 + * description: Local processor enables it's inbound doorbell interrupt
  181 + * PCI master enables outbound doorbell interrupt of devices
  182 + * Other previously enabled interrupts are preserved.
  183 + * Return I2OSUCCESS if no error otherwise return I2ODBINVALID
  184 + *
  185 + * note:
  186 + * In DoorBell interrupt is generated by PCI master and serviced by local processor
  187 + * Out Doorbell interrupt is generated by local processor and serviced by PCI master
  188 + *
  189 + * Out Doorbell interrupt is generated by local processor and serviced by PCI master
  190 + * PCI master needs to enable the outbound doorbell interrupts of device it wants to handle
  191 + **********************************************************************/
  192 +I2OSTATUS I2ODBEnable( LOCATION loc, /* REMOTE/LOCAL */
  193 + unsigned int base, /* pcsrbar/eumbbar */
  194 + unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
  195 +{
  196 +
  197 + /* LOCATION - REMOTE : PCI master initializes outbound doorbell message of device
  198 + * LOCAL : Kahlua initializes its inbound doorbell message
  199 + */
  200 + unsigned int val;
  201 +
  202 + if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
  203 + {
  204 + return I2ODBINVALID;
  205 + }
  206 +
  207 + if ( loc == REMOTE )
  208 + {
  209 + /* pcsrbar is base */
  210 + val = load_runtime_reg( base, I2O_OMIMR );
  211 + val &= 0xfffffff7;
  212 + store_runtime_reg( base, I2O_OMIMR , val );
  213 + }
  214 + else
  215 + {
  216 + /* eumbbar is base */
  217 + val = load_runtime_reg( base, I2O_IMIMR);
  218 + in_db = ( (~in_db) & 0x3 ) << 3;
  219 + val = ( val & 0xffffffe7) | in_db;
  220 + store_runtime_reg( base, I2O_IMIMR, val );
  221 + }
  222 +
  223 + return I2OSUCCESS;
  224 +}
  225 +
  226 +/**********************************************************************************
  227 + * function: I2ODBDisable
  228 + *
  229 + * description: local processor disables its inbound DoorBell Interrupt
  230 + * PCI master disables outbound DoorBell interrupt of device
  231 + * Other previously enabled interrupts are preserved.
  232 + * return I2OSUCCESS if no error.Otherwise return I2ODBINVALID
  233 + *
  234 + * note:
  235 + * local processor needs to disable its inbound doorbell interrupts it is not interested
  236 + *
  237 + * PCI master needs to disable outbound doorbell interrupts of device it is not interested
  238 + ************************************************************************************/
  239 +I2OSTATUS I2ODBDisable( LOCATION loc, /* REMOTE/LOCAL */
  240 + unsigned int base, /* pcsrbar/eumbbar */
  241 + unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
  242 +{
  243 + /* LOCATION - REMOTE : handle device's out bound message initialization
  244 + * LOCAL : handle local in bound message initialization
  245 + */
  246 + unsigned int val;
  247 +
  248 + if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
  249 + {
  250 + return I2ODBINVALID;
  251 + }
  252 +
  253 + if ( loc == REMOTE )
  254 + {
  255 + /* pcsrbar is the base */
  256 + val = load_runtime_reg( base, I2O_OMIMR );
  257 + val |= 0x8;
  258 + store_runtime_reg( base, I2O_OMIMR, val );
  259 + }
  260 + else
  261 + {
  262 + val = load_runtime_reg( base, I2O_IMIMR);
  263 + in_db = ( in_db & 0x3 ) << 3;
  264 + val |= in_db;
  265 + store_runtime_reg( base, I2O_IMIMR, val );
  266 + }
  267 +
  268 + return I2OSUCCESS;
  269 +}
  270 +
  271 +/**********************************************************************************
  272 + * function: I2ODBGet
  273 + *
  274 + * description: Local processor reads its in doorbell register,
  275 + * PCI master reads the outdoorbell register of device.
  276 + * After a doorbell register is read, the whole register will be cleared.
  277 + * Otherwise, HW keeps generating interrupt.
  278 + *
  279 + * note:
  280 + * If it is not local, pcsrbar must be passed to the function.
  281 + * Otherwise eumbbar is passed.
  282 + *
  283 + * If it is remote, out doorbell register on the device is read.
  284 + * Otherwise local in doorbell is read
  285 + *
  286 + * If the register is not cleared by write to it, any remaining bit of b'1's
  287 + * will cause interrupt pending.
  288 + *********************************************************************************/
  289 +unsigned int I2ODBGet( LOCATION loc, /* REMOTE/LOCAL */
  290 + unsigned int base) /* pcsrbar/eumbbar */
  291 +{
  292 + unsigned int msg, val;
  293 +
  294 + if ( loc == REMOTE )
  295 + {
  296 + /* read outbound doorbell register of device, pcsrbar is the base */
  297 + val = load_runtime_reg( base, I2O_ODBR );
  298 + msg = val & 0xe0000000;
  299 + store_runtime_reg( base, I2O_ODBR, val ); /* clear the register */
  300 + }
  301 + else
  302 + {
  303 + /* read the inbound doorbell register, eumbbar is the base */
  304 + val = load_runtime_reg( base, I2O_IDBR );
  305 + store_runtime_reg( base, I2O_IDBR, val ); /* clear the register */
  306 + msg = val;
  307 + }
  308 +
  309 + return msg;
  310 +}
  311 +
  312 +/**********************************************************************
  313 + * function: I2ODBPost
  314 + *
  315 + * description: local processor writes to a outbound doorbell register,
  316 + * PCI master writes to the inbound doorbell register of device
  317 + *
  318 + * note:
  319 + * If it is not local, pcsrbar must be passed to the function.
  320 + * Otherwise eumbbar is passed.
  321 + *
  322 + * If it is remote, in doorbell register on the device is written.
  323 + * Otherwise local out doorbell is written
  324 + *********************************************************************/
  325 +void I2ODBPost( LOCATION loc, /* REMOTE/LOCAL */
  326 + unsigned int base, /* pcsrbar/eumbbar */
  327 + unsigned int msg ) /* in / out */
  328 +{
  329 + if ( loc == REMOTE )
  330 + {
  331 + /* write to inbound doorbell register of device, pcsrbar is the base */
  332 + store_runtime_reg( base, I2O_IDBR, msg );
  333 + }
  334 + else
  335 + {
  336 + /* write to local outbound doorbell register, eumbbar is the base */
  337 + store_runtime_reg( base, I2O_ODBR, msg & 0x1fffffff );
  338 + }
  339 +
  340 +}
  341 +
  342 +/********************************************************************
  343 + * function: I2OOutMsgStatGet
  344 + *
  345 + * description: PCI master reads device's outbound msg unit interrupt status.
  346 + * Reading an interrupt status register,
  347 + * the register will be cleared.
  348 + *
  349 + * The value of the status register is AND with the outbound
  350 + * interrupt mask and result is returned.
  351 + *
  352 + * note:
  353 + * pcsrbar must be passed to the function.
  354 + ********************************************************************/
  355 +I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT *val )
  356 +{
  357 + unsigned int stat;
  358 + unsigned int mask;
  359 +
  360 + if ( val == 0 )
  361 + {
  362 + return I2OINVALID;
  363 + }
  364 +
  365 + /* read device's outbound status */
  366 + stat = load_runtime_reg( pcsrbar, I2O_OMISR );
  367 + mask = load_runtime_reg( pcsrbar, I2O_OMIMR );
  368 + store_runtime_reg( pcsrbar, I2O_OMISR, stat & 0xffffffd7);
  369 +
  370 + stat &= mask;
  371 + val->rsvd0 = ( stat & 0xffffffc0 ) >> 6;
  372 + val->opqi = ( stat & 0x00000020 ) >> 5;
  373 + val->rsvd1 = ( stat & 0x00000010 ) >> 4;
  374 + val->odi = ( stat & 0x00000008 ) >> 3;
  375 + val->rsvd2 = ( stat & 0x00000004 ) >> 2;
  376 + val->om1i = ( stat & 0x00000002 ) >> 1;
  377 + val->om0i = ( stat & 0x00000001 );
  378 +
  379 + return I2OSUCCESS;
  380 +}
  381 +
  382 +/********************************************************************
  383 + * function: I2OInMsgStatGet
  384 + *
  385 + * description: Local processor reads its inbound msg unit interrupt status.
  386 + * Reading an interrupt status register,
  387 + * the register will be cleared.
  388 + *
  389 + * The inbound msg interrupt status is AND with the inbound
  390 + * msg interrupt mask and result is returned.
  391 + *
  392 + * note:
  393 + * eumbbar must be passed to the function.
  394 + ********************************************************************/
  395 +I2OSTATUS I2OInMsgStatGet(unsigned int eumbbar, I2OIMSTAT *val)
  396 +{
  397 + unsigned int stat;
  398 + unsigned int mask;
  399 +
  400 + if ( val == 0 )
  401 + {
  402 + return I2OINVALID;
  403 + }
  404 +
  405 + /* read device's outbound status */
  406 + stat = load_runtime_reg( eumbbar, I2O_OMISR );
  407 + mask = load_runtime_reg( eumbbar, I2O_OMIMR );
  408 + store_runtime_reg( eumbbar, I2O_OMISR, stat & 0xffffffe7 );
  409 +
  410 + stat &= mask;
  411 + val->rsvd0 = ( stat & 0xfffffe00 ) >> 9;
  412 + val->ofoi = ( stat & 0x00000100 ) >> 8;
  413 + val->ipoi = ( stat & 0x00000080 ) >> 7;
  414 + val->rsvd1 = ( stat & 0x00000040 ) >> 6;
  415 + val->ipqi = ( stat & 0x00000020 ) >> 5;
  416 + val->mci = ( stat & 0x00000010 ) >> 4;
  417 + val->idi = ( stat & 0x00000008 ) >> 3;
  418 + val->rsvd2 = ( stat & 0x00000004 ) >> 2;
  419 + val->im1i = ( stat & 0x00000002 ) >> 1;
  420 + val->im0i = ( stat & 0x00000001 );
  421 +
  422 + return I2OSUCCESS;
  423 +
  424 +}
  425 +
  426 +/***********************************************************
  427 + * function: I2OFIFOInit
  428 + *
  429 + * description: Configure the I2O FIFO, including QBAR,
  430 + * IFHPR/IFTPR, IPHPR/IPTPR, OFHPR/OFTPR,
  431 + * OPHPR/OPTPR, MUCR.
  432 + *
  433 + * return I2OSUCCESS if no error,
  434 + * otherwise return I2OQUEINVALID
  435 + *
  436 + * note: It is NOT this driver's responsibility of initializing
  437 + * MFA blocks, i.e., FIFO queue itself. The MFA blocks
  438 + * must be initialized before I2O unit can be used.
  439 + ***********************************************************/
  440 +I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
  441 + QUEUE_SIZE sz, /* value of CQS of MUCR */
  442 + unsigned int qba) /* queue base address that must be aligned at 1M */
  443 +{
  444 +
  445 + if ( ( qba & 0xfffff ) != 0 )
  446 + {
  447 + /* QBA must be aligned at 1Mbyte boundary */
  448 + return I2OQUEINVALID;
  449 + }
  450 +
  451 + store_runtime_reg( eumbbar, I2O_QBAR, qba );
  452 + store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz );
  453 + store_runtime_reg( eumbbar, I2O_IFHPR, qba );
  454 + store_runtime_reg( eumbbar, I2O_IFTPR, qba );
  455 + store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 ));
  456 + store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 ));
  457 + store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 ));
  458 + store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 ));
  459 + store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 ));
  460 + store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 ));
  461 +
  462 + fifo_stat.qsz = sz;
  463 + fifo_stat.qba = qba;
  464 +
  465 + return I2OSUCCESS;
  466 +}
  467 +
  468 +/**************************************************
  469 + * function: I2OFIFOEnable
  470 + *
  471 + * description: Enable the circular queue
  472 + * return I2OSUCCESS if no error.
  473 + * Otherwise I2OQUEINVALID is returned.
  474 + *
  475 + * note:
  476 + *************************************************/
  477 +I2OSTATUS I2OFIFOEnable( unsigned int eumbbar )
  478 +{
  479 + unsigned int val;
  480 +
  481 + if ( fifo_stat.qba == 0xfffffff )
  482 + {
  483 + return I2OQUEINVALID;
  484 + }
  485 +
  486 + val = load_runtime_reg( eumbbar, I2O_MUCR );
  487 + store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 );
  488 +
  489 + return I2OSUCCESS;
  490 +}
  491 +
  492 +/**************************************************
  493 + * function: I2OFIFODisable
  494 + *
  495 + * description: Disable the circular queue
  496 + *
  497 + * note:
  498 + *************************************************/
  499 +void I2OFIFODisable( unsigned int eumbbar )
  500 +{
  501 + if ( fifo_stat.qba == 0xffffffff )
  502 + {
  503 + /* not enabled */
  504 + return;
  505 + }
  506 +
  507 + unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR );
  508 + store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );
  509 +}
  510 +
  511 +/****************************************************
  512 + * function: I2OFIFOAlloc
  513 + *
  514 + * description: Allocate a free MFA from free FIFO.
  515 + * return I2OSUCCESS if no error.
  516 + * return I2OQUEEMPTY if no more free MFA.
  517 + * return I2OINVALID on other errors.
  518 + *
  519 + * A free MFA must be allocated before a
  520 + * message can be posted.
  521 + *
  522 + * note:
  523 + * PCI Master allocates a free MFA from inbound queue of device
  524 + * (pcsrbar is the base,) through the inbound queue port of device
  525 + * while local processor allocates a free MFA from its outbound
  526 + * queue (eumbbar is the base.)
  527 + *
  528 + ****************************************************/
  529 +I2OSTATUS I2OFIFOAlloc( LOCATION loc,
  530 + unsigned int base,
  531 + void **pMsg )
  532 +{
  533 + I2OSTATUS stat = I2OSUCCESS;
  534 + void *pHdr, *pTil;
  535 +
  536 + if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
  537 + {
  538 + /* not configured */
  539 + return I2OQUEINVALID;
  540 + }
  541 +
  542 + if ( loc == REMOTE )
  543 + {
  544 + /* pcsrbar is the base and read the inbound free tail ptr */
  545 + pTil = (void *)load_runtime_reg( base, I2O_IFQPR );
  546 + if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
  547 + {
  548 + stat = I2OQUEEMPTY;
  549 + }
  550 + else
  551 + {
  552 + *pMsg = pTil;
  553 + }
  554 + }
  555 + else
  556 + {
  557 + /* eumbbar is the base and read the outbound free tail ptr */
  558 + pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */
  559 + pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */
  560 +
  561 + /* check underflow */
  562 + if ( pHdr == pTil )
  563 + {
  564 + /* hdr and til point to the same fifo item, no free MFA */
  565 + stat = I2OQUEEMPTY;
  566 + }
  567 + else
  568 + {
  569 + /* update OFTPR */
  570 + *pMsg = (void *)(*(unsigned char *)pTil);
  571 + pTil = (void *)((unsigned int)pTil + 4);
  572 + if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) )
  573 + {
  574 + /* reach the upper limit */
  575 + pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) ));
  576 + }
  577 + store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil );
  578 + }
  579 + }
  580 +
  581 + return stat;
  582 +}
  583 +
  584 +/******************************************************
  585 + * function: I2OFIFOFree
  586 + *
  587 + * description: Free a used MFA back to free queue after
  588 + * use.
  589 + * return I2OSUCCESS if no error.
  590 + * return I2OQUEFULL if inbound free queue
  591 + * overflow
  592 + *
  593 + * note: PCI Master frees a MFA into device's outbound queue
  594 + * (OFQPR) while local processor frees a MFA into its
  595 + * inbound queue (IFHPR).
  596 + *****************************************************/
  597 +I2OSTATUS I2OFIFOFree( LOCATION loc,
  598 + unsigned int base,
  599 + void *pMsg )
  600 +{
  601 + void **pHdr, **pTil;
  602 + I2OSTATUS stat = I2OSUCCESS;
  603 +
  604 + if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
  605 + {
  606 + return I2OQUEINVALID;
  607 + }
  608 +
  609 + if ( loc == REMOTE )
  610 + {
  611 + /* pcsrbar is the base */
  612 + store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg );
  613 + }
  614 + else
  615 + {
  616 + /* eumbbar is the base */
  617 + pHdr = (void **)load_runtime_reg( base, I2O_IFHPR );
  618 + pTil = (void **)load_runtime_reg( base, I2O_IFTPR );
  619 +
  620 + /* store MFA */
  621 + *pHdr = pMsg;
  622 +
  623 + /* update IFHPR */
  624 + pHdr += 4;
  625 +
  626 + if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) )
  627 + {
  628 + /* reach the upper limit */
  629 + pHdr = (void **)fifo_stat.qba;
  630 + }
  631 +
  632 + /* check inbound free queue overflow */
  633 + if ( pHdr != pTil )
  634 + {
  635 + store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
  636 + }
  637 + else
  638 + {
  639 + stat = I2OQUEFULL;
  640 + }
  641 +
  642 + }
  643 +
  644 + return stat;
  645 +
  646 +}
  647 +
  648 +/*********************************************
  649 + * function: I2OFIFOPost
  650 + *
  651 + * description: Post a msg into FIFO post queue
  652 + * the value of msg must be the one
  653 + * returned by I2OFIFOAlloc
  654 + *
  655 + * note: PCI Master posts a msg into device's inbound queue
  656 + * (IFQPR) while local processor post a msg into device's
  657 + * outbound queue (OPHPR)
  658 + *********************************************/
  659 +I2OSTATUS I2OFIFOPost( LOCATION loc,
  660 + unsigned int base,
  661 + void *pMsg )
  662 +{
  663 + void **pHdr, **pTil;
  664 + I2OSTATUS stat = I2OSUCCESS;
  665 +
  666 + if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
  667 + {
  668 + return I2OQUEINVALID;
  669 + }
  670 +
  671 + if ( loc == REMOTE )
  672 + {
  673 + /* pcsrbar is the base */
  674 + store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg );
  675 + }
  676 + else
  677 + {
  678 + /* eumbbar is the base */
  679 + pHdr = (void **)load_runtime_reg( base, I2O_OPHPR );
  680 + pTil = (void **)load_runtime_reg( base, I2O_OPTPR );
  681 +
  682 + /* store MFA */
  683 + *pHdr = pMsg;
  684 +
  685 + /* update IFHPR */
  686 + pHdr += 4;
  687 +
  688 + if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) )
  689 + {
  690 + /* reach the upper limit */
  691 + pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) );
  692 + }
  693 +
  694 + /* check post queue overflow */
  695 + if ( pHdr != pTil )
  696 + {
  697 + store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
  698 + }
  699 + else
  700 + {
  701 + stat = I2OQUEFULL;
  702 + }
  703 + }
  704 +
  705 + return stat;
  706 +}
  707 +
  708 +/************************************************
  709 + * function: I2OFIFOGet
  710 + *
  711 + * description: Read a msg from FIFO
  712 + * This function should be called
  713 + * only when there is a corresponding
  714 + * msg interrupt.
  715 + *
  716 + * note: PCI Master reads a msg from device's outbound queue
  717 + * (OFQPR) while local processor reads a msg from device's
  718 + * inbound queue (IPTPR)
  719 + ************************************************/
  720 +I2OSTATUS I2OFIFOGet( LOCATION loc,
  721 + unsigned int base,
  722 + void **pMsg )
  723 +{
  724 + I2OSTATUS stat = I2OSUCCESS;
  725 + void *pHdr, *pTil;
  726 +
  727 + if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
  728 + {
  729 + /* not configured */
  730 + return I2OQUEINVALID;
  731 + }
  732 +
  733 + if ( loc == REMOTE )
  734 + {
  735 + /* pcsrbar is the base */
  736 + pTil = (void *)load_runtime_reg( base, I2O_OFQPR );
  737 + if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
  738 + {
  739 + stat = I2OQUEEMPTY;
  740 + }
  741 + else
  742 + {
  743 + *pMsg = pTil;
  744 + }
  745 + }
  746 + else
  747 + {
  748 + /* eumbbar is the base and read the outbound free tail ptr */
  749 + pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */
  750 + pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */
  751 +
  752 + /* check underflow */
  753 + if ( pHdr == pTil )
  754 + {
  755 + /* no free MFA */
  756 + stat = I2OQUEEMPTY;
  757 + }
  758 + else
  759 + {
  760 + /* update OFTPR */
  761 + *pMsg = (void *)(*(unsigned char *)pTil);
  762 + pTil = (void *)((unsigned int)pTil + 4);
  763 + if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) )
  764 + {
  765 + /* reach the upper limit */
  766 + pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) );
  767 + }
  768 +
  769 + store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil );
  770 + }
  771 + }
  772 +
  773 + return stat;
  774 +}
  775 +
  776 +/********************************************************
  777 + * function: I2OIOP
  778 + *
  779 + * description: Get the I2O PCI configuration identification
  780 + * register.
  781 + *
  782 + * note: PCI master should pass pcsrbar while local processor
  783 + * should pass eumbbar.
  784 + *********************************************************/
  785 +I2OSTATUS I2OPCIConfigGet( LOCATION loc,
  786 + unsigned int base,
  787 + I2OIOP * val)
  788 +{
  789 + unsigned int tmp;
  790 + if ( val == 0 )
  791 + {
  792 + return I2OINVALID;
  793 + }
  794 + tmp = load_runtime_reg( base, PCI_CFG_CLA );
  795 + val->base_class = ( tmp & 0xFF) << 16;
  796 + tmp = load_runtime_reg( base, PCI_CFG_SCL );
  797 + val->sub_class= ( (tmp & 0xFF) << 8 );
  798 + tmp = load_runtime_reg( base, PCI_CFG_PIC );
  799 + val->prg_code = (tmp & 0xFF);
  800 + return I2OSUCCESS;
  801 +}
  802 +
  803 +/*********************************************************
  804 + * function: I2OFIFOIntEnable
  805 + *
  806 + * description: Enable the circular post queue interrupt
  807 + *
  808 + * note:
  809 + * PCI master enables outbound FIFO interrupt of device
  810 + * pscrbar is the base
  811 + * Device enables its inbound FIFO interrupt
  812 + * eumbbar is the base
  813 + *******************************************************/
  814 +void I2OFIFOIntEnable( LOCATION loc, unsigned int base )
  815 +{
  816 + unsigned int reg, val;
  817 +
  818 + /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
  819 + * LOCAL : enable local inbound message, eumbbar as base
  820 + */
  821 + reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
  822 + val = load_runtime_reg( base, reg );
  823 +
  824 + val &= 0xffffffdf; /* clear the msg interrupt bits */
  825 + store_runtime_reg( base, reg, val );
  826 +
  827 +}
  828 +
  829 +/****************************************************
  830 + * function: I2OFIFOIntDisable
  831 + *
  832 + * description: Disable the circular post queue interrupt
  833 + *
  834 + * note:
  835 + * PCI master disables outbound FIFO interrupt of device
  836 + * (pscrbar is the base)
  837 + * Device disables its inbound FIFO interrupt
  838 + * (eumbbar is the base)
  839 + *****************************************************/
  840 +void I2OFIFOIntDisable( LOCATION loc, unsigned int base )
  841 +{
  842 +
  843 + /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
  844 + * LOCAL : disable local inbound message interrupt, eumbbar as base
  845 + */
  846 + unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
  847 + unsigned int val = load_runtime_reg( base, reg );
  848 +
  849 + val |= 0x00000020; /* masked out the msg interrupt bits */
  850 + store_runtime_reg( base, reg, val );
  851 +
  852 +}
  853 +
  854 +/*********************************************************
  855 + * function: I2OFIFOOverflowIntEnable
  856 + *
  857 + * description: Enable the circular queue overflow interrupt
  858 + *
  859 + * note:
  860 + * Device enables its inbound FIFO post overflow interrupt
  861 + * and outbound free overflow interrupt.
  862 + * eumbbar is the base
  863 + *******************************************************/
  864 +void I2OFIFOOverflowIntEnable( unsigned int eumbbar )
  865 +{
  866 + unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
  867 +
  868 + val &= 0xfffffe7f; /* clear the two overflow interrupt bits */
  869 + store_runtime_reg( eumbbar, I2O_IMIMR, val );
  870 +
  871 +}
  872 +
  873 +/****************************************************
  874 + * function: I2OFIFOOverflowIntDisable
  875 + *
  876 + * description: Disable the circular queue overflow interrupt
  877 + *
  878 + * note:
  879 + * Device disables its inbound post FIFO overflow interrupt
  880 + * and outbound free FIFO overflow interrupt
  881 + * (eumbbar is the base)
  882 + *****************************************************/
  883 +void I2OFIFOOverflowIntDisable( unsigned int eumbbar )
  884 +{
  885 +
  886 + unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
  887 +
  888 + val |= 0x00000180; /* masked out the msg overflow interrupt bits */
  889 + store_runtime_reg( eumbbar, I2O_IMIMR, val );
  890 +}
cpu/mpc824x/drivers/i2o/i2o2.S
  1 +/**************************************
  2 + *
  3 + * copyright @ Motorola, 1999
  4 + *
  5 + **************************************/
  6 +
  7 +/**********************************************************
  8 + * function: load_runtime_reg
  9 + *
  10 + * input: r3 - value of eumbbar
  11 + * r4 - register offset in embedded utility space
  12 + *
  13 + * output: r3 - register content
  14 + **********************************************************/
  15 + .text
  16 + .align 2
  17 + .global load_runtime_reg
  18 +
  19 +load_runtime_reg:
  20 +
  21 + xor r5,r5,r5
  22 + or r5,r5,r3 /* save eumbbar */
  23 +
  24 + lwbrx r3,r4,r5
  25 + sync
  26 +
  27 + bclr 20, 0
  28 +
  29 +/****************************************************************
  30 + * function: store_runtime_reg
  31 + *
  32 + * input: r3 - value of eumbbar
  33 + * r4 - register offset in embedded utility space
  34 + * r5 - new value to be stored
  35 + *
  36 + ****************************************************************/
  37 + .text
  38 + .align 2
  39 + .global store_runtime_reg
  40 +store_runtime_reg:
  41 +
  42 + xor r0,r0,r0
  43 +
  44 + stwbrx r5, r4, r3
  45 + sync
  46 +
  47 + bclr 20,0