diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-25 10:22:37 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-25 10:30:20 +0200 |
commit | 8f12ee32b647fa6b26c20ba1b6ba7133e5349cea (patch) | |
tree | 11c9b64b72ecc3429986224e42c9b33e41b5ffda /bsps/powerpc/mvme5500 | |
parent | bsp/virtex5: Move mmu.c to bsps (diff) | |
download | rtems-8f12ee32b647fa6b26c20ba1b6ba7133e5349cea.tar.bz2 |
bsp/mvme5500: Move source files to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/powerpc/mvme5500')
-rw-r--r-- | bsps/powerpc/mvme5500/GT64260/GT64260TWSI.c | 214 | ||||
-rw-r--r-- | bsps/powerpc/mvme5500/GT64260/MVME5500I2C.c | 107 | ||||
-rw-r--r-- | bsps/powerpc/mvme5500/start/exceptionhandler.c | 221 |
3 files changed, 542 insertions, 0 deletions
diff --git a/bsps/powerpc/mvme5500/GT64260/GT64260TWSI.c b/bsps/powerpc/mvme5500/GT64260/GT64260TWSI.c new file mode 100644 index 0000000000..6b5b46e511 --- /dev/null +++ b/bsps/powerpc/mvme5500/GT64260/GT64260TWSI.c @@ -0,0 +1,214 @@ +/* + * Two-Wire Serial Interface (TWSI) support for the GT64260 + */ + +/* + * Copyright (c) 2004, Brookhaven National Laboratory and + * Shuchen Kate Feng <feng1@bnl.gov> + * All rights reserved. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution. + * + * See section 24:TWSI interface of "the GT-64260B System Controller + * for powerPc Processors Data Sheet". + * + * For full TWSI protocol description look in Philips Semiconductor + * TWSI spec. + * + * We need it to read out I2C devices used for the MVME5500 + * (eg. the memory SPD and VPD). + */ + +#include <libcpu/spr.h> /*registers.h included here for rtems_bsp_delay()*/ +#include <libcpu/io.h> +#include <rtems/bspIo.h> + +#include "bsp/gtreg.h" +#include "bsp/GT64260TWSI.h" + +#define MAX_LOOP 100 + +#define TWSI_DEBUG 0 + +static int TWSI_initFlg = 0; /* TWSI Initialization Flag */ + +void GT64260TWSIinit(void) +{ + if ( !TWSI_initFlg ) { +#if TWSI_DEBUG + printk("GT64260TWSIinit("); +#endif + outl( 0, TWSI_SFT_RST); /* soft reset */ + rtems_bsp_delay(1000); + + /* See 24.2.5 : Assume bus speed is 133MHZ + * Try to be close to the default frequency : 62.5KHZ + * value 0x2c: 69.27 KHz TWSI bus clock + */ + outl(0x2c, TWSI_BAUDE_RATE); + rtems_bsp_delay(1000); + + /* Set Acknowledge and enable TWSI in the Control register */ + outl(0x44, TWSI_CTRL); + rtems_bsp_delay(4000); + TWSI_initFlg = 1; +#if TWSI_DEBUG + printk(")\n"); +#endif + } +} + +/* return the interrupt flag */ +static int GT64260TWSIintFlag(void) +{ + unsigned int loop; + + for (loop = 0; loop < MAX_LOOP; loop++ ) { + /* Return 1 if the interrupt flag is set */ + if (inl(TWSI_CTRL) & TWSI_INTFLG) + return(1); + rtems_bsp_delay(1000); + } + return(0); +} + +int GT64260TWSIstop(void) +{ + +#if TWSI_DEBUG + printk("GT64260TWSIstop("); +#endif + + outl((inl(TWSI_CTRL) | TWSI_STOP), TWSI_CTRL); + rtems_bsp_delay(1000); + + /* Check if interrupt flag bit is set*/ + if (GT64260TWSIintFlag()) { + outl((inl( TWSI_CTRL) & ~TWSI_INTFLG), TWSI_CTRL); + rtems_bsp_delay(1000); +#if TWSI_DEBUG + printk(")\n"); +#endif + return(0); + } +#if TWSI_DEBUG + printk("NoIntFlag\n"); +#endif + return(-1); +} + +int GT64260TWSIstart(void) +{ + unsigned int loop; + unsigned int status; + +#if TWSI_DEBUG + printk("GT64260TWSIstart("); +#endif + /* Initialize the TWSI interface */ + GT64260TWSIinit(); + + /* set the start bit */ + outl((TWSI_START | TWSI_TWSIEN), TWSI_CTRL); + rtems_bsp_delay(1000); + + if (GT64260TWSIintFlag()) { + /* Check for completion of START sequence */ + for (loop = 0; loop<MAX_LOOP; loop++ ) { + /* if (start condition transmitted) || + * (repeated start condition transmitted ) + */ + if (((status= inl( TWSI_STATUS)) == 8) || (status == 0x10)) { +#if TWSI_DEBUG + printk(")"); +#endif + return(0); + } + rtems_bsp_delay(1000); + } + } + /* if loop ends or intFlag ==0 */ + GT64260TWSIstop(); + return(-1); +} + +int GT64260TWSIread(unsigned char * pData, int lastByte) +{ + unsigned int loop; + +#if TWSI_DEBUG + printk("GT64260TWSIread("); +#endif + /* Clear INTFLG and set ACK and ENABLE bits */ + outl((TWSI_ACK | TWSI_TWSIEN), TWSI_CTRL); + rtems_bsp_delay(1000); + + if (GT64260TWSIintFlag()) { + for (loop = 0; loop< MAX_LOOP; loop++) { + /* if Master received read data, acknowledge transmitted */ + if ( (inl( TWSI_STATUS) == 0x50)) { + *pData = (unsigned char) inl( TWSI_DATA); + rtems_bsp_delay(1500); + + /* Clear INTFLAG and set Enable bit only */ + if (lastByte) + outl(TWSI_TWSIEN, TWSI_CTRL); + rtems_bsp_delay(1500); +#if TWSI_DEBUG + printk(")\n"); +#endif + return(0); + } + rtems_bsp_delay(1000); + } /* end for */ + } + /* if loop ends or intFlag ==0 */ + GT64260TWSIstop(); + return(-1); +} + +/* do a TWSI write cycle on the TWSI bus*/ +int GT64260TWSIwrite(unsigned char Data) +{ + unsigned int loop; + unsigned int status; + +#if TWSI_DEBUG + printk("GT64260TWSIwrite("); +#endif + /* Write data into the TWSI data register */ + outl(((unsigned int) Data), TWSI_DATA); + rtems_bsp_delay(1000); + + /* Clear INTFLG in the control register to drive data onto TWSI bus */ + outl(0, TWSI_CTRL); + rtems_bsp_delay(1000); + + if (GT64260TWSIintFlag() ) { + for (loop = 0; loop< MAX_LOOP; loop++) { + rtems_bsp_delay(1000); + /* if address + write bit transmitted, acknowledge not received */ + if ( (status = inl( TWSI_STATUS)) == 0x20) { + /* No device responding, generate STOP and return -1 */ + printk("no device responding\n"); + GT64260TWSIstop(); + return(-1); + } + /* if (address + write bit transmitted, acknowledge received) + * (Master transmmitted data byte, acknowledge received) + * (address + read bit transmitted, acknowledge received) + */ + if ((status == 0x18)||(status == 0x28)||(status == 0x40)) { +#if TWSI_DEBUG + printk(")\n"); +#endif + return(0); + } + rtems_bsp_delay(1000); + } /* end for */ + } + printk("No correct status, timeout\n"); + GT64260TWSIstop(); + return(-1); +} diff --git a/bsps/powerpc/mvme5500/GT64260/MVME5500I2C.c b/bsps/powerpc/mvme5500/GT64260/MVME5500I2C.c new file mode 100644 index 0000000000..107b8f15cb --- /dev/null +++ b/bsps/powerpc/mvme5500/GT64260/MVME5500I2C.c @@ -0,0 +1,107 @@ +/* + * To read information of the EEPROM via the I2C + */ + +/* + * Copyright (c) 2003, 2004 Brookhaven National Laboratory + * Author: S. Kate Feng <feng1@bnl.gov> + * All rights reserved. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution. + */ + +#include <bsp.h> +#include <rtems/bspIo.h> /* printk */ +#include <stdint.h> /* uint32_t */ +#include "bsp/GT64260TWSI.h" + +/* #define I2C_DEBUG*/ + +static unsigned char I2cAddrPack(unsigned char busAddr,uint32_t offset) +{ + return(busAddr | ((offset & 0x700) >> 7)); +} + +static unsigned char I2cDevByteAddr(uint32_t devA2A1A0, unsigned char byteNum) +{ + return(( devA2A1A0 >>(byteNum*8)) & 0xff); +} +/**************************************************************************** +* I2Cread_eeprom - read EEPROM VPD from the I2C +*/ +int I2Cread_eeprom( + unsigned char I2cBusAddr, + uint32_t devA2A1A0, + uint32_t AddrBytes, + unsigned char *pBuff, + uint32_t numBytes +) +{ + int status=0, lastByte=0; + + switch (AddrBytes) { + case 1: + if ((status=GT64260TWSIstart()) != -1) { + if ((status=GT64260TWSIwrite(I2cAddrPack(I2cBusAddr,devA2A1A0)))!= -1){ + if ((status=GT64260TWSIwrite(devA2A1A0))!=-1){ + if ((status=GT64260TWSIstart())!=-1) + status=GT64260TWSIwrite(I2cAddrPack((I2cBusAddr|0x01),devA2A1A0)); + } + } + } + break; + case 2: + if ((status=GT64260TWSIstart())!=-1) { + if ((status=GT64260TWSIwrite(I2cBusAddr))!= -1) { + if ((status=GT64260TWSIwrite(I2cDevByteAddr(devA2A1A0,1)))!=-1) { + if ((status=GT64260TWSIwrite(I2cDevByteAddr(devA2A1A0,0)))!= -1){ + if ((status=GT64260TWSIstart()) != -1) { + status = GT64260TWSIwrite((I2cBusAddr | 0x01)); + } + } + } + } + } + break; + case 3: + if ((status = GT64260TWSIstart())!= -1) { + if ((status = GT64260TWSIwrite(I2cBusAddr))!= -1) { + if ((status=GT64260TWSIwrite(I2cDevByteAddr(devA2A1A0,2)))!= -1){ + if ((status=GT64260TWSIwrite(I2cDevByteAddr(devA2A1A0,1)))!= -1){ + if ((status=GT64260TWSIwrite(I2cDevByteAddr(devA2A1A0,0)))!= -1){ + if ((status=GT64260TWSIstart())!= -1) { + status = GT64260TWSIwrite(I2cBusAddr | 0x01); + } + } + } + } + } + } + break; + default: + status=-1; + break; + } + if (status !=-1) { +#ifdef I2C_DEBUG + printk("\n"); +#endif + /* read data from device */ + for ( ; numBytes > 0; numBytes-- ) { + if ( numBytes == 1) lastByte=1; + if (GT64260TWSIread(pBuff,lastByte) == -1) return (-1); +#ifdef I2C_DEBUG + printk("%2x ", *pBuff); + if ( (numBytes % 20)==0 ) printk("\n"); +#endif + pBuff++; + } +#ifdef I2C_DEBUG + printk("\n"); +#endif + if (GT64260TWSIstop() == -1) return (-1); + } + return (status); +} + diff --git a/bsps/powerpc/mvme5500/start/exceptionhandler.c b/bsps/powerpc/mvme5500/start/exceptionhandler.c new file mode 100644 index 0000000000..be5f78f2d3 --- /dev/null +++ b/bsps/powerpc/mvme5500/start/exceptionhandler.c @@ -0,0 +1,221 @@ +/* + * Authorship + * ---------- + * This software was created by + * Till Straumann <strauman@slac.stanford.edu>, 5/2002, + * Stanford Linear Accelerator Center, Stanford University. + * + * Acknowledgement of sponsorship + * ------------------------------ + * This software was produced by + * the Stanford Linear Accelerator Center, Stanford University, + * under Contract DE-AC03-76SFO0515 with the Department of Energy. + * + * Government disclaimer of liability + * ---------------------------------- + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, or + * assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately owned + * rights. + * + * Stanford disclaimer of liability + * -------------------------------- + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * Stanford disclaimer of copyright + * -------------------------------- + * Stanford University, owner of the copyright, hereby disclaims its + * copyright and all other rights in this software. Hence, anyone may + * freely use it for any purpose without restriction. + * + * Maintenance of notices + * ---------------------- + * In the interest of clarity regarding the origin and status of this + * SLAC software, this and all the preceding Stanford University notices + * are to remain affixed to any copy or derivative of this software made + * or distributed by the recipient and are to be affixed to any copy of + * software made or distributed by the recipient that contains a copy or + * derivative of this software. + * + * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 + */ +/* Copyright : + * (C) S. Kate Feng <feng1@bnl.gov> 4/2004 modified it for MVME5500 + */ + +#include <bsp.h> +#include <bsp/vectors.h> +#include <bsp/bootcard.h> +#include <libcpu/spr.h> +#include <bsp/pci.h> +#include <rtems/bspIo.h> +#include <rtems/score/percpu.h> +#include <threads.h> +#include <inttypes.h> + +#include <bsp/bspException.h> + +#define SRR1_TEA_EXC (1<<(31-13)) +#define SRR1_MCP_EXC (1<<(31-12)) + +static thread_local volatile BSP_ExceptionExtension BSP_exceptionExtension = 0; + +BSP_ExceptionExtension +BSP_exceptionHandlerInstall(BSP_ExceptionExtension e) +{ +volatile BSP_ExceptionExtension test; + test = BSP_exceptionExtension; + BSP_exceptionExtension = e; + return test; +} + +void +BSP_exceptionHandler(BSP_Exception_frame* excPtr) +{ +BSP_ExceptionExtension ext=0; +rtems_id id=0; +int recoverable = 0; +char *fmt="Uhuuuh, Exception %d in unknown task???\n"; +int quiet=0; + + if (!quiet) printk("In BSP_exceptionHandler()\n"); + /* If we are in interrupt context, we are in trouble - skip the user + * hook and panic + */ + if (rtems_interrupt_is_in_progress()) { + fmt="Aieeh, Exception %d in interrupt handler\n"; + } else if ( !_Thread_Executing) { + fmt="Aieeh, Exception %d in initialization code\n"; + } else { + /* retrieve the notepad which possibly holds an extention pointer */ + if (RTEMS_SUCCESSFUL==rtems_task_ident(RTEMS_SELF,RTEMS_LOCAL,&id)) { + ext = BSP_exceptionExtension; + if (ext) + quiet=ext->quiet; + if (!quiet) { + printk("Task (Id 0x%08" PRIx32 ") got ",id); + } + fmt="exception %d\n"; + } + } + + if (ext && ext->lowlevelHook && ext->lowlevelHook(excPtr,ext,0)) { + /* they did all the work and want us to do nothing! */ + printk("they did all the work and want us to do nothing!\n"); + return; + } + + if (!quiet) { + /* message about exception */ + printk(fmt, excPtr->_EXC_number); + /* register dump */ + printk("\t Next PC or Address of fault = %" PRIxPTR ", ", excPtr->EXC_SRR0); + printk("Mvme5500 Saved MSR = %" PRIxPTR "\n", excPtr->EXC_SRR1); + printk("\t R0 = %08" PRIxPTR, excPtr->GPR0); + printk(" R1 = %08" PRIxPTR, excPtr->GPR1); + printk(" R2 = %08" PRIxPTR, excPtr->GPR2); + printk(" R3 = %08" PRIxPTR "\n", excPtr->GPR3); + printk("\t R4 = %08" PRIxPTR, excPtr->GPR4); + printk(" R5 = %08" PRIxPTR, excPtr->GPR5); + printk(" R6 = %08" PRIxPTR, excPtr->GPR6); + printk(" R7 = %08" PRIxPTR "\n", excPtr->GPR7); + printk("\t R8 = %08" PRIxPTR, excPtr->GPR8); + printk(" R9 = %08" PRIxPTR, excPtr->GPR9); + printk(" R10 = %08" PRIxPTR, excPtr->GPR10); + printk(" R11 = %08" PRIxPTR "\n", excPtr->GPR11); + printk("\t R12 = %08" PRIxPTR, excPtr->GPR12); + printk(" R13 = %08" PRIxPTR, excPtr->GPR13); + printk(" R14 = %08" PRIxPTR, excPtr->GPR14); + printk(" R15 = %08" PRIxPTR "\n", excPtr->GPR15); + printk("\t R16 = %08" PRIxPTR, excPtr->GPR16); + printk(" R17 = %08" PRIxPTR, excPtr->GPR17); + printk(" R18 = %08" PRIxPTR, excPtr->GPR18); + printk(" R19 = %08" PRIxPTR "\n", excPtr->GPR19); + printk("\t R20 = %08" PRIxPTR, excPtr->GPR20); + printk(" R21 = %08" PRIxPTR, excPtr->GPR21); + printk(" R22 = %08" PRIxPTR, excPtr->GPR22); + printk(" R23 = %08" PRIxPTR "\n", excPtr->GPR23); + printk("\t R24 = %08" PRIxPTR, excPtr->GPR24); + printk(" R25 = %08" PRIxPTR, excPtr->GPR25); + printk(" R26 = %08" PRIxPTR, excPtr->GPR26); + printk(" R27 = %08" PRIxPTR "\n", excPtr->GPR27); + printk("\t R28 = %08" PRIxPTR, excPtr->GPR28); + printk(" R29 = %08" PRIxPTR, excPtr->GPR29); + printk(" R30 = %08" PRIxPTR, excPtr->GPR30); + printk(" R31 = %08" PRIxPTR "\n", excPtr->GPR31); + printk("\t CR = %08" PRIx32 "\n", excPtr->EXC_CR); + printk("\t CTR = %08" PRIxPTR "\n", excPtr->EXC_CTR); + printk("\t XER = %08" PRIx32 "\n", excPtr->EXC_XER); + printk("\t LR = %08" PRIxPTR "\n", excPtr->EXC_LR); + + BSP_printStackTrace(excPtr); + } + + if (ASM_MACH_VECTOR == excPtr->_EXC_number) { + /* ollah , we got a machine check - this could either + * be a TEA, MCP or internal; let's see and provide more info + */ + if (!quiet) + printk("Machine check; reason:"); + if ( ! (excPtr->EXC_SRR1 & (SRR1_TEA_EXC | SRR1_MCP_EXC)) ) { + if (!quiet) + printk("SRR1\n"); + } else { + if (excPtr->EXC_SRR1 & (SRR1_TEA_EXC)) { + if (!quiet) + printk(" TEA"); + } + if (excPtr->EXC_SRR1 & (SRR1_MCP_EXC)) { + unsigned long gerr; + + if (!quiet) printk(" MCP\n"); + + /* it's MCP; gather info from the host bridge */ + gerr=_BSP_clear_hostbridge_errors(0,0); + if (gerr&0x80000000) printk("GT64260 Parity error\n"); + if (gerr&0x40000000) printk("GT64260 SysErr\n"); + if ((!quiet) && (!gerr)) printk("GT64260 host bridge seems OK\n"); + } + } + } else if (ASM_DEC_VECTOR == excPtr->_EXC_number) { + recoverable = 1; + } else if (ASM_SYS_VECTOR == excPtr->_EXC_number) { +#ifdef TEST_RAW_EXCEPTION_CODE + recoverable = 1; +#else + recoverable = 0; +#endif + } + + /* call them for a second time giving a chance to intercept + * the task_suspend + */ + if (ext && ext->lowlevelHook && ext->lowlevelHook(excPtr, ext, 1)) + return; + + if (!recoverable) { + if (id) { + /* if there's a highlevel hook, install it */ + if (ext && ext->highlevelHook) { + excPtr->EXC_SRR0 = (uint32_t)ext->highlevelHook; + excPtr->GPR3 = (uint32_t)ext; + return; + } + if (excPtr->EXC_SRR1 & MSR_FP) { + /* thread dispatching is _not_ disabled at this point; hence + * we must make sure we have the FPU enabled... + */ + _write_MSR( _read_MSR() | MSR_FP ); + __asm__ __volatile__("isync"); + } + printk("unrecoverable exception!!! task %08" PRIx32 " suspended\n",id); + rtems_task_suspend(id); + } else { + printk("PANIC, rebooting...\n"); + bsp_reset(); + } + } +} |