diff options
Diffstat (limited to 'c')
10 files changed, 340 insertions, 9 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog b/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog index 213f00ec9e..e9ea31c72a 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/ChangeLog @@ -1,3 +1,33 @@ +2011-08-30 Peter Dufault <dufault@hda.com> + + * make/custom/phycore_mpc5554.cfg, startup/linkcmds.phycore_mpc5554, + network/if_smc.c: New files. + * Makefile.am, preinstall.am: Reflect changes above. + * configure.ac: Add support for the Phytec PhyCORE MPC5554. Includes: + - HAS_SMC91111 to indicate a BSP has that neworking. + - SMC91111_ENADDR_IS_SETUP so that it skips code to set up the MAC + address. + - MPC55XX_CLOCK_EMIOS_CHANNEL to permit one to set which eMIOS + channel to use for the clock. + - MPC55XX_BOOTFLAGS: Skips two words above the RCHW in the startup + for use in skpping over the MMU setup. Required for debugging via a + cheap emulator where code is loaded into RAM and then mapped in as + flash. + - BOARD_PHYCORE_MPC5554 If defined, use custom settings for the + Phytec PhyCORE MPC5554 SOM. + * clock/clock-config.c: Modify so that the EMIOS channel used for the + clock can be selected at configuration time. For MPC5544 only: + - Conditionally skip access to a register that faults if accessed on + the MPC5554 + - Do not set the control register mode as was done for GW_LCFM + support, it breaks interrupts. + * make/custom/mpc55xx.inc: Make it possible to override the soft-float + to set the type of floating point BSP will use. + * startup/start.S: Add support for the "boot flags", two long-words + that I manipulate with the debugger to skip over MMU setup. Use an + external for the start of external SRAM instead of the hardwired + number 0x20000000. Disable write access to the internal flash. + 2011-08-30 Sebastian Huber <sebastian.huber@embedded-brains.de> * include/bsp.h: Define BSP_FEATURE_IRQ_EXTENSION. diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am b/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am index e449ad9528..bf6b2eaabb 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/Makefile.am @@ -24,8 +24,11 @@ project_lib_DATA += rtems_crti.$(OBJEXT) # Link commands project_lib_DATA += startup/linkcmds -dist_project_lib_DATA += startup/linkcmds.gwlcfm startup/linkcmds.mpc5566evb \ - startup/linkcmds.base +dist_project_lib_DATA += \ + startup/linkcmds.gwlcfm \ + startup/linkcmds.phycore_mpc5554 \ + startup/linkcmds.mpc5566evb \ + startup/linkcmds.base noinst_LIBRARIES += libbsp.a libbsp_a_SOURCES = @@ -71,7 +74,7 @@ libbsp_a_SOURCES += i2c/i2c_init.c \ # Network if HAS_NETWORKING -libbsp_a_SOURCES += network/smsc9218i.c +libbsp_a_SOURCES += network/smsc9218i.c network/if_smc.c endif # BSP library diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c index 641bb12047..b3dc3bddab 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c @@ -31,8 +31,6 @@ #include <rtems/status-checks.h> -#define MPC55XX_CLOCK_EMIOS_CHANNEL (MPC55XX_EMIOS_CHANNEL_NUMBER - 1) - /* This is defined in clockdrv_shell.h */ rtems_isr Clock_isr( rtems_vector_number vector); @@ -104,10 +102,21 @@ static void mpc55xx_clock_initialize( void) /* Set unused registers */ regs->CBDR.R = 0; regs->CCNTR.R = 0; +#if MPC55XX_CHIP_TYPE != 5554 + /* This is reserved on the MPC5554. + */ regs->ALTCADR.R = 0; +#endif /* Set control register */ + /* The mode change, made by Thomas for GW_LCFM support, breaks interrupts + * on the MPC5554. + */ +#if MPC55XX_CHIP_TYPE == 5554 + ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK; +#else ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK; +#endif ccr.B.UCPREN = 1; ccr.B.FEN = 1; ccr.B.FREN = 1; diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac b/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac index 049ab7ff4a..337ef6cd87 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/configure.ac @@ -50,6 +50,7 @@ RTEMS_BSPOPTS_HELP([UARTS_IO_MODE], [Define to 1 if you want interrupt-driven I/O for the SCI ports.]) RTEMS_BSPOPTS_SET([PRINTK_MINOR],[gwlcfm],[MPC55XX_ESCI_A_MINOR]) +RTEMS_BSPOPTS_SET([PRINTK_MINOR],[phytec_mpc5554],[MPC55XX_ESCI_A_MINOR]) RTEMS_BSPOPTS_SET([PRINTK_MINOR],[*] ,[MPC55XX_ESCI_B_MINOR]) RTEMS_BSPOPTS_HELP([PRINTK_MINOR], [Must be defined to be one of MPC55XX_ESCI_A_MINOR or MPC55XX_ESCI_B_MINOR. Determines which @@ -83,12 +84,28 @@ RTEMS_BSPOPTS_SET([MPC55XX_EMIOS_PRESCALER],[*] ,[1]) RTEMS_BSPOPTS_HELP([MPC55XX_EMIOS_PRESCALER], [Must be defined to set the EMIOS prescaler]) +RTEMS_BSPOPTS_SET([HAS_SMC91111],[phycore_mpc5554],[1]) +RTEMS_BSPOPTS_HELP([HAS_SMC91111], +[If defined the board has the SMC91111 networking chip.]) + +RTEMS_BSPOPTS_SET([SMC91111_ENADDR_IS_SETUP],[phycore_mpc5554],[1]) +RTEMS_BSPOPTS_HELP([SMC91111_ENADDR_IS_SETUP], +[If defined the SMC91111 chip has the ethernet address loaded at reset.]) + +RTEMS_BSPOPTS_SET([MPC55XX_CLOCK_EMIOS_CHANNEL],[*],[(MPC55XX_EMIOS_CHANNEL_NUMBER-1)]) +RTEMS_BSPOPTS_HELP([MPC55XX_CLOCK_EMIOS_CHANNEL], +[Define to the eMIOS channel to use for the BSP clock. + The default is the last channel.]) + RTEMS_BSPOPTS_SET([MPC55XX_CHIP_TYPE],[mpc5566evb],[5566]) RTEMS_BSPOPTS_SET([MPC55XX_CHIP_TYPE],[gwlcfm] ,[5516]) RTEMS_BSPOPTS_SET([MPC55XX_CHIP_TYPE],[*] ,[5554]) RTEMS_BSPOPTS_HELP([MPC55XX_CHIP_TYPE], [specifies the chip type in use (e.g. 5554 for MPC5554)]) +RTEMS_BSPOPTS_HELP([MPC55XX_BOOTFLAGS], +[If defined, builds in bootflags above the RCHW for setup in a debugger to avoid startup MMU setup]) + RTEMS_BSPOPTS_SET([BOARD_GWLCFM],[gwlcfm],[1]) RTEMS_BSPOPTS_HELP([BOARD_GWLCFM], [If defined, use custom settings of for the GW_LCFM board]) @@ -98,6 +115,10 @@ RTEMS_BSPOPTS_HELP([RTEMS_BSP_I2C_EEPROM_DEVICE_NAME],[EEPROM name for LibI2C]) RTEMS_BSPOPTS_SET([RTEMS_BSP_I2C_EEPROM_DEVICE_PATH],[gwlcfm],['"/dev/i2c1.eeprom"']) RTEMS_BSPOPTS_HELP([RTEMS_BSP_I2C_EEPROM_DEVICE_PATH],[EEPROM device file path]) +RTEMS_BSPOPTS_SET([BOARD_PHYCORE_MPC5554],[phycore_mpc5554],[1]) +RTEMS_BSPOPTS_HELP([BOARD_PHYCORE_MPC5554], +[If defined, use custom settings for the Phytec PhyCORE MPC5554 SOM]) + AC_CONFIG_FILES([Makefile include/bspopts.h]) diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc b/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc index faf493431f..fa469fad23 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/mpc55xx.inc @@ -13,8 +13,10 @@ RTEMS_CPU = powerpc RTEMS_CPU_MODEL = mpc55xx +CPU_CFLAGS_FLOAT?=-msoft-float + # FIXME -CPU_CFLAGS = -mcpu=8540 -meabi -msdata -fno-common -msoft-float \ +CPU_CFLAGS = -mcpu=8540 -meabi -msdata -fno-common $(CPU_CFLAGS_FLOAT) \ -D__ppc_generic -mstrict-align CFLAGS_OPTIMIZE_V = -O2 -g -fno-keep-inline-functions diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/phycore_mpc5554.cfg b/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/phycore_mpc5554.cfg new file mode 100644 index 0000000000..37fd6d2a56 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/make/custom/phycore_mpc5554.cfg @@ -0,0 +1,16 @@ +## +# +# @file +# +# @ingroup mpc55xx_config +# +# @brief configuration file for the Phytec PhyCORE MPC5554 +# + +RTEMS_LINKCMDS=linkcmds.phycore_mpc5554 + +ifeq ($(PPC_USE_SPE),1) +CPU_CFLAGS_FLOAT=-mfloat-gprs=single -mspe +endif + +include $(RTEMS_ROOT)/make/custom/mpc55xx.inc diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c new file mode 100644 index 0000000000..c16dcda022 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c @@ -0,0 +1,167 @@ +/* + * $Id$ + */ + +#include <mpc55xx/mpc55xx.h> +#include <mpc55xx/regs.h> + +#include <rtems.h> + +#include <bsp.h> + +#include <bsp/irq.h> +#include <rtems/bspIo.h> +#include <libcpu/powerpc-utility.h> + + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <rtems/error.h> +#include <rtems/rtems_bsdnet.h> +#include <rtems/irq-extension.h> + +#include <sys/param.h> +#include <sys/mbuf.h> + +#include <sys/socket.h> +#include <sys/sockio.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/if_ether.h> + +#include <libchip/smc91111exp.h> + + + +/* The SMC91111 on the MPC5554SOM is IRQ2. + */ +#define SMC91111_BASE_ADDR (void*)0x22000300 +#define SMC91111_BASE_IRQ MPC55XX_IRQ_SIU_EXTERNAL_2 +#define SMC91111_BASE_PIO 4 + +extern rtems_isr lan91cxx_interrupt_handler(rtems_vector_number v); + +static const union SIU_EISR_tag clear_eisr_2 = {.B.EIF2 = 1}; + +static void rtems_smc91111_interrupt_wrapper(rtems_vector_number v, void *arg) +{ + /* Clear external interrupt status */ + + SIU.EISR = clear_eisr_2; + + lan91cxx_interrupt_handler(v); + +} + +scmv91111_configuration_t mpc5554_scmv91111_configuration = { + SMC91111_BASE_ADDR, /* base address */ + SMC91111_BASE_IRQ, /* vector number */ + SMC91111_BASE_PIO, /* XXX: What's this? */ + 100, /* 100b */ + 1, /* fulldx */ + 1, /* autoneg */ + "SMC91111", + RTEMS_INTERRUPT_UNIQUE, + rtems_smc91111_interrupt_wrapper, + (void *)0 +}; + +int _rtems_smc91111_driver_attach( + struct rtems_bsdnet_ifconfig *config, + scmv91111_configuration_t *scm_config +); + +/* + * Attach an SMC91111 driver to the system + */ +int rtems_smc91111_driver_attach_mpc5554(struct rtems_bsdnet_ifconfig *config) +{ + /* Configure IRQ2 (GPIO pin 211) is set up properly: + * Secondary, Alternate, Input. + */ + static const union SIU_PCR_tag irq_input_pcr = { + .B.PA = 2, /* Alternate function 1 */ + .B.OBE = 0, + .B.IBE = 1, /* Input Buffer Enable */ + .B.DSC = 0, + .B.ODE = 0, + .B.HYS = 1, + .B.SRC = 3, /* Maximum slew rate */ + .B.WPE = 0, /* Disable weak pullup/pulldown */ + .B.WPS = 1 /* Specify weak pullup? But it isn't enabled! */ + }; + + union SIU_ORER_tag orer = MPC55XX_ZERO_FLAGS; + union SIU_DIRER_tag direr = MPC55XX_ZERO_FLAGS; + union SIU_IREER_tag ireer = MPC55XX_ZERO_FLAGS; + union SIU_IFEER_tag ifeer = MPC55XX_ZERO_FLAGS; + union SIU_IDFR_tag idfr = MPC55XX_ZERO_FLAGS; + union SIU_DIRSR_tag dirsr = MPC55XX_ZERO_FLAGS; + rtems_interrupt_level level; + +#define MPC55XX_EBI_CS_2_BR 0x22000003 +#define MPC55XX_EBI_CS_2_OR 0xff000010 +#if MPC55XX_EBI_CS_2_BR + static const union SIU_PCR_tag primary_50pf_weak_pullup = { /* 0x4c3 */ + .B.PA = 1, + .B.DSC = 3, + .B.WPE = 1, + .B.WPS = 1 + }; + EBI.CS[2].BR.R = MPC55XX_EBI_CS_2_BR; + EBI.CS[2].OR.R = MPC55XX_EBI_CS_2_OR; + SIU.PCR[2] = primary_50pf_weak_pullup; +#endif + + SIU.PCR[211] = irq_input_pcr; + + /* XXX These should be using bit set and bit clear instructions */ + + /* DMA/Interrupt Request Select */ + rtems_interrupt_disable(level); + dirsr.R = SIU.DIRSR.R; + dirsr.B.DIRS2 = 0; /* Select interrupt not DMA */ + SIU.DIRSR.R = dirsr.R; + rtems_interrupt_enable(level); + + /* Overrun Request Enable */ + rtems_interrupt_disable(level); + orer.R = SIU.ORER.R; + orer.B.ORE2 = 0; /* Disable overruns. */ + SIU.ORER.R = orer.R; + rtems_interrupt_enable(level); + + /* IRQ Rising-Edge Enable */ + rtems_interrupt_disable(level); + ireer.R = SIU.IREER.R; + ireer.B.IREE2 = 1; /* Enable rising edge. */ + SIU.IREER.R = ireer.R; + rtems_interrupt_enable(level); + + /* IRQ Falling-Edge Enable */ + rtems_interrupt_disable(level); + ifeer.R = SIU.IFEER.R; + ifeer.B.IFEE2 = 0; /* Disable falling edge. */ + SIU.IFEER.R = ifeer.R; + rtems_interrupt_enable(level); + + /* IRQ Digital Filter */ + rtems_interrupt_disable(level); + idfr.R = SIU.IDFR.R; + idfr.B.DFL = 0; /* Minimal digital filter. */ + SIU.IDFR.R = idfr.R; + rtems_interrupt_enable(level); + + /* Clear external interrupt status */ + SIU.EISR = clear_eisr_2; + + /* DMA/Interrupt Request Enable */ + rtems_interrupt_disable(level); + direr.R = SIU.DIRER.R; + direr.B.EIRE2 = 1; /* Enable. */ + SIU.DIRER.R = direr.R; + rtems_interrupt_enable(level); + + return _rtems_smc91111_driver_attach(config,&mpc5554_scmv91111_configuration); +}; diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am b/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am index a0c45b245c..18fb061a21 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/preinstall.am @@ -57,6 +57,10 @@ $(PROJECT_LIB)/linkcmds.gwlcfm: startup/linkcmds.gwlcfm $(PROJECT_LIB)/$(dirstam $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.gwlcfm PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.gwlcfm +$(PROJECT_LIB)/linkcmds.phycore_mpc5554: startup/linkcmds.phycore_mpc5554 $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.phycore_mpc5554 +PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.phycore_mpc5554 + $(PROJECT_LIB)/linkcmds.mpc5566evb: startup/linkcmds.mpc5566evb $(PROJECT_LIB)/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.mpc5566evb PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.mpc5566evb diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/linkcmds.phycore_mpc5554 b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/linkcmds.phycore_mpc5554 new file mode 100644 index 0000000000..2c83736c9d --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/linkcmds.phycore_mpc5554 @@ -0,0 +1,39 @@ +/* + * Debug RAM is the top 4MB of external RAM and is swapped with the + * FLASH for development. + */ +MEMORY +{ + ROM (RX) : ORIGIN = 0x00000000, LENGTH = 2M + RAM (AIW) : ORIGIN = 0x40000000, LENGTH = 64K + RAM_EXT (AIW) : ORIGIN = 0x21000000, LENGTH = 4M + DEBUG_RAM (AIW): ORIGIN = 0x21400000, LENGTH = 4M + NIRVANA : ORIGIN = 0x00000000, LENGTH = 0 +} + +bsp_ram_start = ORIGIN (RAM); +bsp_ram_end = ORIGIN (RAM) + LENGTH (RAM); +bsp_ram_size = LENGTH (RAM); + +bsp_rom_start = ORIGIN (ROM); +bsp_rom_end = ORIGIN (ROM) + LENGTH (ROM); +bsp_rom_size = LENGTH (ROM); + +bsp_external_ram_start = ORIGIN (RAM_EXT); +bsp_external_ram_end = ORIGIN (RAM_EXT) + LENGTH (RAM_EXT); +bsp_external_ram_size = LENGTH (RAM_EXT); + +bsp_debug_ram_start = ORIGIN (DEBUG_RAM); +bsp_debug_ram_end = ORIGIN (DEBUG_RAM) + LENGTH (DEBUG_RAM); +bsp_debug_ram_size = LENGTH (DEBUG_RAM); + +bsp_section_align = 32; + +REGION_ALIAS ("REGION_TEXT", ROM); +REGION_ALIAS ("REGION_VECTORS", RAM); +REGION_ALIAS ("REGION_DATA", RAM); +REGION_ALIAS ("REGION_BSS", RAM_EXT); + +INCLUDE linkcmds.base + +bsp_workspace_start = bsp_section_bss_end; diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S index ffc36c1b07..1e26ebd1b2 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S @@ -29,6 +29,10 @@ #include <bspopts.h> .section ".bsp_start_text", "ax" +#ifdef MPC55XX_BOOTFLAGS +PUBLIC_VAR (mpc55xx_bootflag_0) +PUBLIC_VAR (mpc55xx_bootflag_1) +#endif PUBLIC_VAR (start) .globl fmpll_syncr_vals bam_rchw: @@ -39,8 +43,27 @@ bam_rchw: /* BAM: RCHW */ .int 0x005a0000 - /* BAM: Address of start instruction */ - .int 0x8 +#ifdef MPC55XX_BOOTFLAGS + /* BAM: Address of start instruction + * We skip over the next two boot flag words to the next + * 64-bit aligned start address. It is 64-bit aligned + * to play well with FLASH programming. + * These boot flags can be set by debuggers and emulators to + * customize boot. + * Currently bit0 of bootflag_0 means to "skip setting up the MMU", + * allowing external MMU setup in a debugger before branching + * to 0x10. This can be used e.g., to map FLASH into RAM. + */ + .int 0x00000010 /* Start address is 0x10. */ + +mpc55xx_bootflag_0: + .int 0xffffffff +mpc55xx_bootflag_1: + .int 0xffffffff + +#else + .int 0x00000008 /* Start address is 0x08. */ +#endif /* * Enable time base @@ -97,6 +120,8 @@ start: .equ MAS2, 626 .equ MAS3, 627 +/* Read back MMU TLB1 entry 3 (internal SRAM) and enable the cache. + */ LWI r3, 0x10030000 mtspr MAS0, r3 tlbre @@ -110,17 +135,32 @@ start: * TODO, FIXME: Set MMU for the external SRAM */ +/* Read back MMU TLB1 entry 2 (external SRAM) and set the + * logical address to the external RAM start. + */ LWI r3, 0x10020000 mtspr MAS0, r3 tlbre LWI r4, 0xfff mfspr r3, MAS3 and r3, r3, r4 - LWI r4, 0x20000000 + LA r4, bsp_external_ram_start or r3, r3, r4 mtspr MAS3, r3 tlbwe +/* Read back MMU TLB1 entry 1 (internal flash) and disable + * write access. + */ + LWI r3, 0x10010000 + mtspr MAS0, r3 + tlbre + LWI r4, ~0x0000000C + mfspr r3, MAS3 + and r3, r3, r4 + mtspr MAS3, r3 + tlbwe + /* * Zero RAM (needed to get proper ECC) */ |