From dc1ea019f3c5be4f45f0232fcac954b65610933f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 22 Mar 2018 06:27:31 +0100 Subject: bsps/mpc55xx: Move libcpu content to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libcpu/powerpc/Makefile.am | 46 -- c/src/lib/libcpu/powerpc/configure.ac | 2 - c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c | 808 --------------------- c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c | 329 --------- c/src/lib/libcpu/powerpc/mpc55xx/emios/emios.c | 105 --- c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c | 20 - c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c | 165 ----- c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S | 81 --- .../libcpu/powerpc/mpc55xx/misc/flash_support.c | 698 ------------------ c/src/lib/libcpu/powerpc/mpc55xx/siu/siu.c | 42 -- 10 files changed, 2296 deletions(-) delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/emios/emios.c delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c delete mode 100644 c/src/lib/libcpu/powerpc/mpc55xx/siu/siu.c (limited to 'c/src/lib/libcpu/powerpc') diff --git a/c/src/lib/libcpu/powerpc/Makefile.am b/c/src/lib/libcpu/powerpc/Makefile.am index e83d47a772..b2f03b64fe 100644 --- a/c/src/lib/libcpu/powerpc/Makefile.am +++ b/c/src/lib/libcpu/powerpc/Makefile.am @@ -167,52 +167,6 @@ endif # END: MPC83XX # ############################################################################## -############################################################################## -# START: MPC55XX # -############################################################################## -if mpc55xx - -# IRQ -noinst_PROGRAMS += mpc55xx/irq.rel -mpc55xx_irq_rel_SOURCES = mpc55xx/irq/irq.c -mpc55xx_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -# FEC -noinst_PROGRAMS += mpc55xx/fec.rel -mpc55xx_fec_rel_SOURCES = mpc55xx/fec/fec.c -mpc55xx_fec_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -# eDMA -noinst_PROGRAMS += mpc55xx/edma.rel -mpc55xx_edma_rel_SOURCES = mpc55xx/edma/edma.c -mpc55xx_edma_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -# eMIOS -noinst_PROGRAMS += mpc55xx/emios.rel -mpc55xx_emios_rel_SOURCES = mpc55xx/emios/emios.c -mpc55xx_emios_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -# SIU -noinst_PROGRAMS += mpc55xx/siu.rel -mpc55xx_siu_rel_SOURCES = mpc55xx/siu/siu.c -mpc55xx_siu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -# DSPI -noinst_PROGRAMS += mpc55xx/dspi.rel -mpc55xx_dspi_rel_SOURCES = mpc55xx/dspi/dspi.c -mpc55xx_dspi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -# Misc -noinst_PROGRAMS += mpc55xx/misc.rel -mpc55xx_misc_rel_SOURCES = mpc55xx/misc/copy.S \ - mpc55xx/misc/flash_support.c -mpc55xx_misc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -endif -############################################################################## -# END: MPC55XX # -############################################################################## - ############################################################################## # START: QorIQ # ############################################################################## diff --git a/c/src/lib/libcpu/powerpc/configure.ac b/c/src/lib/libcpu/powerpc/configure.ac index 3d85e2b25f..8b91859bc5 100644 --- a/c/src/lib/libcpu/powerpc/configure.ac +++ b/c/src/lib/libcpu/powerpc/configure.ac @@ -27,7 +27,6 @@ AM_CONDITIONAL(shared, \ || test "$RTEMS_CPU_MODEL" = "mpc7400" \ || test "$RTEMS_CPU_MODEL" = "mpc7455" \ || test "$RTEMS_CPU_MODEL" = "mpc555" \ -|| test "$RTEMS_CPU_MODEL" = "mpc55xx" \ || test "$RTEMS_CPU_MODEL" = "ppc405" \ || test "$RTEMS_CPU_MODEL" = "ppc440" \ || test "$RTEMS_CPU_MODEL" = "mpc604" \ @@ -40,7 +39,6 @@ AM_CONDITIONAL(shared, \ || test "$RTEMS_CPU_MODEL" = "e500") # test on CPU type -AM_CONDITIONAL(mpc55xx, test "$RTEMS_CPU_MODEL" = "mpc55xx") AM_CONDITIONAL(mpc5xx, test "$RTEMS_CPU_MODEL" = "mpc555" ) AM_CONDITIONAL(mpc6xx, test "$RTEMS_CPU_MODEL" = "mpc6xx" \ || test "$RTEMS_CPU_MODEL" = "mpc604" \ diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c b/c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c deleted file mode 100644 index f6edb560b0..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/dspi/dspi.c +++ /dev/null @@ -1,808 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx_dspi - * - * @brief Source file for the LibI2C bus driver for the Deserial Serial Peripheral Interface (DSPI). - */ - -/* - * Copyright (c) 2008 - * Embedded Brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * rtems@embedded-brains.de - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -#include - -#include - -#define RTEMS_STATUS_CHECKS_USE_PRINTK - -#include - -#define MPC55XX_DSPI_FIFO_SIZE 4 - -#define MPC55XX_DSPI_CTAR_NUMBER 8 - -#define MPC55XX_DSPI_CTAR_DEFAULT 0 - -#define MPC55XX_DSPI_EDMA_MAGIC_SIZE 128 - -#define MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE 63 - -typedef struct { - uint32_t scaler : 26; - uint32_t pbr : 2; - uint32_t br : 4; -} mpc55xx_dspi_baudrate_scaler_entry; - -static const mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_baudrate_scaler_table [MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE] = { - { 4, 0, 0 }, - { 6, 1, 0 }, - { 8, 0, 1 }, - { 10, 2, 0 }, - { 12, 1, 1 }, - { 14, 3, 0 }, - { 16, 0, 3 }, - { 18, 1, 2 }, - { 20, 2, 1 }, - { 24, 1, 3 }, - { 28, 3, 1 }, - { 30, 2, 2 }, - { 32, 0, 4 }, - { 40, 2, 3 }, - { 42, 3, 2 }, - { 48, 1, 4 }, - { 56, 3, 3 }, - { 64, 0, 5 }, - { 80, 2, 4 }, - { 96, 1, 5 }, - { 112, 3, 4 }, - { 128, 0, 6 }, - { 160, 2, 5 }, - { 192, 1, 6 }, - { 224, 3, 5 }, - { 256, 0, 7 }, - { 320, 2, 6 }, - { 384, 1, 7 }, - { 448, 3, 6 }, - { 512, 0, 8 }, - { 640, 2, 7 }, - { 768, 1, 8 }, - { 896, 3, 7 }, - { 1024, 0, 9 }, - { 1280, 2, 8 }, - { 1536, 1, 9 }, - { 1792, 3, 8 }, - { 2048, 0, 10 }, - { 2560, 2, 9 }, - { 3072, 1, 10 }, - { 3584, 3, 9 }, - { 4096, 0, 11 }, - { 5120, 2, 10 }, - { 6144, 1, 11 }, - { 7168, 3, 10 }, - { 8192, 0, 12 }, - { 10240, 2, 11 }, - { 12288, 1, 12 }, - { 14336, 3, 11 }, - { 16384, 0, 13 }, - { 20480, 2, 12 }, - { 24576, 1, 13 }, - { 28672, 3, 12 }, - { 32768, 0, 14 }, - { 40960, 2, 13 }, - { 49152, 1, 14 }, - { 57344, 3, 13 }, - { 65536, 0, 15 }, - { 81920, 2, 14 }, - { 98304, 1, 15 }, - { 114688, 3, 14 }, - { 163840, 2, 15 }, - { 229376, 3, 15 }, -}; - -static void mpc55xx_dspi_edma_done( edma_channel_context *ctx, uint32_t error_status) -{ - const mpc55xx_dspi_edma_entry *e = (const mpc55xx_dspi_edma_entry *) ctx; - rtems_semaphore_release( e->id); - - if (error_status != 0) { - RTEMS_SYSLOG_ERROR( "eDMA error: 0x%08x\n", error_status); - } -} - -static mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_search_baudrate_scaler( uint32_t scaler, int min, int mid, int max) -{ - if (scaler <= mpc55xx_dspi_baudrate_scaler_table [mid].scaler) { - max = mid; - } else { - min = mid; - } - mid = (min + max) / 2; - if (mid == min) { - return mpc55xx_dspi_baudrate_scaler_table [max]; - } else { - return mpc55xx_dspi_search_baudrate_scaler( scaler, min, mid, max); - } -} - -static uint32_t mpc55xx_dspi_push_data [8 * MPC55XX_DSPI_NUMBER] __attribute__ ((aligned (32))); - -static inline void mpc55xx_dspi_store_push_data( mpc55xx_dspi_bus_entry *e) -{ - mpc55xx_dspi_push_data [e->table_index * 8] = e->push_data.R; - rtems_cache_flush_multiple_data_lines( &mpc55xx_dspi_push_data [e->table_index * 8], 4); -} - -static inline uint32_t mpc55xx_dspi_push_data_address( mpc55xx_dspi_bus_entry *e) -{ - return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8]; -} - -static inline uint32_t mpc55xx_dspi_nirvana_address( mpc55xx_dspi_bus_entry *e) -{ - return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8 + 1]; -} - -static rtems_status_code mpc55xx_dspi_init( rtems_libi2c_bus_t *bus) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; - union DSPI_MCR_tag mcr = MPC55XX_ZERO_FLAGS; - union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS; - union DSPI_RSER_tag rser = MPC55XX_ZERO_FLAGS; - struct tcd_t tcd_push = EDMA_TCD_DEFAULT; - int i = 0; - - /* eDMA receive */ - sc = rtems_semaphore_create ( - rtems_build_name ( 'S', 'P', 'I', 'R'), - 0, - RTEMS_SIMPLE_BINARY_SEMAPHORE, - 0, - &e->edma_receive.id - ); - RTEMS_CHECK_SC( sc, "create receive update semaphore"); - - sc = mpc55xx_edma_obtain_channel( &e->edma_receive.edma, MPC55XX_INTC_DEFAULT_PRIORITY); - RTEMS_CHECK_SC( sc, "obtain receive eDMA channel"); - - /* eDMA transmit */ - sc = rtems_semaphore_create ( - rtems_build_name ( 'S', 'P', 'I', 'T'), - 0, - RTEMS_SIMPLE_BINARY_SEMAPHORE, - 0, - &e->edma_transmit.id - ); - RTEMS_CHECK_SC( sc, "create transmit update semaphore"); - - sc = mpc55xx_edma_obtain_channel( &e->edma_transmit.edma, MPC55XX_INTC_DEFAULT_PRIORITY); - RTEMS_CHECK_SC( sc, "obtain transmit eDMA channel"); - - sc = mpc55xx_edma_obtain_channel( &e->edma_push.edma, MPC55XX_INTC_DEFAULT_PRIORITY); - RTEMS_CHECK_SC( sc, "obtain push eDMA channel"); - - tcd_push.SADDR = mpc55xx_dspi_push_data_address( e); - tcd_push.SDF.B.SSIZE = 2; - tcd_push.SDF.B.SOFF = 0; - tcd_push.DADDR = (uint32_t) &e->regs->PUSHR.R; - tcd_push.SDF.B.DSIZE = 2; - tcd_push.CDF.B.DOFF = 0; - tcd_push.NBYTES = 4; - tcd_push.CDF.B.CITER = 1; - tcd_push.BMF.B.BITER = 1; - - *e->edma_push.edma.edma_tcd = tcd_push; - - /* Module Control Register */ - mcr.B.MSTR = e->master ? 1 : 0; - mcr.B.CONT_SCKE = 0; - mcr.B.DCONF = 0; - mcr.B.FRZ = 0; - mcr.B.MTFE = 0; - mcr.B.PCSSE = 0; - mcr.B.ROOE = 0; - mcr.B.PCSIS0 = 1; - mcr.B.PCSIS1 = 1; - mcr.B.PCSIS2 = 1; - mcr.B.PCSIS3 = 1; - mcr.B.PCSIS5 = 1; - mcr.B.MDIS = 0; - mcr.B.DIS_TXF = 0; - mcr.B.DIS_RXF = 0; - mcr.B.CLR_TXF = 0; - mcr.B.CLR_RXF = 0; - mcr.B.SMPL_PT = 0; - mcr.B.HALT = 0; - - e->regs->MCR.R = mcr.R; - - /* Clock and Transfer Attributes Register */ - ctar.B.DBR = 0; - ctar.B.FMSZ = 0x7; - ctar.B.CPOL = 0; - ctar.B.CPHA = 0; - ctar.B.LSBFE = 0; - ctar.B.PCSSCK = 0; - ctar.B.PASC = 0; - ctar.B.PDT = 0; - ctar.B.PBR = 0; - ctar.B.CSSCK = 0; - ctar.B.ASC = 0; - ctar.B.DT = 0; - ctar.B.BR = 0; - - for (i = 0; i < MPC55XX_DSPI_CTAR_NUMBER; ++i) { - e->regs->CTAR [i].R = ctar.R; - } - - /* DMA/Interrupt Request Select and Enable Register */ - rser.B.TFFFRE = 1; - rser.B.TFFFDIRS = 1; - rser.B.RFDFRE = 1; - rser.B.RFDFDIRS = 1; - - e->regs->RSER.R = rser.R; - - return RTEMS_SUCCESSFUL; -} - -static rtems_status_code mpc55xx_dspi_send_start( rtems_libi2c_bus_t *bus) -{ - mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; - - /* Reset chip selects */ - e->push_data.B.PCS0 = 0; - e->push_data.B.PCS1 = 0; - e->push_data.B.PCS2 = 0; - e->push_data.B.PCS3 = 0; - e->push_data.B.PCS4 = 0; - e->push_data.B.PCS5 = 0; - mpc55xx_dspi_store_push_data( e); - - return RTEMS_SUCCESSFUL; -} - -static rtems_status_code mpc55xx_dspi_send_stop( rtems_libi2c_bus_t *bus) -{ - return RTEMS_SUCCESSFUL; -} - -static rtems_status_code mpc55xx_dspi_send_addr( rtems_libi2c_bus_t *bus, uint32_t addr, int rw) -{ - mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; - union DSPI_SR_tag sr = MPC55XX_ZERO_FLAGS; - - /* Flush transmit and receive FIFO */ - e->regs->MCR.B.CLR_TXF = 1; - e->regs->MCR.B.CLR_RXF = 1; - - /* Clear status flags */ - sr.B.EOQF = 1; - sr.B.TFFF = 1; - sr.B.RFDF = 1; - e->regs->SR.R = sr.R; - - /* Frame command */ - e->push_data.R = 0; - e->push_data.B.CONT = 0; - e->push_data.B.CTAS = MPC55XX_DSPI_CTAR_DEFAULT; - e->push_data.B.EOQ = 0; - e->push_data.B.CTCNT = 0; - switch (addr) { - case 0: - e->push_data.B.PCS0 = 1; - break; - case 1: - e->push_data.B.PCS1 = 1; - break; - case 2: - e->push_data.B.PCS2 = 1; - break; - case 3: - e->push_data.B.PCS3 = 1; - break; - case 4: - e->push_data.B.PCS4 = 1; - break; - case 5: - e->push_data.B.PCS5 = 1; - break; - default: - return -RTEMS_INVALID_ADDRESS; - } - mpc55xx_dspi_store_push_data( e); - - return RTEMS_SUCCESSFUL; -} - -/* FIXME, TODO */ -extern uint32_t bsp_clock_speed; - -static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_libi2c_tfr_mode_t *mode) -{ - mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; - union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS; - - if (mode->bits_per_char != 8) { - return -RTEMS_INVALID_NUMBER; - } - - e->idle_char = mode->idle_char; - - ctar.R = e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R; - - ctar.B.PCSSCK = 0; - ctar.B.CSSCK = 0; - ctar.B.PASC = 0; - ctar.B.ASC = 0; - - ctar.B.LSBFE = mode->lsb_first ? 1 : 0; - ctar.B.CPOL = mode->clock_inv ? 1 : 0; - ctar.B.CPHA = mode->clock_phs ? 1 : 0; - - if (mode->baudrate != e->baud) { - uint32_t scaler = bsp_clock_speed / mode->baudrate; - mpc55xx_dspi_baudrate_scaler_entry bse = mpc55xx_dspi_search_baudrate_scaler( scaler, 0, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE / 2, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE); - - ctar.B.PBR = bse.pbr; - ctar.B.BR = bse.br; - - e->baud = mode->baudrate; - } - - e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R = ctar.R; - - return 0; -} - -/** - * @brief Writes @a n characters from @a out to bus @a bus and synchronously stores the received data in @a in. - * - * eDMA channel usage for transmission: - * @dot - * digraph push { - * push [label="Push Register"]; - * push_data [label="Push Data"]; - * idle_push_data [label="Idle Push Data"]; - * out [shape=box,label="Output Buffer"]; - * edge [color=red,fontcolor=red]; - * push -> idle_push_data [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_transmit"]; - * push -> out [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_transmit"]; - * out -> push_data [label="Channel Link",URL="\ref mpc55xx_dspi_bus_entry::edma_push"]; - * edge [color=blue,fontcolor=blue]; - * out -> push_data [label="Data"]; - * push_data -> push [label="Data"]; - * idle_push_data -> push [label="Data"]; - * } - * @enddot - * - * eDMA channel usage for receiving: - * @dot - * digraph pop { - * pop [label="Pop Register"]; - * nirvana [label="Nirvana"]; - * in [shape=box,label="Input Buffer"]; - * edge [color=red,fontcolor=red]; - * pop -> nirvana [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_receive"]; - * pop -> in [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_receive"]; - * edge [color=blue,fontcolor=blue]; - * pop -> nirvana [label="Data"]; - * pop -> in [label="Data"]; - * } - * @enddot - */ -static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in, const unsigned char *out, int n) -{ - mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; - - /* Non cache aligned characters */ - int n_nc = n; - - /* Cache aligned characters */ - int n_c = 0; - - /* Register addresses */ - volatile void *push = &e->regs->PUSHR.R; - volatile void *pop = &e->regs->POPR.R; - volatile union DSPI_SR_tag *status = &e->regs->SR; - - /* Push and pop data */ - union DSPI_PUSHR_tag push_data = e->push_data; - union DSPI_POPR_tag pop_data; - - /* Status register */ - union DSPI_SR_tag sr; - - /* Read and write indices */ - int r = 0; - int w = 0; - - if (n == 0) { - return 0; - } else if (in == NULL && out == NULL) { - return -RTEMS_INVALID_ADDRESS; - } - - if (n > MPC55XX_DSPI_EDMA_MAGIC_SIZE) { - n_nc = (int) mpc55xx_non_cache_aligned_size( in); - n_c = (int) mpc55xx_cache_aligned_size( in, (size_t) n); - if (n_c > EDMA_TCD_BITER_LINKED_SIZE) { - RTEMS_SYSLOG_WARNING( "buffer size out of range, cannot use eDMA\n"); - n_nc = n; - n_c = 0; - } else if (n_nc + n_c != n) { - RTEMS_SYSLOG_WARNING( "input buffer not proper cache aligned, cannot use eDMA\n"); - n_nc = n; - n_c = 0; - } - } - -#ifdef DEBUG - if (e->regs->SR.B.TXCTR != e->regs->SR.B.RXCTR) { - RTEMS_SYSLOG_WARNING( "FIFO counter not equal\n"); - } -#endif /* DEBUG */ - - /* Direct IO */ - if (out == NULL) { - push_data.B.TXDATA = e->idle_char; - while (r < n_nc || w < n_nc) { - /* Wait for available FIFO */ - do { - sr.R = status->R; - } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0); - - /* Write */ - if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) { - ++w; - ppc_write_word( push_data.R, push); - } - - /* Read */ - if (r < n_nc && sr.B.RXCTR != 0) { - pop_data.R = ppc_read_word( pop); - in [r] = (unsigned char) pop_data.B.RXDATA; - ++r; - } - } - } else if (in == NULL) { - while (r < n_nc || w < n_nc) { - /* Wait for available FIFO */ - do { - sr.R = status->R; - } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0); - - /* Write */ - if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) { - push_data.B.TXDATA = out [w]; - ++w; - ppc_write_word( push_data.R, push); - } - - /* Read */ - if (r < n_nc && sr.B.RXCTR != 0) { - pop_data.R = ppc_read_word( pop); - ++r; - } - } - } else { - while (r < n_nc || w < n_nc) { - /* Wait for available FIFO */ - do { - sr.R = status->R; - } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0); - - /* Write */ - if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) { - push_data.B.TXDATA = out [w]; - ++w; - ppc_write_word( push_data.R, push); - } - - /* Read */ - if (r < n_nc && sr.B.RXCTR != 0) { - pop_data.R = ppc_read_word( pop); - in [r] = (unsigned char) pop_data.B.RXDATA; - ++r; - } - } - } - - /* eDMA transfers */ - if (n_c > 0) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned char *in_c = in + n_nc; - const unsigned char *out_c = out + n_nc; - struct tcd_t tcd_transmit = EDMA_TCD_DEFAULT; - struct tcd_t tcd_receive = EDMA_TCD_DEFAULT; - - /* Cache operations */ - rtems_cache_flush_multiple_data_lines( out_c, (size_t) n_c); - rtems_cache_invalidate_multiple_data_lines( in_c, (size_t) n_c); - - /* Set transmit TCD */ - if (out == NULL) { - e->push_data.B.TXDATA = e->idle_char; - mpc55xx_dspi_store_push_data( e); - tcd_transmit.SADDR = mpc55xx_dspi_push_data_address( e); - tcd_transmit.SDF.B.SSIZE = 2; - tcd_transmit.SDF.B.SOFF = 0; - tcd_transmit.DADDR = (uint32_t) push; - tcd_transmit.SDF.B.DSIZE = 2; - tcd_transmit.CDF.B.DOFF = 0; - tcd_transmit.NBYTES = 4; - tcd_transmit.CDF.B.CITER = n_c; - tcd_transmit.BMF.B.BITER = n_c; - } else { - unsigned push_channel = mpc55xx_edma_channel_by_tcd( e->edma_push.edma.edma_tcd); - mpc55xx_edma_clear_done( e->edma_transmit.edma.edma_tcd); - tcd_transmit.SADDR = (uint32_t) out_c; - tcd_transmit.SDF.B.SSIZE = 0; - tcd_transmit.SDF.B.SOFF = 1; - tcd_transmit.DADDR = mpc55xx_dspi_push_data_address( e) + 3; - tcd_transmit.SDF.B.DSIZE = 0; - tcd_transmit.CDF.B.DOFF = 0; - tcd_transmit.NBYTES = 1; - tcd_transmit.CDF.B.CITERE_LINK = 1; - tcd_transmit.BMF.B.BITERE_LINK = 1; - tcd_transmit.BMF.B.MAJORLINKCH = push_channel; - tcd_transmit.CDF.B.CITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c); - tcd_transmit.BMF.B.BITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c); - tcd_transmit.BMF.B.MAJORE_LINK = 1; - } - tcd_transmit.BMF.B.D_REQ = 1; - tcd_transmit.BMF.B.INT_MAJ = 1; - *e->edma_transmit.edma.edma_tcd = tcd_transmit; - - /* Set receive TCD */ - if (in == NULL) { - tcd_receive.CDF.B.DOFF = 0; - tcd_receive.DADDR = mpc55xx_dspi_nirvana_address( e); - } else { - tcd_receive.CDF.B.DOFF = 1; - tcd_receive.DADDR = (uint32_t) in_c; - } - tcd_receive.SADDR = (uint32_t) pop + 3; - tcd_receive.SDF.B.SSIZE = 0; - tcd_receive.SDF.B.SOFF = 0; - tcd_receive.SDF.B.DSIZE = 0; - tcd_receive.NBYTES = 1; - tcd_receive.BMF.B.D_REQ = 1; - tcd_receive.BMF.B.INT_MAJ = 1; - tcd_receive.CDF.B.CITER = n_c; - tcd_receive.BMF.B.BITER = n_c; - *e->edma_receive.edma.edma_tcd = tcd_receive; - - /* Clear request flags */ - sr.R = 0; - sr.B.TFFF = 1; - sr.B.RFDF = 1; - status->R = sr.R; - - /* Enable hardware requests */ - mpc55xx_edma_enable_hardware_requests( e->edma_receive.edma.edma_tcd); - mpc55xx_edma_enable_hardware_requests( e->edma_transmit.edma.edma_tcd); - - /* Wait for transmit update */ - sc = rtems_semaphore_obtain( e->edma_transmit.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - RTEMS_CHECK_SC_RV( sc, "transmit update"); - - /* Wait for receive update */ - sc = rtems_semaphore_obtain( e->edma_receive.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - RTEMS_CHECK_SC_RV( sc, "receive update"); - } - - return n; -} - -/** - * @brief Reads @a n characters from bus @a bus and stores it in @a in. - * - * Writes idle characters to receive data. - * - * @see mpc55xx_dspi_read_write(). - */ -static int mpc55xx_dspi_read( rtems_libi2c_bus_t *bus, unsigned char *in, int n) -{ - return mpc55xx_dspi_read_write( bus, in, NULL, n); -} - -/** - * @brief Writes @a n characters from @a out to bus @a bus. - * - * Discards the synchronously received data. - * - * @see mpc55xx_dspi_read_write(). - */ -static int mpc55xx_dspi_write( rtems_libi2c_bus_t *bus, unsigned char *out, int n) -{ - return mpc55xx_dspi_read_write( bus, NULL, out, n); -} - -static int mpc55xx_dspi_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg) -{ - int rv = -1; - switch (cmd) { - case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: - rv = mpc55xx_dspi_set_transfer_mode( bus, (const rtems_libi2c_tfr_mode_t *) arg); - break; - case RTEMS_LIBI2C_IOCTL_READ_WRITE: - rv = mpc55xx_dspi_read_write( - bus, - ((rtems_libi2c_read_write_t *) arg)->rd_buf, - ((rtems_libi2c_read_write_t *) arg)->wr_buf, - ((rtems_libi2c_read_write_t *) arg)->byte_cnt - ); - break; - default: - rv = -RTEMS_NOT_DEFINED; - break; - } - return rv; -} - -static const rtems_libi2c_bus_ops_t mpc55xx_dspi_ops = { - .init = mpc55xx_dspi_init, - .send_start = mpc55xx_dspi_send_start, - .send_stop = mpc55xx_dspi_send_stop, - .send_addr = mpc55xx_dspi_send_addr, - .read_bytes = mpc55xx_dspi_read, - .write_bytes = mpc55xx_dspi_write, - .ioctl = mpc55xx_dspi_ioctl -}; - -mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { - { - /* DSPI A */ - .bus = { - .ops = &mpc55xx_dspi_ops, - .size = sizeof( mpc55xx_dspi_bus_entry) - }, - .table_index = 0, - .bus_number = 0, - .regs = &DSPI_A, - .master = true, - .push_data = MPC55XX_ZERO_FLAGS, - .edma_transmit = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_TFFF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_push = { - .edma = { - .edma_tcd = &EDMA.TCD [43], - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_receive = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_RFDF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .idle_char = 0xffffffff, - .baud = 0 - }, { - /* DSPI B */ - .bus = { - .ops = &mpc55xx_dspi_ops, - .size = sizeof( mpc55xx_dspi_bus_entry) - }, - .table_index = 1, - .bus_number = 0, - .regs = &DSPI_B, - .master = true, - .push_data = MPC55XX_ZERO_FLAGS, - .edma_transmit = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_TFFF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_push = { - .edma = { - .edma_tcd = &EDMA.TCD [10], - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_receive = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_RFDF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .idle_char = 0xffffffff, - .baud = 0 - }, { - /* DSPI C */ - .bus = { - .ops = &mpc55xx_dspi_ops, - .size = sizeof( mpc55xx_dspi_bus_entry) - }, - .table_index = 2, - .bus_number = 0, - .regs = &DSPI_C, - .master = true, - .push_data = MPC55XX_ZERO_FLAGS, - .edma_transmit = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_TFFF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_push = { - .edma = { - .edma_tcd = &EDMA.TCD [11], - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_receive = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_RFDF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .idle_char = 0xffffffff, - .baud = 0 -#ifdef DSPI_D - }, { - /* DSPI D */ - .bus = { - .ops = &mpc55xx_dspi_ops, - .size = sizeof( mpc55xx_dspi_bus_entry) - }, - .table_index = 3, - .bus_number = 0, - .regs = &DSPI_D, - .master = true, - .push_data = MPC55XX_ZERO_FLAGS, - .edma_transmit = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_TFFF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_push = { - .edma = { - .edma_tcd = &EDMA.TCD [18], - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .edma_receive = { - .edma = { - .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_RFDF), - .done = mpc55xx_dspi_edma_done - }, - .id = RTEMS_ID_NONE - }, - .idle_char = 0xffffffff, - .baud = 0 -#endif - } -}; diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c b/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c deleted file mode 100644 index c5d47705ec..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c +++ /dev/null @@ -1,329 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx - * - * @brief Enhanced Direct Memory Access (eDMA). - */ - -/* - * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - -#include - -#include -#include -#include - -#define EDMA_CHANNELS_PER_GROUP 32U - -#define EDMA_GROUP_COUNT ((EDMA_CHANNEL_COUNT + 31U) / 32U) - -#define EDMA_GROUP_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_GROUP) - -#define EDMA_GROUP_BIT(channel) (1U << ((channel) % EDMA_CHANNELS_PER_GROUP)) - -#define EDMA_MODULE_INDEX(channel) ((channel) / EDMA_CHANNELS_PER_MODULE) - -static uint32_t edma_channel_occupation [EDMA_GROUP_COUNT]; - -static RTEMS_CHAIN_DEFINE_EMPTY(edma_channel_chain); - -static unsigned edma_channel_index_of_tcd(volatile struct tcd_t *edma_tcd) -{ - volatile struct EDMA_tag *edma = mpc55xx_edma_by_tcd(edma_tcd); - unsigned channel = edma_tcd - &edma->TCD[0]; - -#if EDMA_MODULE_COUNT == 1 - return channel; -#elif EDMA_MODULE_COUNT == 2 - return channel + (&EDMA_A == edma ? 0 : EDMA_CHANNELS_PER_MODULE); -#else - #error "unsupported module count" -#endif -} - -static volatile struct EDMA_tag *edma_get_regs_by_module(unsigned module) -{ -#if EDMA_MODULE_COUNT == 1 - return &EDMA; -#elif EDMA_MODULE_COUNT == 2 - return module == 0 ? &EDMA_A : &EDMA_B; -#else - #error "unsupported module count" -#endif -} - -static uint32_t edma_bit_array_set(unsigned channel, uint32_t *bit_array) -{ - unsigned array = channel / 32; - uint32_t bit = 1U << (channel % 32); - uint32_t previous = bit_array [array]; - - bit_array [array] = previous | bit; - - return previous; -} - -static uint32_t edma_bit_array_clear(unsigned channel, uint32_t *bit_array) -{ - unsigned array = channel / 32; - uint32_t bit = 1U << (channel % 32); - uint32_t previous = bit_array [array]; - - bit_array [array] = previous & ~bit; - - return previous; -} - -static void edma_interrupt_handler(void *arg) -{ - edma_channel_context *ctx = arg; - - mpc55xx_edma_clear_interrupts(ctx->edma_tcd); - - (*ctx->done)(ctx, 0); -} - -static void edma_interrupt_error_handler(void *arg) -{ - rtems_chain_control *chain = &edma_channel_chain; - rtems_chain_node *node = rtems_chain_first(chain); - uint32_t error_channels [] = { -#if EDMA_GROUP_COUNT >= 1 - EDMA.ERL.R -#endif -#if EDMA_GROUP_COUNT >= 2 - , EDMA.ERH.R -#endif -#if EDMA_GROUP_COUNT >= 3 - , EDMA_B.ERL.R -#endif - }; - uint32_t error_status [] = { -#if EDMA_GROUP_COUNT >= 1 - EDMA.ESR.R -#endif -#if EDMA_GROUP_COUNT >= 3 - , EDMA_B.ESR.R -#endif - }; - -#if EDMA_GROUP_COUNT >= 1 - EDMA.ERL.R = error_channels [0]; -#endif -#if EDMA_GROUP_COUNT >= 2 - EDMA.ERH.R = error_channels [1]; -#endif -#if EDMA_GROUP_COUNT >= 3 - EDMA_B.ERL.R = error_channels [2]; -#endif - - while (!rtems_chain_is_tail(chain, node)) { - edma_channel_context *ctx = (edma_channel_context *) node; - unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); - unsigned group_index = EDMA_GROUP_INDEX(channel_index); - unsigned group_bit = EDMA_GROUP_BIT(channel_index); - - if ((error_channels [group_index] & group_bit) != 0) { - unsigned module_index = EDMA_MODULE_INDEX(channel_index); - - (*ctx->done)(ctx, error_status [module_index]); - } - - node = rtems_chain_next(node); - } -} - -void mpc55xx_edma_init(void) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned channel_remaining = EDMA_CHANNEL_COUNT; - unsigned module = 0; - unsigned group = 0; - - for (module = 0; module < EDMA_MODULE_COUNT; ++module) { - volatile struct EDMA_tag *edma = edma_get_regs_by_module(module); - unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ? - channel_remaining : EDMA_CHANNELS_PER_MODULE; - unsigned channel = 0; - - channel_remaining -= channel_count; - - /* Disable requests */ - edma->CERQR.B.CERQ = 0x40; - - /* Arbitration mode: group round robin, channel fixed */ - edma->CR.B.ERGA = 1; - edma->CR.B.ERCA = 0; - for (channel = 0; channel < channel_count; ++channel) { - volatile struct tcd_t *tcd = &edma->TCD [channel]; - edma->CPR [channel].R = 0x80U | (channel & 0xfU); - - /* Initialize TCD, stop channel first */ - tcd->BMF.R = 0; - tcd->SADDR = 0; - tcd->SDF.R = 0; - tcd->NBYTES = 0; - tcd->SLAST = 0; - tcd->DADDR = 0; - tcd->CDF.R = 0; - tcd->DLAST_SGA = 0; - } - - /* Clear interrupt requests */ - edma->CIRQR.B.CINT = 0x40; - edma->CER.B.CERR = 0x40; - } - - for (group = 0; group < EDMA_GROUP_COUNT; ++group) { - sc = mpc55xx_interrupt_handler_install( - MPC55XX_IRQ_EDMA_ERROR(group), - "eDMA Error", - RTEMS_INTERRUPT_UNIQUE, - MPC55XX_INTC_DEFAULT_PRIORITY, - edma_interrupt_error_handler, - NULL - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_INSTALL); - } - } -} - -rtems_status_code mpc55xx_edma_obtain_channel_by_tcd( - volatile struct tcd_t *edma_tcd -) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned channel_index = edma_channel_index_of_tcd(edma_tcd); - rtems_interrupt_level level; - uint32_t channel_occupation; - - rtems_interrupt_disable(level); - channel_occupation = edma_bit_array_set( - channel_index, - &edma_channel_occupation [0] - ); - rtems_interrupt_enable(level); - - if ((channel_occupation & EDMA_GROUP_BIT(channel_index)) != 0) { - sc = RTEMS_RESOURCE_IN_USE; - } - - return sc; -} - -void mpc55xx_edma_release_channel_by_tcd(volatile struct tcd_t *edma_tcd) -{ - unsigned channel_index = edma_channel_index_of_tcd(edma_tcd); - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - edma_bit_array_clear(channel_index, &edma_channel_occupation [0]); - rtems_interrupt_enable(level); - - mpc55xx_edma_disable_hardware_requests(edma_tcd); - mpc55xx_edma_disable_error_interrupts(edma_tcd); -} - -rtems_status_code mpc55xx_edma_obtain_channel( - edma_channel_context *ctx, - unsigned irq_priority -) -{ - rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd); - if (sc == RTEMS_SUCCESSFUL) { - unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); - - sc = mpc55xx_interrupt_handler_install( - MPC55XX_IRQ_EDMA(channel_index), - "eDMA Channel", - RTEMS_INTERRUPT_SHARED, - irq_priority, - edma_interrupt_handler, - ctx - ); - if (sc == RTEMS_SUCCESSFUL) { - rtems_chain_prepend(&edma_channel_chain, &ctx->node); - mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd); - } else { - mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd); - sc = RTEMS_IO_ERROR; - } - } - - return sc; -} - -void mpc55xx_edma_release_channel(edma_channel_context *ctx) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); - - mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd); - rtems_chain_extract(&ctx->node); - - sc = rtems_interrupt_handler_remove( - MPC55XX_IRQ_EDMA(channel_index), - edma_interrupt_handler, - ctx - ); - if (sc != RTEMS_SUCCESSFUL) { - bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_REMOVE); - } -} - -void mpc55xx_edma_copy( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd -) -{ - /* Clear DONE flag */ - edma_tcd->BMF.R = 0; - - edma_tcd->SADDR = source_tcd->SADDR; - edma_tcd->SDF.R = source_tcd->SDF.R; - edma_tcd->NBYTES = source_tcd->NBYTES; - edma_tcd->SLAST = source_tcd->SLAST; - edma_tcd->DADDR = source_tcd->DADDR; - edma_tcd->CDF.R = source_tcd->CDF.R; - edma_tcd->DLAST_SGA = source_tcd->DLAST_SGA; - edma_tcd->BMF.R = source_tcd->BMF.R; -} - -void mpc55xx_edma_copy_and_enable_hardware_requests( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd -) -{ - mpc55xx_edma_copy(edma_tcd, source_tcd); - mpc55xx_edma_enable_hardware_requests(edma_tcd); -} - -void mpc55xx_edma_sg_link( - volatile struct tcd_t *edma_tcd, - const struct tcd_t *source_tcd -) -{ - edma_tcd->DLAST_SGA = (int32_t) source_tcd; - edma_tcd->BMF.B.E_SG = 1; - - if (!edma_tcd->BMF.B.E_SG) { - mpc55xx_edma_copy(edma_tcd, source_tcd); - } -} diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/emios/emios.c b/c/src/lib/libcpu/powerpc/mpc55xx/emios/emios.c deleted file mode 100644 index 89873b4c67..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/emios/emios.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx - * - * @brief Enhanced Modular Input Output Subsystem (eMIOS). - */ - -/* - * Copyright (c) 2009-2011 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#ifdef MPC55XX_HAS_EMIOS - -/** - * @brief Initialize the eMIOS module. - * - * The module is enabled. It is configured to use the internal clock. The - * global prescaler value is set to @a prescaler. If the value is greater than - * the maximum the maxium value will be used instead. A prescaler value of - * zero disables the clock. - * - * @note No protection against concurrent execution. - */ -void mpc55xx_emios_initialize( unsigned prescaler) -{ - union EMIOS_MCR_tag mcr = MPC55XX_ZERO_FLAGS; - - /* Enable module */ - mcr.B.MDIS = 0; - - /* Disable debug mode */ - mcr.B.FRZ = 1; - - /* Enable global time base */ - mcr.B.GTBE = 1; - - /* Disable global prescaler (= disable clock) */ - mcr.B.GPREN = 0; - - /* Set MCR */ - EMIOS.MCR.R = mcr.R; - - /* Set OUDR */ - EMIOS.OUDR.R = 0; - - /* Set global prescaler value */ - mpc55xx_emios_set_global_prescaler( prescaler); -} - -/** - * @brief Returns the global prescaler value of the eMIOS module. - */ -unsigned mpc55xx_emios_global_prescaler( void) -{ - union EMIOS_MCR_tag mcr = EMIOS.MCR; - - if (mcr.B.GPREN != 0) { - return mcr.B.GPRE + 1; - } else { - return 0; - } -} - -/** - * @brief Sets the global prescaler value of the eMIOS module. - * - * The global prescaler value is set to @a prescaler. If the value is greater - * than the maximum the maxium value will be used instead. A prescaler value - * of zero disables the clock. - * - * @note No protection against concurrent execution. - */ -void mpc55xx_emios_set_global_prescaler( unsigned prescaler) -{ - union EMIOS_MCR_tag mcr = EMIOS.MCR; - - /* Enable or disable the global prescaler */ - mcr.B.GPREN = prescaler > 0 ? 1 : 0; - - /* Set global prescaler value */ - if (prescaler > 256) { - prescaler = 256; - } else if (prescaler < 1) { - prescaler = 1; - } - mcr.B.GPRE = prescaler - 1; - - /* Set MCR */ - EMIOS.MCR.R = mcr.R; -} - -#endif /* MPC55XX_HAS_EMIOS */ diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c b/c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c deleted file mode 100644 index 11016b4aea..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/fec/fec.c +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx - * - * @brief Empty file. - */ - -/* - * Copyright (c) 2008 - * Embedded Brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * rtems@embedded-brains.de - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c b/c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c deleted file mode 100644 index 53c30f171e..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/irq/irq.c +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx - * - * @brief Source file for MPC55XX interrupt support. - */ - -/* - * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include - -#include -#include -#include - -#define RTEMS_STATUS_CHECKS_USE_PRINTK - -#include - -/** - * @brief Returns the priority @a priority of IRQ @a vector from the INTC. - */ -rtems_status_code mpc55xx_intc_get_priority( rtems_vector_number vector, unsigned *priority) -{ - if (MPC55XX_IRQ_IS_VALID( vector)) { - *priority = INTC.PSR [vector].B.PRI; - return RTEMS_SUCCESSFUL; - } else { - *priority = MPC55XX_INTC_INVALID_PRIORITY; - return RTEMS_INVALID_NUMBER; - } -} - -/** - * @brief Sets the priority of IRQ @a vector to @a priority at the INTC. - */ -rtems_status_code mpc55xx_intc_set_priority( rtems_vector_number vector, unsigned priority) -{ - if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) { - INTC.PSR [vector].B.PRI = priority; - if (INTC.PSR [vector].B.PRI == priority) { - return RTEMS_SUCCESSFUL; - } else { - return RTEMS_IO_ERROR; - } - } else { - return RTEMS_INVALID_NUMBER; - } -} - -/** - * @brief Raises the software IRQ with number @a vector. - */ -rtems_status_code mpc55xx_intc_raise_software_irq( rtems_vector_number vector) -{ - if (MPC55XX_IRQ_IS_SOFTWARE( vector)) { - INTC.SSCIR [vector].B.SET = 1; - return RTEMS_SUCCESSFUL; - } else { - return RTEMS_INVALID_NUMBER; - } -} - -/** - * @brief Clears the software IRQ with number @a vector. - */ -rtems_status_code mpc55xx_intc_clear_software_irq( rtems_vector_number vector) -{ - if (MPC55XX_IRQ_IS_SOFTWARE( vector)) { - INTC.SSCIR [vector].B.CLR = 1; - return RTEMS_SUCCESSFUL; - } else { - return RTEMS_INVALID_NUMBER; - } -} - -/** - * @brief Installs interrupt handler and sets priority. - */ -rtems_status_code mpc55xx_interrupt_handler_install( - rtems_vector_number vector, - const char *info, - rtems_option options, - unsigned priority, - rtems_interrupt_handler handler, - void *arg -) -{ - if (MPC55XX_IRQ_IS_VALID( vector) && MPC55XX_INTC_IS_VALID_PRIORITY( priority)) { - rtems_status_code sc = RTEMS_SUCCESSFUL; - - sc = rtems_interrupt_handler_install( vector, info, options, handler, arg); - RTEMS_CHECK_SC( sc, "Install interrupt handler"); - - return mpc55xx_intc_set_priority( vector, priority); - } else { - return RTEMS_INVALID_NUMBER; - } -} - -void bsp_interrupt_dispatch(uintptr_t exception_number) -{ - /* Acknowledge interrupt request */ - rtems_vector_number vector = INTC.IACKR.B.INTVEC; - - /* Save machine state and enable external exceptions */ - uint32_t msr = ppc_external_exceptions_enable(); - - /* Dispatch interrupt handlers */ - bsp_interrupt_handler_dispatch( vector); - - /* Restore machine state */ - ppc_external_exceptions_disable( msr); - - /* End of interrupt */ - INTC.EOIR.R = 1; -} - -rtems_status_code bsp_interrupt_facility_initialize(void) -{ - rtems_vector_number vector; - - /* Initialize interrupt controller */ - - /* Disable all interrupts */ - for (vector = MPC55XX_IRQ_MIN; vector <= MPC55XX_IRQ_MAX; ++vector) { - INTC.PSR [vector].B.PRI = MPC55XX_INTC_DISABLED_PRIORITY; - } - - /* Software vector mode */ - INTC.MCR.B.VTES = 0; - INTC.MCR.B.HVEN = 0; - - /* Set current priority to 0 */ - INTC.CPR.B.PRI = 0; - - return RTEMS_SUCCESSFUL; -} - -void bsp_interrupt_vector_enable( rtems_vector_number vector) -{ - bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - mpc55xx_intc_set_priority( vector, MPC55XX_INTC_DEFAULT_PRIORITY); -} - -void bsp_interrupt_vector_disable( rtems_vector_number vector) -{ - bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); - mpc55xx_intc_set_priority( vector, MPC55XX_INTC_DISABLED_PRIORITY); -} diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S b/c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S deleted file mode 100644 index f993936752..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/misc/copy.S +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx_asm - * - * @brief Memory copy functions. - */ - -/* - * Copyright (c) 2008 - * Embedded Brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * rtems@embedded-brains.de - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include - - .section ".bsp_start_text", "ax" - -/** - * @fn int mpc55xx_copy_8( const void *src, void *dest, size_t n) - * - * @brief Copy @a n bytes from @a src to @a dest with 8 byte reads and writes. - * - * The memory areas should not overlap. The addresses @a src and @a dest have - * to be aligned on 8 byte boundaries. The size @a n must be evenly divisible by 8. - * The SPE operations @b evxor, @b evlddx and @b evstddx will be used. - */ -#if ((MPC55XX_CHIP_TYPE>=5510) && (MPC55XX_CHIP_TYPE<=5517)) -GLOBAL_FUNCTION mpc55xx_copy_8 -#endif /* ((MPC55XX_CHIP_TYPE>=5510) && (MPC55XX_CHIP_TYPE<=5517)) */ -GLOBAL_FUNCTION mpc55xx_copy_4 - /* Loop counter = data size / 4 */ - srwi. r5, r5, 2 - beqlr - mtctr r5 - xor r5,r5,r5 -copy_data4: - lwzx r6, r5, r3 - stwx r6, r5, r4 - addi r5, r5, 4 - bdnz copy_data4 - - /* Return */ - blr - -#if !((MPC55XX_CHIP_TYPE>=5510) && (MPC55XX_CHIP_TYPE<=5517)) -/** - * @fn int mpc55xx_copy_8( const void *src, void *dest, size_t n) - * - * @brief Copy @a n bytes from @a src to @a dest with 8 byte reads and writes. - * - * The memory areas should not overlap. The addresses @a src and @a dest have - * to be aligned on 8 byte boundaries. The size @a n must be evenly divisible by 8. - * The SPE operations @b evxor, @b evlddx and @b evstddx will be used. - */ -GLOBAL_FUNCTION mpc55xx_copy_8 - /* Loop counter = data size / 8 */ - srwi. r5, r5, 3 - beqlr - mtctr r5 - - /* Set offset */ - evxor r5, r5, r5 - -copy_data: - evlddx r6, r3, r5 - evstddx r6, r4, r5 - addi r5, r5, 8 - bdnz copy_data - - /* Return */ - blr -#endif /*!((MPC55XX_CHIP_TYPE>=5510) && (MPC55XX_CHIP_TYPE<=5517))*/ diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c b/c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c deleted file mode 100644 index 1d94fda205..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/misc/flash_support.c +++ /dev/null @@ -1,698 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx - * - * @brief MPC55XX flash memory support. - * - * I set my MMU up to map what will finally be in flash into RAM and at the - * same time I map the flash to a different location. When the software - * is tested I can use this to copy the RAM version of the program into - * the flash and when I reboot I'm running out of flash. - * - * I use a flag word located after the boot configuration half-word to - * indicate that the MMU should be left alone, and I don't include the RCHW - * or that flag in my call to this routine. - * - * There are obviously other uses for this. - **/ - -/* - * Copyright (c) 2009-2011 - * HD Associates, Inc. - * 18 Main Street - * Pepperell, MA 01463 - * USA - * dufault@hda.com - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include -#include - -#if MPC55XX_CHIP_FAMILY == 555 || MPC55XX_CHIP_FAMILY == 556 - -/* Set up the memory ranges for the flash on - * the MPC5553, MPC5554, MPC5566 and MPC5567. - * I check if it is an unknown CPU and return an error. - * - * These CPUS have a low, mid, and high space of memory. - * - * Only the low space really needs a table like this, but for simplicity - * I do low, mid, and high the same way. - */ -struct range { /* A memory range. */ - uint32_t lower; - uint32_t upper; -}; - -/* The ranges of the memory banks for the low space. All the - * chips I'm looking at share this low format, identified by LAS=6: - * 2 16K banks, - * 2 48K banks, - * 2 64K banks. - */ -static const struct range lsel_ranges[] = { - { 0, (1*16 )*1024 - 1}, - {(1*16 )*1024, (2*16 )*1024 - 1}, - {(2*16 )*1024, (2*16 + 1*48 )*1024 - 1}, - {(2*16 + 1*48 )*1024, (2*16 + 2*48 )*1024 - 1}, - {(2*16 + 2*48 )*1024, (2*16 + 2*48 + 1*64)*1024 - 1}, - {(2*16 + 2*48 + 1*64)*1024, (2*16 + 2*48 + 2*64)*1024 - 1}, -}; - -/* The ranges of the memory blocks for the mid banks, 2 128K banks. - * Again, all the chips share this, identified by MAS=0. - */ -#define MBSTART ((2*16+2*48+2*64)*1024) -static const struct range msel_ranges[] = { - {MBSTART , MBSTART + 1*128*1024 - 1}, - {MBSTART + 1*128*1024, MBSTART + 2*128*1024 - 1}, -}; - -/* The ranges of the memory blocks for the high banks. - * There are N 128K banks, where N <= 20, - * and is identified by looking at the SIZE field. - * - * This could benefit from being redone to save a few bytes - * and provide for bigger flash spaces. - */ -#define HBSTART (MBSTART+2*128*1024) -static const struct range hbsel_ranges[] = { - {HBSTART , HBSTART + 1*128*1024 - 1}, - {HBSTART + 1*128*1024, HBSTART + 2*128*1024 - 1}, - {HBSTART + 2*128*1024, HBSTART + 3*128*1024 - 1}, - {HBSTART + 3*128*1024, HBSTART + 4*128*1024 - 1}, - {HBSTART + 4*128*1024, HBSTART + 5*128*1024 - 1}, - {HBSTART + 5*128*1024, HBSTART + 6*128*1024 - 1}, - {HBSTART + 6*128*1024, HBSTART + 7*128*1024 - 1}, - {HBSTART + 7*128*1024, HBSTART + 8*128*1024 - 1}, - {HBSTART + 8*128*1024, HBSTART + 9*128*1024 - 1}, - {HBSTART + 9*128*1024, HBSTART + 10*128*1024 - 1}, - {HBSTART + 10*128*1024, HBSTART + 11*128*1024 - 1}, - {HBSTART + 11*128*1024, HBSTART + 12*128*1024 - 1}, - {HBSTART + 12*128*1024, HBSTART + 13*128*1024 - 1}, - {HBSTART + 13*128*1024, HBSTART + 14*128*1024 - 1}, - {HBSTART + 14*128*1024, HBSTART + 15*128*1024 - 1}, - {HBSTART + 15*128*1024, HBSTART + 16*128*1024 - 1}, - {HBSTART + 16*128*1024, HBSTART + 17*128*1024 - 1}, - {HBSTART + 17*128*1024, HBSTART + 18*128*1024 - 1}, - {HBSTART + 18*128*1024, HBSTART + 19*128*1024 - 1}, - {HBSTART + 19*128*1024, HBSTART + 20*128*1024 - 1}, -}; - -/* Set bits in a bitmask to indicate which banks are - * within the range "first" and "last". - */ -static void -range_set( - uint32_t first, - uint32_t last, - int *p_bits, - const struct range *pr, - int n_range -) -{ - int i; - int bits = 0; - for (i = 0; i < n_range; i++) { - /* If the upper limit is less than "first" or the lower limit - * is greater than "last" then the block is not in range. - */ - if ( !(pr[i].upper < first || pr[i].lower > last)) { - bits |= (1 << i); /* This block is in the range, set the bit. */ - } - - } - *p_bits = bits; -} - -/** Return the size of the on-chip flash - * verifying that this is a device that we know about. - * @return 0 for OK, non-zero for error: - * - MPC55XX_FLASH_VERIFY_ERR for LAS not 6 or MAS not 0. - * @note This is overriding what verify means! - * - MPC55XX_FLASH_SIZE_ERR Not a chip I've checked against the manual, - * athat is, SIZE not 5, 7, or 11. - */ -int -mpc55xx_flash_size( - uint32_t *p_size /**< The size is returned here. */ -) -{ - /* On the MPC5553, MPC5554, MPC5566, and MP5567 the - * low address space LAS field is 0x6 and all have - * six blocks sized 2*16k, 2*48k, and 2*64k. - * - * All the mid and high address spaces have 128K blocks. - * - * The mid address space MAS size field is 0 for the above machines, - * and they all have 2 128K blocks. - * - * For the high address space we look at the - * size field to figure out the size. The SIZE field is: - * - * 5 for 1.5MB (MPC5553) - * 7 for 2MB (MPC5554, MPC5567) - * 11 for 3MB (MPC5566) - */ - int hblocks; /* The number of blocks in the high address space. */ - - /* Verify the configuration matches one of the chips that I've checked out. - */ - if (FLASH.MCR.B.LAS != 6 || FLASH.MCR.B.MAS != 0) { - return MPC55XX_FLASH_VERIFY_ERR; - } - - switch(FLASH.MCR.B.SIZE) { - case 5: - hblocks = 8; - break; - - case 7: - hblocks = 12; - break; - - case 11: - hblocks = 20; - break; - - default: - return MPC55XX_FLASH_SIZE_ERR; - } - - /* The first two banks are 256K. - * The high block has "hblocks" 128K blocks. - */ - *p_size = 256*1024 + 256*1024 + hblocks * 128*1024; - return 0; -} - -/* Unlock the flash blocks if "p_locked" points to something that is 0. - * If it is a NULL pointer then we aren't allowed to do the unlock. - */ -static int -unlock_once(int lsel, int msel, int hbsel, int *p_locked) -{ - union LMLR_tag lmlr; - union SLMLR_tag slmlr; - union HLR_tag hlr; - - /* If we're already locked return. - */ - if (p_locked && (*p_locked == 1)) { - return 0; - } - - /* Do we have to lock something in the low or mid block? - */ - lmlr = FLASH.LMLR; - if ((lsel || msel) && (lmlr.B.LME == 0)) { - union LMLR_tag lmlr_unlock; - lmlr_unlock.B.LLOCK=~lsel; - lmlr_unlock.B.MLOCK=~msel; - lmlr_unlock.B.SLOCK=1; - - if (lmlr.B.LLOCK != lmlr_unlock.B.LLOCK || - lmlr.B.MLOCK != lmlr_unlock.B.MLOCK) { - if (p_locked == 0) { - return MPC55XX_FLASH_LOCK_ERR; - } else { - *p_locked = 1; - } - FLASH.LMLR.R = 0xA1A11111; /* Unlock. */ - FLASH.LMLR = lmlr_unlock; - } - } - - slmlr = FLASH.SLMLR; - if ((lsel || msel) && (slmlr.B.SLE == 0)) { - union SLMLR_tag slmlr_unlock; - slmlr_unlock.B.SLLOCK=~lsel; - slmlr_unlock.B.SMLOCK=~msel; - slmlr_unlock.B.SSLOCK=1; - - if (slmlr.B.SLLOCK != slmlr_unlock.B.SLLOCK || - slmlr.B.SMLOCK != slmlr_unlock.B.SMLOCK) { - if (p_locked == 0) { - return MPC55XX_FLASH_LOCK_ERR; - } else { - *p_locked = 1; - } - FLASH.SLMLR.R = 0xC3C33333; /* Unlock. */ - FLASH.SLMLR = slmlr_unlock; - } - } - - /* Do we have to unlock something in the high block? - */ - hlr = FLASH.HLR; - if (hbsel && (hlr.B.HBE == 0)) { - union HLR_tag hlr_unlock; - hlr_unlock.B.HBLOCK = ~hbsel; - - if (hlr.B.HBLOCK != hlr_unlock.B.HBLOCK) { - if (p_locked == 0) { - return MPC55XX_FLASH_LOCK_ERR; - } else { - *p_locked = 1; - } - FLASH.HLR.R = 0xB2B22222; /* Unlock. */ - FLASH.HLR = hlr_unlock; - } - } - - return 0; -} - -static inline uint32_t -tsize(int i) -{ - return 1 << (10 + 2 * i); -} - -static int -addr_map( - int to_phys, /* If 1 lookup physical else lookup mapped. */ - const void *addr, /* The address to look up. */ - uint32_t *p_result /* Result is here. */ -) -{ - uint32_t u_addr = (uint32_t)addr; - uint32_t mas0, mas1, mas2, mas3; - uint32_t start, end; - rtems_interrupt_level level; - int i; - - for (i = 0; i < 32; i++) { - mas0 = 0x10000000 | (i << 16); - rtems_interrupt_disable(level); - PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS0, mas0); - asm volatile("tlbre"); - mas1 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS1); - mas2 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS2); - mas3 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3); - rtems_interrupt_enable(level); - - if (mas1 & 0x80000000) { - /* Valid. */ - start = (to_phys ? mas2 : mas3) & 0xFFFFF000; - end = start + tsize((mas1 >> 8) & 0x0000000F); - /* Are we within range? - */ - if (start <= u_addr && end >= u_addr) { - uint32_t offset = (to_phys ? mas3 : mas2) & 0xFFFFF000; - *p_result = u_addr - offset; - return 0; - } - } - } - - /* Not found in a TLB. - */ - return ESRCH; -} - -/** Return the physical address corresponding to a mapped address. - @return 0 if OK, ESRCH if not found in TLB1. - **/ -int -mpc55xx_physical_address( - const void *addr, /**< Mapped address. */ - uint32_t *p_result /**< Result returned here. */ -) -{ - return addr_map(1, addr, p_result); -} - -/** Return the mapped address corresponding to a mapped address. - @return 0 if OK, ESRCH if not found in TLB1. - **/ -int -mpc55xx_mapped_address( - const void *addr, /**< Mapped address. */ - uint32_t *p_result /**< Result returned here. */ -) -{ - return addr_map(0, addr, p_result); -} - -/** - * Copy memory from an address into the flash when flash is relocated - * If programming fails the address that it failed at can be returned. - @note At end of operation the flash may be left writable. - * Use mpc55xx_flash_read_only() to set read-only. - @return Zero for OK, non-zero for error: - * - ESRCH Can't lookup where something lives. - * - EPERM Attempt to write to non-writable flash. - * - ETXTBSY Attempt to flash overlapping regions. - * - MPC55XX_FLASH_CONFIG_ERR for LAS not 6 or MAS not 0. - * - MPC55XX_FLASH_SIZE_ERR for SIZE not 5, 7, or 11. - * - MPC55XX_FLASH_RANGE_ERR for illegal access: - * - first or first+last outside of flash; - * - first not on a mod(8) boundary; - * - nbytes not multiple of 8. - * - MPC55XX_FLASH_ERASE_ERR Erase requested but failed. - * - MPC55XX_FLASH_PROGRAM_ERR Program requested but failed. - * - MPC55XX_FLASH_NOT_BLANK_ERR Blank check requested but not blank. - * - MPC55XX_FLASH_VERIFY_ERR Verify requested but failed. - * - MPC55XX_FLASH_LOCK_ERR Unlock requested but failed. - **/ - -int -mpc55xx_flash_copy_op( - void *dest, /**< An address in the flash to copy to. */ - const void *src, /**< An address in memory to copy from. */ - size_t nbytes, /**< The number of bytes to copy. */ - uint32_t opmask, /**< Bitmask of operations to perform. - * - MPC55XX_FLASH_UNLOCK: Unlock the blocks. - * - MPC55XX_FLASH_ERASE: Erase the blocks. - * - MPC55XX_FLASH_BLANK_CHECK: Verify the blocks are blank. - * - MPC55XX_FLASH_PROGRAM: Program the FLASH. - * - MPC55XX_FLASH_VERIFY: Verify the regions match. - **/ - uint32_t *p_fail /**< If not NULL then the address where the operation - * failed is returned here. - **/ -) -{ - uint32_t udest, usrc, flash_size; - int r; - int peg; /* Program or Erase Good - Did it work? */ - - int lsel; /* Low block select bits. */ - int msel; /* Mid block select bits. */ - int hbsel; /* High block select bits. */ - - int s_lsel; /* Source Low block select bits. */ - int s_msel; /* Source Mid block select bits. */ - int s_hbsel; /* Source High block select bits. */ - - int unlocked = 0; - int *p_unlocked; - int i; - int nwords; /* The number of 32 bit words to write. */ - volatile uint32_t *flash; /* Where the flash is mapped in. */ - volatile uint32_t *memory; /* What to copy into flash. */ - const void *flashing_from; /* Where we are flahsing from. - * "const" is to match invalidate cache function signature. */ - uint32_t offset; /* Where the FLASH is mapped into memory. */ - - if ( (r = mpc55xx_flash_size(&flash_size))) { - return r; - } - - /* Get where the flash is mapped in. - */ - offset = mpc55xx_flash_address(); - - udest = ((uint32_t)dest) - offset; - if ( (r = mpc55xx_physical_address(src, &usrc)) ) { - return r; - } - - /* Verify that the address being programmed is in flash and that it is - * a multiple of 64 bits. - * Someone else can remove the 64-bit restriction. - */ - if (udest > flash_size || - udest + nbytes > flash_size || - (udest & 0x7) != 0 || - (nbytes & 0x7) != 0) { - return MPC55XX_FLASH_RANGE_ERR; - } - - if (opmask == 0) { - return 0; - } - - /* If we're going to do a write-style operation the flash must be writable. - */ - if ((opmask & - (MPC55XX_FLASH_UNLOCK | MPC55XX_FLASH_ERASE | MPC55XX_FLASH_PROGRAM)) && - !mpc55xx_flash_writable() - ) { - return EPERM; - } - - /* If we aren't allowed to unlock then set the pointer to zero. - * That is how "unlock_once" decides we can't unlock. - */ - p_unlocked = (opmask & MPC55XX_FLASH_UNLOCK) ? &unlocked : 0; - - /* Set up the bit masks for the blocks to program or erase. - */ - range_set(udest, udest + nbytes, &lsel, lsel_ranges, RTEMS_ARRAY_SIZE( lsel_ranges)); - range_set(udest, udest + nbytes, &msel, msel_ranges, RTEMS_ARRAY_SIZE( msel_ranges)); - range_set(udest, udest + nbytes, &hbsel, hbsel_ranges, RTEMS_ARRAY_SIZE(hbsel_ranges)); - - range_set(usrc, usrc + nbytes, &s_lsel, lsel_ranges, RTEMS_ARRAY_SIZE( lsel_ranges)); - range_set(usrc, usrc + nbytes, &s_msel, msel_ranges, RTEMS_ARRAY_SIZE( msel_ranges)); - range_set(usrc, usrc + nbytes, &s_hbsel, hbsel_ranges, RTEMS_ARRAY_SIZE(hbsel_ranges)); - - /* Are we attempting overlapping flash? - */ - if ((lsel & s_lsel) | (msel & s_msel) | (hbsel & s_hbsel)) { - return ETXTBSY; - } - - nwords = nbytes / 4; - flash = (volatile uint32_t *)dest; - memory = (volatile uint32_t *)src; - - /* In the following sections any "Step N" notes refer to - * the steps in "13.4.2.3 Flash Programming" in the reference manual. - */ - - if (opmask & MPC55XX_FLASH_ERASE) { /* Erase. */ - uint32_t flash_biucr_r; - if ( (r = unlock_once(lsel, msel, hbsel, p_unlocked)) ) { - return r; - } - - /* Per errata "e989: FLASH: Disable Prefetch during programming and erase" */ - flash_biucr_r = FLASH.BIUCR.R; - FLASH.BIUCR.B.PFLIM = 0; - - FLASH.MCR.B.ESUS = 0; /* Be sure ESUS is clear. */ - - FLASH.MCR.B.ERS = 1; /* Step 1: Select erase. */ - - FLASH.LMSR.B.LSEL = lsel; /* Step 2: Select blocks to be erased. */ - FLASH.LMSR.B.MSEL = msel; - FLASH.HSR.B.HBSEL = hbsel; - - flash[0] = 0xffffffff; /* Step 3: Write to any address in the flash - * (the "erase interlock write)". - */ - rtems_cache_flush_multiple_data_lines( - RTEMS_DEVOLATILE(void *,flash), - sizeof(flash[0]) - ); - - FLASH.MCR.B.EHV = 1; /* Step 4: Enable high V to start erase. */ - while (FLASH.MCR.B.DONE == 0) { /* Step 5: Wait until done. */ - } - peg = FLASH.MCR.B.PEG; /* Save result. */ - FLASH.MCR.B.EHV = 0; /* Disable high voltage. */ - FLASH.MCR.B.ERS = 0; /* De-select erase. */ - FLASH.BIUCR.R = flash_biucr_r; - - if (peg == 0) { - return MPC55XX_FLASH_ERASE_ERR; /* Flash erase failed. */ - } - } - - if (opmask & MPC55XX_FLASH_BLANK_CHECK) { /* Verify blank. */ - for (i = 0; i < nwords; i++) { - if (flash[i] != 0xffffffff) { - if (p_fail) { - *p_fail = (uint32_t)(flash + i); - } - return MPC55XX_FLASH_NOT_BLANK_ERR; /* Not blank. */ - } - } - } - - /* Program. - */ - if (opmask & MPC55XX_FLASH_PROGRAM) { - int chunk = 0; /* Used to collect programming into 256 bit chunks. */ - - if ( (r = unlock_once(lsel, msel, hbsel, p_unlocked)) ) { - return r; - } - FLASH.MCR.B.PGM = 1; /* Step 1 */ - - for (flashing_from = (const void *)flash, i = 0; i < nwords; i += 2) { - flash[i] = memory[i]; /* Step 2 */ - flash[i + 1] = memory[i + 1]; /* Always program in min 64 bits. */ - - /* Step 3 is "write additional words" */ - - /* Try to program in chunks of 256 bits. - * Collect the 64 bit writes into 256 bit ones: - */ - chunk++; - if (chunk == 4) { - /* Collected 4 64-bits for a 256 bit chunk. */ - - rtems_cache_flush_multiple_data_lines(flashing_from, 32); /* Flush cache. */ - - FLASH.MCR.B.EHV = 1; /* Step 4: Enable high V. */ - - while (FLASH.MCR.B.DONE == 0) { /* Step 5: Wait until done. */ - } - - peg = FLASH.MCR.B.PEG; /* Step 6: Save result. */ - FLASH.MCR.B.EHV = 0; /* Step 7: Disable high V. */ - if (peg == 0) { - FLASH.MCR.B.PGM = 0; - if (p_fail) { - *p_fail = (uint32_t)(flash + i); - } - return MPC55XX_FLASH_PROGRAM_ERR; /* Programming failed. */ - } - chunk = 0; /* Reset chunk counter. */ - flashing_from = (const void *)(flash + i); - } - /* Step 8: Back to step 2. */ - } - - if (!chunk) { - FLASH.MCR.B.PGM = 0; - } else { - /* If there is anything left in that last chunk flush it out: - */ - - rtems_cache_flush_multiple_data_lines(flashing_from, chunk * 8); - - FLASH.MCR.B.EHV = 1; - - while (FLASH.MCR.B.DONE == 0) { /* Wait until done. */ - } - - peg = FLASH.MCR.B.PEG; /* Save result. */ - FLASH.MCR.B.EHV = 0; /* Disable high voltage. */ - FLASH.MCR.B.PGM = 0; - - if (peg == 0) { - if (p_fail) { - *p_fail = (uint32_t)(flash + i); - } - return MPC55XX_FLASH_PROGRAM_ERR; /* Programming failed. */ - } - } - } - - if (opmask & MPC55XX_FLASH_VERIFY) { /* Verify memory matches. */ - for (i = 0; i < nwords; i++) { - if (flash[i] != memory[i]) { - if (p_fail) { /* Return the failed address. */ - *p_fail = (uint32_t)(flash + i); - } - return MPC55XX_FLASH_VERIFY_ERR; /* Verification failed. */ - } - } - } - - return 0; -} - -/** Simple flash copy with a signature that matches memcpy. - @note At end of operation the flash may be left writable. - * Use mpc55xx_flash_read_only() to set read-only. - @return Zero for OK, non-zero for error. - * see flash_copy_op() for possible errors. - **/ -int -mpc55xx_flash_copy( - void *dest, /**< An address in the flash to copy to. */ - const void *src, /**< An address in the flash copy from. */ - size_t nbytes /**< The number of bytes to copy. */ -) -{ - return mpc55xx_flash_copy_op(dest, src, nbytes, - (MPC55XX_FLASH_UNLOCK | - MPC55XX_FLASH_ERASE | - MPC55XX_FLASH_BLANK_CHECK | - MPC55XX_FLASH_PROGRAM | - MPC55XX_FLASH_VERIFY ), 0); -} - -/** Make the flash read-write. - @note This assumes the flash is mapped by TLB1 entry 1. - */ -void -mpc55xx_flash_set_read_write(void) -{ - rtems_interrupt_level level; - rtems_interrupt_disable(level); - PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000); - asm volatile("tlbre"); - PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(FSL_EIS_MAS3, 0x0000000C); - asm volatile("tlbwe"); - rtems_interrupt_enable(level); -} - -/** Make the flash read-only. - @note This assumes the flash is mapped by TLB1 entry 1. - */ -void -mpc55xx_flash_set_read_only(void) -{ - rtems_interrupt_level level; - rtems_interrupt_disable(level); - PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000); - asm volatile("tlbre"); - PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(FSL_EIS_MAS3, 0x0000000C); - asm volatile("tlbwe"); - rtems_interrupt_enable(level); -} - -/** See if the flash is writable. - * @note This assumes the flash is mapped by TLB1 entry 1. - * @note It needs to be writable by both user and supervisor. - */ -int -mpc55xx_flash_writable(void) -{ - uint32_t mas3; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000); - asm volatile("tlbre"); - mas3 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS3); - rtems_interrupt_enable(level); - - return ((mas3 & 0x0000000C) == 0x0000000C) ? 1 : 0; -} - -/** Return the address where the flash is mapped in. - @note This assumes the flash is mapped by TLB1 entry 1. - **/ -uint32_t -mpc55xx_flash_address(void) -{ - uint32_t mas2; - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - PPC_SET_SPECIAL_PURPOSE_REGISTER( FSL_EIS_MAS0, 0x10010000); - asm volatile("tlbre"); - mas2 = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_MAS2); - rtems_interrupt_enable(level); - - return mas2 & 0xFFFFF000; -} - -#endif /* MPC55XX_CHIP_FAMILY == 555 || MPC55XX_CHIP_FAMILY == 556 */ diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/siu/siu.c b/c/src/lib/libcpu/powerpc/mpc55xx/siu/siu.c deleted file mode 100644 index 9801270a80..0000000000 --- a/c/src/lib/libcpu/powerpc/mpc55xx/siu/siu.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file - * - * @ingroup mpc55xx - * - * @brief System Integration Unit Access (SIU). - */ - -/* - * Copyright (c) 2010 - * Embedded Brains GmbH - * Obere Lagerstr. 30 - * D-82178 Puchheim - * Germany - * rtems@embedded-brains.de - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include - -rtems_status_code mpc55xx_siu_pcr_init(volatile struct SIU_tag *siu, - const mpc55xx_siu_pcr_entry_t *pcr_entry) -{ - int idx,cnt; - /* - * repeat, until end of list reached (pcr_cnt = 0) - */ - while ((pcr_entry != NULL) && - (pcr_entry->pcr_cnt > 0)) { - idx = pcr_entry->pcr_idx; - for (cnt = pcr_entry->pcr_cnt;cnt > 0;cnt--) { - siu->PCR[idx++].R = pcr_entry->pcr_val.R; - } - pcr_entry++; - } - return RTEMS_SUCCESSFUL; -} -- cgit v1.2.3