Files
FireBee_SVN/sys/sysinit.c
Markus Fröschle 2f311aedbf modified dbg() macro
corrected irq6 handler
reimplemented MFP interrupt LED blinker in C
2014-05-10 13:21:11 +00:00

1156 lines
32 KiB
C

/*
* File: sysinit.c
* Purpose: Power-on Reset configuration of the Firebee board.
*
* Notes:
*
* This file is part of BaS_gcc.
*
* BaS_gcc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BaS_gcc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2010 - 2012 F. Aschwanden
* Copyright 2011 - 2012 V. Riviere
* Copyright 2012 M. Froeschle
*
*/
#include <stdbool.h>
#include "MCF5475.h"
#include "startcf.h"
#include "cache.h"
#include "sysinit.h"
#include "pci.h"
#include "bas_printf.h"
#include "bas_string.h"
#include "bas_types.h"
#include "wait.h"
#include "util.h"
#include "version.h"
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#endif /* MACHINE_M5484LITE */
#
#include "dma.h"
#include "mod_devicetable.h"
#include "pci_ids.h"
#include "driver_mem.h"
#include "usb.h"
#include "video.h"
#define UNUSED(x) (void)(x) /* Unused variable */
extern volatile long _VRAM; /* start address of video ram from linker script */
/*
* init SLICE TIMER 0
* all = 32.538 sec = 30.736mHz
* BYT0 = 127.1ms/tick = 7.876Hz offset 0
* BYT1 = 496.5us/tick = 2.014kHz offset 1
* BYT2 = 1.939us/tick = 515.6kHz offset 2
* BYT3 = 7.576ns/tick = 132.00MHz offset 3
* count down!!! 132MHz!!!
*/
void init_slt(void)
{
xprintf("slice timer initialization: ");
MCF_SLT0_STCNT = 0xffffffff;
MCF_SLT0_SCR = MCF_SLT_SCR_TEN | MCF_SLT_SCR_RUN; /* enable and run continuously */
xprintf("finished\r\n");
}
/*
* init GPIO general purpose I/O module
*/
void init_gpio(void)
{
/*
* pad register P.S.:FBCTL and FBCS set correctly at reset
*/
/*
* configure all four 547x GPIO module DMA pins:
*
* /DACK1 - DMA acknowledge 1
* /DACK0 - DMA acknowledge 0
* /DREQ1 - DMA request 1
* /DREQ0 - DMA request 0
*
* for DMA operation
*/
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0x3) |
MCF_PAD_PAR_DMA_PAR_DACK1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ0(0x3);
/*
* configure FEC0 pin assignment on GPIO module as FEC0
* configure FEC1 pin assignment (PAR_E17, PAR_E1MII) as GPIO,
* /IRQ5 and /IRQ6 from GPIO (needs to be disabled on EPORT module, which also can
* use those INTs).
*/
MCF_PAD_PAR_FECI2CIRQ = MCF_PAD_PAR_FECI2CIRQ_PAR_E07 |
MCF_PAD_PAR_FECI2CIRQ_PAR_E0MII |
MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDIO |
MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDC |
MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDIO_E1MDIO |
MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDC_E1MDC |
MCF_PAD_PAR_FECI2CIRQ_PAR_SDA |
MCF_PAD_PAR_FECI2CIRQ_PAR_SCL |
MCF_PAD_PAR_FECI2CIRQ_PAR_IRQ6 |
MCF_PAD_PAR_FECI2CIRQ_PAR_IRQ5;
/*
* configure PCI Grant pin assignment on GPIO module:
*
* /PCIBG4 used as FlexBus /TBST
* /PCIBG3 used as general purpose I/O
* /PCIBG2 used as /PCIBG2
* /PCIBG1 used as /PCIBG1
* /PCIBG0 used as /PCIBG0
*/
#if MACHINE_FIREBEE
MCF_PAD_PAR_PCIBG = MCF_PAD_PAR_PCIBG_PAR_PCIBG4_TBST |
MCF_PAD_PAR_PCIBG_PAR_PCIBG3_GPIO |
MCF_PAD_PAR_PCIBG_PAR_PCIBG2_PCIBG2 |
MCF_PAD_PAR_PCIBG_PAR_PCIBG1_PCIBG1 |
MCF_PAD_PAR_PCIBG_PAR_PCIBG0_PCIBG0;
#elif MACHINE_M5484LITE
MCF_PAD_PAR_PCIBG = MCF_PAD_PAR_PCIBG_PAR_PCIBG4_PCIBG4 |
MCF_PAD_PAR_PCIBG_PAR_PCIBG3_PCIBG3 |
MCF_PAD_PAR_PCIBG_PAR_PCIBG2_PCIBG2 |
MCF_PAD_PAR_PCIBG_PAR_PCIBG1_PCIBG1 |
MCF_PAD_PAR_PCIBG_PAR_PCIBG0_PCIBG0;
#endif /* MACHINE_FIREBEE */
/*
* configure PCI request pin assignment on GPIO module:
* /PCIBR4 as /IRQ4
* /PCIBR3 as GPIO (PIC)
* /PCIBR2 as /PCIBR2
* /PCIBR1 as /PCIBR1
* /PCIBR0 as /PCIBR0
*/
#if defined(MACHINE_FIREBEE)
MCF_PAD_PAR_PCIBR = MCF_PAD_PAR_PCIBR_PAR_PCIBR4_IRQ4 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR3_GPIO |
MCF_PAD_PAR_PCIBR_PAR_PCIBR2_PCIBR2 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR1_PCIBR1 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR0_PCIBR0;
#elif defined(MACHINE_M5484LITE)
MCF_PAD_PAR_PCIBR = MCF_PAD_PAR_PCIBR_PAR_PCIBR4_PCIBR4 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR3_PCIBR3 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR2_PCIBR2 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR1_PCIBR1 |
MCF_PAD_PAR_PCIBR_PAR_PCIBR0_PCIBR0;
#endif /* MACHINE_FIREBEE */
/*
* configure PSC3 pin assignment on GPIO module:
* /PSC3CTS as /PSC3PTS
* /PSC3RTS as /PSC3RTS
* PSC3RXD as PSC3RXD
* PSC3TXD as PSC3TXD
*/
MCF_PAD_PAR_PSC3 = MCF_PAD_PAR_PSC3_PAR_TXD3 | MCF_PAD_PAR_PSC3_PAR_RXD3;
/*
* Configure PSC1 pin assignment on GPIO module:
* - all pins configured for serial interface operation
*/
MCF_PAD_PAR_PSC1 = MCF_PAD_PAR_PSC1_PAR_CTS1_CTS |
MCF_PAD_PAR_PSC1_PAR_RTS1_RTS |
MCF_PAD_PAR_PSC1_PAR_RXD1 |
MCF_PAD_PAR_PSC1_PAR_TXD1;
/*
* Configure PSC0 Pin Assignment on GPIO module:
* - all pins configured for serial interface operation
*/
MCF_PAD_PAR_PSC0 = MCF_PAD_PAR_PSC0_PAR_CTS0_CTS |
MCF_PAD_PAR_PSC0_PAR_RTS0_RTS |
MCF_PAD_PAR_PSC0_PAR_RXD0 |
MCF_PAD_PAR_PSC0_PAR_TXD0;
/*
* Configure all DSPI pins on the GPIO module for there primary function
*/
MCF_PAD_PAR_DSPI = MCF_PAD_PAR_DSPI_PAR_SOUT(MCF_PAD_PAR_DSPI_PAR_SOUT_SOUT) |
MCF_PAD_PAR_DSPI_PAR_SIN(MCF_PAD_PAR_DSPI_PAR_SIN_SIN) |
MCF_PAD_PAR_DSPI_PAR_SCK(MCF_PAD_PAR_DSPI_PAR_SCK_SCK) |
MCF_PAD_PAR_DSPI_PAR_CS0(MCF_PAD_PAR_DSPI_PAR_CS0_DSPICS0) |
MCF_PAD_PAR_DSPI_PAR_CS2(MCF_PAD_PAR_DSPI_PAR_CS2_DSPICS2) |
MCF_PAD_PAR_DSPI_PAR_CS3(MCF_PAD_PAR_DSPI_PAR_CS3_DSPICS3) |
MCF_PAD_PAR_DSPI_PAR_CS5;
MCF_PAD_PAR_TIMER = MCF_PAD_PAR_TIMER_PAR_TIN3(MCF_PAD_PAR_TIMER_PAR_TIN3_IRQ3) |
MCF_PAD_PAR_TIMER_PAR_TOUT3 |
MCF_PAD_PAR_TIMER_PAR_TIN2(MCF_PAD_PAR_TIMER_PAR_TIN2_IRQ2) |
MCF_PAD_PAR_TIMER_PAR_TOUT2;
#if defined(MACHINE_FIREBEE)
/*
* Configure GPIO FEC1L port directions (needed to load FPGA configuration)
*/
MCF_GPIO_PDDR_FEC1L = 0 | /* bit 7 = input */
0 | /* bit 6 = input */
0 | /* bit 5 = input */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 | /* bit 4 = LED => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L3 | /* bit 3 = PRG_DQ0 => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L2 | /* bit 2 = FPGA_CONFIG => output */
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L1 | /* bit 1 = PRG_CLK (FPGA) => output */
0; /* bit 0 => input */
#endif /* MACHINE_FIREBEE */
}
/*
* init serial
*/
void init_serial(void)
{
/* PSC0: SER1 */
MCF_PSC0_PSCSICR = 0; /* PSC control register: select UART mode */
MCF_PSC0_PSCCSR = 0xDD; /* use TX and RX baud rate from PSC timer */
MCF_PSC0_PSCCTUR = 0x00; /* =\ */
#ifdef MACHINE_FIREBEE
MCF_PSC0_PSCCTLR = 36; /* divide sys_clk by 36 => BAUD RATE = 115200 bps */
#endif
#ifdef MACHINE_M5484LITE
MCF_PSC0_PSCCTLR = 27; /* LITE board has 100 MHz sys_clk only */
#endif
MCF_PSC0_PSCCR = 0x20; /* reset receiver and RxFIFO */
MCF_PSC0_PSCCR = 0x30; /* reset transmitter and TxFIFO */
MCF_PSC0_PSCCR = 0x40; /* reset all error status */
MCF_PSC0_PSCCR = 0x50; /* reset break change interrupt */
MCF_PSC0_PSCCR = 0x10; /* reset MR pointer */
MCF_PSC0_PSCIMR = 0x8700; /* enable input port change interrupt, enable delta break interrupt, */
/* enable receiver interrupt/request, enable transceiver interrupt/request */
MCF_PSC0_PSCACR = 0x03; /* enable state change of CTS */
MCF_PSC0_PSCMR1 = 0xb3; /* 8 bit, no parity */
MCF_PSC0_PSCMR2 = 0x07; /* 1 stop bit */
MCF_PSC0_PSCRFCR = 0x0F;
MCF_PSC0_PSCTFCR = 0x0F;
MCF_PSC0_PSCRFAR = 0x00F0;
MCF_PSC0_PSCTFAR = 0x00F0;
MCF_PSC0_PSCOPSET = 0x01;
MCF_PSC0_PSCCR = 0x05;
#ifdef MACHINE_FIREBEE /* PSC3 is not connected to anything on the LITE board */
/* PSC3: PIC */
MCF_PSC3_PSCSICR = 0; // UART
MCF_PSC3_PSCCSR = 0xDD;
MCF_PSC3_PSCCTUR = 0x00;
MCF_PSC3_PSCCTLR = 36; // BAUD RATE = 115200
MCF_PSC3_PSCCR = 0x20;
MCF_PSC3_PSCCR = 0x30;
MCF_PSC3_PSCCR = 0x40;
MCF_PSC3_PSCCR = 0x50;
MCF_PSC3_PSCCR = 0x10;
MCF_PSC3_PSCIMR = 0x0200; // receiver interrupt enable
MCF_PSC3_PSCACR = 0x03;
MCF_PSC3_PSCMR1 = 0xb3;
MCF_PSC3_PSCMR2 = 0x07;
MCF_PSC3_PSCRFCR = 0x0F;
MCF_PSC3_PSCTFCR = 0x0F;
MCF_PSC3_PSCRFAR = 0x00F0;
MCF_PSC3_PSCTFAR = 0x00F0;
MCF_PSC3_PSCOPSET = 0x01;
MCF_PSC3_PSCCR = 0x05;
#endif /* MACHINE_FIREBEE */
MCF_INTC_ICR32 = 0x3F; /* PSC3 interrupt vector. Do we need it? */
xprintf("\r\nserial interfaces initialization: finished\r\n");
}
/********************************************************************/
/* Initialize DDR DIMMs on the EVB board */
/********************************************************************/
bool init_ddram(void)
{
xprintf("SDRAM controller initialization: ");
/*
* Check to see if the SDRAM has already been initialized
* by a run control tool
*/
if (!(MCF_SDRAMC_SDCR & MCF_SDRAMC_SDCR_REF)) {
/* Basic configuration and initialization */
/*
* SB_E (Bits 9-8): 10 <=> 7.6 mA (SDCKE)
* SB_C (Bits 7-6): 10 <=> 7.6 mA (SDRAM Clocks)
* SB_A (Bits 5-4): 10 <=> 7.6 mA (RAS, CAS, SDWE, SDADDR[12:0], and SDBA)
* SB_S (Bits 3-2): 10 <=> 7.6 mA (SDRDQS)
* SB_D (Bits 1-0): 10 <=> 7.6 mA (SDRDQS)
*
* -> lowest setting the Coldfire SDRAM controller allows
*/
MCF_SDRAMC_SDRAMDS = 0x000002AA;/* SDRAMDS configuration */
#if MACHINE_FIREBEE
MCF_SDRAMC_CS0CFG = 0x0000001A; /* SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF) */
MCF_SDRAMC_CS1CFG = 0x0800001A; /* SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF) */
MCF_SDRAMC_CS2CFG = 0x1000001A; /* SDRAM CS2 configuration (128Mbytes 1000_0000 - 07FF_FFFF) */
MCF_SDRAMC_CS3CFG = 0x1800001A; /* SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF) */
/*
*
*/
MCF_SDRAMC_SDCFG1 = MCF_SDRAMC_SDCFG1_WTLAT(3) /* Write latency */
| MCF_SDRAMC_SDCFG1_REF2ACT(8) /* Refresh to Active Delay */
| MCF_SDRAMC_SDCFG1_PRE2ACT(2) /* Precharge to Active Delay */
| MCF_SDRAMC_SDCFG1_ACT2RW(2) /* Active to Read/Write Delay */
| MCF_SDRAMC_SDCFG1_RDLAT(6) /* Read CAS latency */
| MCF_SDRAMC_SDCFG1_SWT2RD(3) /* Single Write to Read/Write/Precharge delay */
| MCF_SDRAMC_SDCFG1_SRD2RW(7); /* Single Read to Read/Write/Precharge delay */
MCF_SDRAMC_SDCFG2 = MCF_SDRAMC_SDCFG2_BL(7) /* Burst Length */
| MCF_SDRAMC_SDCFG2_BRD2WT(7) /* Burst Read to Write delay */
| MCF_SDRAMC_SDCFG2_BWT2RW(6) /* Burst Write to Read/Write/Precharge delay */
| MCF_SDRAMC_SDCFG2_BRD2PRE(4); /* Burst Read to Read/Precharge delay */
MCF_SDRAMC_SDCR = MCF_SDRAMC_SDCR_IPALL /* initiate Precharge All command */
| MCF_SDRAMC_SDCR_RCNT(13) /* Refresh Count (= (x + 1) * 64 */
| MCF_SDRAMC_SDCR_MUX(1) /* Muxing control */
| MCF_SDRAMC_SDCR_DDR
| MCF_SDRAMC_SDCR_CKE
| MCF_SDRAMC_SDCR_MODE_EN;
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_CMD /* Generate an LMR/LEMR command */
| MCF_SDRAMC_SDMR_AD(0) /* Address */
| MCF_SDRAMC_SDMR_BNKAD(1); /* LEMR */
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_CMD /* Generate an LMR/LEMR command */
| MCF_SDRAMC_SDMR_AD(0x123)
| MCF_SDRAMC_SDMR_BNKAD(0); /* LMR */
MCF_SDRAMC_SDCR = 0xE10D0002; /* SDCR + IPALL */
MCF_SDRAMC_SDCR = 0xE10D0004; /* SDCR + IREF (first refresh) */
MCF_SDRAMC_SDCR = 0xE10D0004; /* SDCR + IREF (second refresh) */
MCF_SDRAMC_SDMR = 0x008D0000; /* SDMR (write to LMR) */
MCF_SDRAMC_SDCR = 0x710D0F00; /* SDCR (lock SDMR and enable refresh) */
#elif MACHINE_M5484LITE
MCF_SDRAMC_CS0CFG = 0x00000019; /* SDRAM CS0 configuration (64 Mbytes 0000_0000 - 03FF_FFFF) */
MCF_SDRAMC_CS1CFG = 0x00000000; /* SDRAM CS1 configuration - off */
MCF_SDRAMC_CS2CFG = 0x00000000; /* SDRAM CS2 configuration - off */
MCF_SDRAMC_CS3CFG = 0x00000000; /* SDRAM CS3 configuration - off */
/*
*
*/
MCF_SDRAMC_SDCFG1 = MCF_SDRAMC_SDCFG1_WTLAT(3) /* Write latency */
| MCF_SDRAMC_SDCFG1_REF2ACT(8) /* Refresh to Active Delay */
| MCF_SDRAMC_SDCFG1_PRE2ACT(2) /* Precharge to Active Delay */
| MCF_SDRAMC_SDCFG1_ACT2RW(2) /* Active to Read/Write Delay */
| MCF_SDRAMC_SDCFG1_RDLAT(6) /* Read CAS latency */
| MCF_SDRAMC_SDCFG1_SWT2RD(3) /* Single Write to Read/Write/Precharge delay */
| MCF_SDRAMC_SDCFG1_SRD2RW(7); /* Single Read to Read/Write/Precharge delay */
MCF_SDRAMC_SDCFG2 = MCF_SDRAMC_SDCFG2_BL(7) /* Burst Length */
| MCF_SDRAMC_SDCFG2_BRD2WT(7) /* Burst Read to Write delay */
| MCF_SDRAMC_SDCFG2_BWT2RW(6) /* Burst Write to Read/Write/Precharge delay */
| MCF_SDRAMC_SDCFG2_BRD2PRE(4); /* Burst Read to Read/Precharge delay */
MCF_SDRAMC_SDCR = MCF_SDRAMC_SDCR_IPALL /* initiate Precharge All command */
| MCF_SDRAMC_SDCR_RCNT(13) /* Refresh Count (= (x + 1) * 64 */
| MCF_SDRAMC_SDCR_MUX(1) /* Muxing control */
| MCF_SDRAMC_SDCR_DDR
| MCF_SDRAMC_SDCR_CKE
| MCF_SDRAMC_SDCR_MODE_EN;
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_CMD /* Generate an LMR/LEMR command */
| MCF_SDRAMC_SDMR_AD(0) /* Address */
| MCF_SDRAMC_SDMR_BNKAD(1); /* LEMR */
MCF_SDRAMC_SDMR = MCF_SDRAMC_SDMR_CMD /* Generate an LMR/LEMR command */
| MCF_SDRAMC_SDMR_AD(0x123)
| MCF_SDRAMC_SDMR_BNKAD(0); /* LMR */
MCF_SDRAMC_SDCR = 0xE10D0002; /* SDCR + IPALL */
MCF_SDRAMC_SDCR = 0xE10D0004; /* SDCR + IREF (first refresh) */
MCF_SDRAMC_SDCR = 0xE10D0004; /* SDCR + IREF (second refresh) */
MCF_SDRAMC_SDMR = 0x008D0000; /* SDMR (write to LMR) */
MCF_SDRAMC_SDCR = 0x710D0F00; /* SDCR (lock SDMR and enable refresh) */
#endif /* MACHINE_FIREBEE */
xprintf("finished\r\n");
return true;
}
else
{
xprintf("skipped. Already initialized (running from RAM)\r\n");
}
return false;
}
/*
* initialize FlexBus chip select registers
*/
void init_fbcs()
{
xprintf("FlexBus chip select registers initialization: ");
/* Flash */
MCF_FBCS0_CSAR = BOOTFLASH_BASE_ADDRESS; /* flash base address */
MCF_FBCS0_CSCR = MCF_FBCS_CSCR_PS_16 | /* 16 bit word access */
MCF_FBCS_CSCR_WS(6)| /* 6 Waitstates */
MCF_FBCS_CSCR_AA |
MCF_FBCS_CSCR_ASET(1) |
MCF_FBCS_CSCR_RDAH(1); /* chip errata SECF077 */
MCF_FBCS0_CSMR = BOOTFLASH_BAM |
MCF_FBCS_CSMR_V; /* enable */
#if MACHINE_FIREBEE /* FBC setup for FireBee */
MCF_FBCS1_CSAR = 0xFFF00000; /* ATARI I/O ADRESS */
MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
| MCF_FBCS_CSCR_AA; /* AA */
MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V;
MCF_FBCS2_CSAR = 0xF0000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
| MCF_FBCS_CSCR_AA; // AA
MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M // F000'0000-F7FF'FFFF
| MCF_FBCS_CSMR_V);
MCF_FBCS3_CSAR = 0xF8000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 // 16BIT PORT
| MCF_FBCS_CSCR_AA; // AA
MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M // F800'0000-FBFF'FFFF
| MCF_FBCS_CSMR_V);
MCF_FBCS4_CSAR = 0x40000000; // VIDEO RAM BEREICH, #FB_CS3 WIRD NICHT BENÜTZT, DECODE DIREKT AUF DEM FPGA
MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_BSTR // BURST READ ENABLE
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G // 4000'0000-7FFF'FFFF
| MCF_FBCS_CSMR_V;
#elif MACHINE_M5484LITE
/* disable other FBCS for now */
MCF_FBCS1_CSMR = 0;
MCF_FBCS2_CSMR = 0;
MCF_FBCS3_CSMR = 0;
MCF_FBCS4_CSMR = 0;
MCF_FBCS5_CSAR = MCF_FBCS_CSAR_BA(0x60000000);
MCF_FBCS5_CSCR = MCF_FBCS_CSCR_PS_16 /* CPLD access */
| MCF_FBCS_CSCR_WS(32)
| MCF_FBCS_CSCR_ASET(1)
| MCF_FBCS_CSCR_AA;
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M
| MCF_FBCS_CSMR_V;
#endif /* MACHINE_FIREBEE */
#ifndef MACHINE_M5484LITE
MCF_FBCS5_CSAR = 0x0;
MCF_FBCS5_CSCR = MCF_FBCS_CSCR_PS_8
| MCF_FBCS_CSCR_BSTR
| MCF_FBCS_CSCR_BSTW
| MCF_FBCS_CSCR_RDAH(1); /* chip errata SECF077 */
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_1G;
//| MCF_FBCS_CSMR_V;
#endif /* MACHINE_M5484LITE */
xprintf("finished\r\n");
}
void wait_pll(void)
{
int32_t trgt = MCF_SLT0_SCNT - 100000;
do
{
;
} while ((* (volatile int16_t *) 0xf0000800 < 0) && MCF_SLT0_SCNT > trgt);
}
static volatile uint8_t *pll_base = (volatile uint8_t *) 0xf0000600;
void init_pll(void)
{
xprintf("FPGA PLL initialization: ");
wait_pll();
* (volatile uint16_t *) (pll_base + 0x48) = 27; /* loopfilter r */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x08) = 1; /* charge pump 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x00) = 12; /* N counter high = 12 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x40) = 12; /* N counter low = 12 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x114) = 1; /* ck1 bypass */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x118) = 1; /* ck2 bypass */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x11c) = 1; /* ck3 bypass */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x10) = 1; /* ck0 high = 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x50) = 1; /* ck0 low = 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x144) = 1; /* M odd division */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x44) = 1; /* M low = 1 */
wait_pll();
* (volatile uint16_t *) (pll_base + 0x04) = 145; /* M high = 145 = 146 MHz */
wait_pll();
* (volatile uint8_t *) 0xf0000800 = 0; /* set */
xprintf("finished\r\n");
}
/*
* INIT VIDEO DDR RAM
*/
void init_video_ddr(void) {
xprintf("init video RAM: ");
* (volatile uint16_t *) 0xf0000400 = 0xb; /* set cke = 1, cs=1, config = 1 */
NOP();
_VRAM = 0x00050400; /* IPALL */
NOP();
_VRAM = 0x00072000; /* load EMR pll on */
NOP();
_VRAM = 0x00070122; /* load MR: reset pll, cl=2, burst=4lw */
NOP();
_VRAM = 0x00050400; /* IPALL */
NOP();
_VRAM = 0x00060000; /* auto refresh */
NOP();
_VRAM = 0x00060000; /* auto refresh */
NOP();
_VRAM = 0000070022; /* load MR dll on */
NOP();
* (uint32_t *) 0xf0000400 = 0x01070002; /* fifo on, refresh on, ddrcs und cke on, video dac on */
xprintf("finished\r\n");
}
/*
* probe for NEC compatible USB host controller and install if found
*/
void init_usb(void)
{
extern struct pci_device_id ohci_usb_pci_table[];
extern struct pci_device_id ehci_usb_pci_table[];
struct pci_device_id *board;
int32_t handle;
int usb_found = 0;
int index = 0;
xprintf("USB controller initialization:\r\n");
do
{
handle = pci_find_device(0x0000, 0xffff, index++);
if (handle > 0)
{
uint32_t id = 0;
uint32_t class = 0;
id = pci_read_config_longword(handle, PCIIDR);
class = pci_read_config_longword(handle, PCIREV);
if (PCI_CLASS_CODE(class) == PCI_CLASS_SERIAL_USB)
{
xprintf("serial USB found at bus=0x%x, dev=0x%x, fnc=0x%x (0x%x)\r\n",
PCI_BUS_FROM_HANDLE(handle),
PCI_DEVICE_FROM_HANDLE(handle),
PCI_FUNCTION_FROM_HANDLE(handle),
handle);
if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_EHCI)
{
board = ehci_usb_pci_table;
while (board->vendor)
{
if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id))
{
if (usb_init(handle, board) >= 0)
{
usb_found++;
}
}
board++;
}
}
if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_OHCI)
{
board = ohci_usb_pci_table;
while (board->vendor)
{
if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id))
{
if (usb_init(handle, board) >= 0)
usb_found++;
}
board++;
}
}
}
}
} while (handle >= 0);
xprintf("finished (found %d USB controller(s))\r\n", usb_found);
}
static bool i2c_transfer_finished(void)
{
if (MCF_I2C_I2SR & MCF_I2C_I2SR_IIF)
return true;
return false;
}
static void wait_i2c_transfer_finished(void)
{
waitfor(100000, i2c_transfer_finished); /* wait until interrupt bit has been set */
MCF_I2C_I2SR &= ~MCF_I2C_I2SR_IIF; /* clear interrupt bit (byte transfer finished */
}
static bool i2c_bus_free(void)
{
return (MCF_I2C_I2SR & MCF_I2C_I2SR_IBB);
}
/*
* TFP410 (DVI) on
*/
void dvi_on(void) {
uint8_t receivedByte;
uint8_t dummyByte; /* only used for a dummy read */
int num_tries = 0;
xprintf("DVI digital video output initialization: ");
MCF_I2C_I2FDR = 0x3c; /* divide system clock by 1280: 100kHz standard */
do {
/* disable all i2c interrupt routing targets */
MCF_I2C_I2ICR = 0x0; //~(MCF_I2C_I2ICR_IE | MCF_I2C_I2ICR_RE | MCF_I2C_I2ICR_TE | MCF_I2C_I2ICR_BNBE);
/* disable i2c, disable i2c interrupts, slave, receive, i2c = acknowledge, no repeat start */
MCF_I2C_I2CR = 0x0;
/* repeat start, transmit acknowledge */
MCF_I2C_I2CR = MCF_I2C_I2CR_RSTA | MCF_I2C_I2CR_TXAK;
receivedByte = MCF_I2C_I2DR; /* read a byte */
MCF_I2C_I2SR = 0x0; /* clear status register */
MCF_I2C_I2CR = 0x0; /* disable i2c */
MCF_I2C_I2ICR = MCF_I2C_I2ICR_IE; /* route i2c interrupts to cpu */
/* i2c enable, master mode, transmit acknowledge */
MCF_I2C_I2CR = MCF_I2C_I2CR_IEN | MCF_I2C_I2CR_MSTA | MCF_I2C_I2CR_MTX;
MCF_I2C_I2DR = 0x7a; /* send data: address of TFP410 */
wait_i2c_transfer_finished();
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) /* next try if no acknowledge */
continue;
MCF_I2C_I2DR = 0x00; /* send data: SUB ADRESS 0 */
wait_i2c_transfer_finished();
MCF_I2C_I2CR |= MCF_I2C_I2CR_RSTA; /* repeat start */
MCF_I2C_I2DR = 0x7b; /* begin read */
wait_i2c_transfer_finished();
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK) /* next try if no acknowledge */
continue;
#ifdef _NOT_USED_
MCH_I2C_I2CR &= ~MCF_I2C_I2CR_MTX; /* FIXME: not clear where this came from ... */
#endif /* _NOT_USED_ */
MCF_I2C_I2CR &= 0xef; /* ... this actually disables the I2C module... */
dummyByte = MCF_I2C_I2DR; /* dummy read */
wait_i2c_transfer_finished();
MCF_I2C_I2CR |= MCF_I2C_I2CR_TXAK; /* transmit acknowledge enable */
receivedByte = MCF_I2C_I2DR; /* read a byte */
wait_i2c_transfer_finished();
MCF_I2C_I2CR = MCF_I2C_I2CR_IEN; /* stop */
dummyByte = MCF_I2C_I2DR; // dummy read
if (receivedByte != 0x4c)
continue;
MCF_I2C_I2CR = 0x0; // stop
MCF_I2C_I2SR = 0x0; // clear sr
waitfor(10000, i2c_bus_free);
MCF_I2C_I2CR = 0xb0; // on tx master
MCF_I2C_I2DR = 0x7A;
wait_i2c_transfer_finished();
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK)
continue;
MCF_I2C_I2DR = 0x08; // SUB ADRESS 8
wait_i2c_transfer_finished();
MCF_I2C_I2DR = 0xbf; // ctl1: power on, T:M:D:S: enable
wait_i2c_transfer_finished();
MCF_I2C_I2CR = 0x80; // stop
dummyByte = MCF_I2C_I2DR; // dummy read
MCF_I2C_I2SR = 0x0; // clear sr
waitfor(10000, i2c_bus_free);
MCF_I2C_I2CR = 0xb0;
MCF_I2C_I2DR = 0x7A;
wait_i2c_transfer_finished();
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK)
continue;
MCF_I2C_I2DR = 0x08; // SUB ADRESS 8
wait_i2c_transfer_finished();
MCF_I2C_I2CR |= 0x4; // repeat start
MCF_I2C_I2DR = 0x7b; // beginn read
wait_i2c_transfer_finished();
if (MCF_I2C_I2SR & MCF_I2C_I2SR_RXAK)
continue;
MCF_I2C_I2CR &= 0xef; // switch to rx
dummyByte = MCF_I2C_I2DR; // dummy read
wait_i2c_transfer_finished();
MCF_I2C_I2CR |= 0x08; // txak=1
wait(50);
receivedByte = MCF_I2C_I2DR;
wait_i2c_transfer_finished();
MCF_I2C_I2CR = 0x80; // stop
dummyByte = MCF_I2C_I2DR; // dummy read
num_tries++;
} while ((receivedByte != 0xbf) && (num_tries < 10));
if (num_tries >= 10) {
xprintf("FAILED!\r\n");
} else {
xprintf("finished\r\n");
}
UNUSED(dummyByte);
// Avoid warning
}
/*
* AC97
*/
void init_ac97(void) {
// PSC2: AC97 ----------
int i;
int zm;
int va;
int vb;
int vc;
xprintf("AC97 sound chip initialization: ");
MCF_PAD_PAR_PSC2 = MCF_PAD_PAR_PSC2_PAR_RTS2_RTS // PSC2=TX,RX BCLK,CTS->AC'97
| MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK
| MCF_PAD_PAR_PSC2_PAR_TXD2
| MCF_PAD_PAR_PSC2_PAR_RXD2;
MCF_PSC2_PSCMR1 = 0x0;
MCF_PSC2_PSCMR2 = 0x0;
MCF_PSC2_PSCIMR = 0x0300;
MCF_PSC2_PSCSICR = 0x03; //AC97
MCF_PSC2_PSCRFCR = 0x0f000000;
MCF_PSC2_PSCTFCR = 0x0f000000;
MCF_PSC2_PSCRFAR = 0x00F0;
MCF_PSC2_PSCTFAR = 0x00F0;
for (zm = 0; zm < 100000; zm++) // wiederholen bis synchron
{
MCF_PSC2_PSCCR = 0x20;
MCF_PSC2_PSCCR = 0x30;
MCF_PSC2_PSCCR = 0x40;
MCF_PSC2_PSCCR = 0x05;
// MASTER VOLUME -0dB
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x02000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
for (i = 2; i < 13; i++)
{
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
// read register
MCF_PSC2_PSCTB_AC97 = 0xc0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x82000000; //SLOT1:master volume
for (i = 2; i < 13; i++)
{
MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT2-12:RD REG ALLES 0
}
wait(50);
va = MCF_PSC2_PSCTB_AC97;
if ((va & 0x80000fff) == 0x80000800) {
vb = MCF_PSC2_PSCTB_AC97;
vc = MCF_PSC2_PSCTB_AC97;
/* FIXME: that looks more than suspicious (Fredi?) */
/* fixed with parentheses to avoid compiler warnings, but this looks still more than wrong to me */
if (((va & 0xE0000fff) == 0xE0000800) & (vb == 0x02000000) & (vc == 0x00000000)) {
goto livo;
}
}
}
xprintf(" NOT");
livo:
// AUX VOLUME ->-0dB
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x16000000; //SLOT1:WR REG AUX VOLUME adr 0x16
MCF_PSC2_PSCTB_AC97 = 0x06060000; //SLOT1:VOLUME
for (i = 3; i < 13; i++) {
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
// line in VOLUME +12dB
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x10000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
for (i = 2; i < 13; i++) {
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
// cd in VOLUME 0dB
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x12000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
for (i = 2; i < 13; i++) {
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
// mono out VOLUME 0dB
MCF_PSC2_PSCTB_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x06000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT1:WR REG MASTER VOLUME adr 0x02
for (i = 3; i < 13; i++) {
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
MCF_PSC2_PSCTFCR |= MCF_PSC_PSCTFCR_WFR; //set EOF
MCF_PSC2_PSCTB_AC97 = 0x00000000; //last data
xprintf(" finished\r\n");
}
/* Symbols from the linker script */
extern uint8_t _STRAM_END[];
#define STRAM_END ((uint32_t)_STRAM_END)
extern uint8_t _FIRETOS[];
#define FIRETOS ((uint32_t)_FIRETOS) /* where FireTOS is stored in flash */
extern uint8_t _BAS_LMA[];
#define BAS_LMA (&_BAS_LMA[0]) /* where the BaS is stored in flash */
extern uint8_t _BAS_IN_RAM[];
#define BAS_IN_RAM (&_BAS_IN_RAM[0]) /* where the BaS is run in RAM */
extern uint8_t _BAS_SIZE[];
#define BAS_SIZE ((uint32_t)_BAS_SIZE) /* size of the BaS, in bytes */
extern uint8_t _FASTRAM_END[];
#define FASTRAM_END ((uint32_t)_FASTRAM_END)
extern uint8_t _BAS_RESIDENT_TEXT[];
#define BAS_RESIDENT_TEXT ((uint32_t) _BAS_RESIDENT_TEXT)
extern uint8_t _BAS_RESIDENT_TEXT_SIZE[];
#define BAS_RESIDENT_TEXT_SIZE ((uint32_t) _BAS_RESIDENT_TEXT_SIZE)
void clear_bss_segment(void)
{
extern uint8_t _BAS_BSS_START[];
uint8_t * BAS_BSS_START = &_BAS_BSS_START[0];
extern uint8_t _BAS_BSS_END[];
uint8_t *BAS_BSS_END = &_BAS_BSS_END[0];
bzero(BAS_BSS_START, BAS_BSS_END - BAS_BSS_START - 1);
}
void initialize_hardware(void)
{
bool coldboot = true;
/* Test for FireTOS switch: DIP switch #5 up */
#ifdef MACHINE_FIREBEE
if (!(DIP_SWITCH & (1 << 6))) {
/* Minimal hardware initialization */
init_gpio();
init_serial();
init_slt();
init_fbcs();
init_ddram();
init_fpga();
/* Validate ST RAM */
* (volatile uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */
* (volatile uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */
* (volatile uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
* (volatile uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
/* TT-RAM */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
/* Jump into FireTOS */
typedef void void_func(void);
void_func* FireTOS = (void_func*) FIRETOS;
FireTOS(); // Should never return
return;
}
#endif /* MACHINE_FIREBEE */
init_gpio();
init_serial();
xprintf("\n\n");
xprintf("%s BASIS system (BaS) v %d.%d (%s, %s)\r\n\r\n",
#if MACHINE_FIREBEE
"Firebee"
#elif MACHINE_M5484LITE
"m5484 LITEKIT"
#else
"unknown platform"
#endif
, MAJOR_VERSION, MINOR_VERSION, __DATE__, __TIME__);
/*
* Determine cause(s) of Reset
*/
if (MCF_SIU_RSR & MCF_SIU_RSR_RST)
xprintf("Reset. Cause: External Reset\r\n");
if (MCF_SIU_RSR & MCF_SIU_RSR_RSTWD)
xprintf("Reset. Cause: Watchdog Timer Reset\n");
if (MCF_SIU_RSR & MCF_SIU_RSR_RSTJTG)
xprintf("Reset. Cause: BDM/JTAG Reset\r\n");
/*
* Clear the Reset Status Register
*/
MCF_SIU_RSR = (MCF_SIU_RSR_RST
| MCF_SIU_RSR_RSTWD
| MCF_SIU_RSR_RSTJTG);
/*
* Determine which processor we are running on
*/
xprintf("JTAGID: ");
switch (MCF_SIU_JTAGID & MCF_SIU_JTAGID_PROCESSOR)
{
case MCF_SIU_JTAGID_MCF5485:
xprintf("MCF5485");
break;
case MCF_SIU_JTAGID_MCF5484:
xprintf("MCF5484");
break;
case MCF_SIU_JTAGID_MCF5483:
xprintf("MCF5483");
break;
case MCF_SIU_JTAGID_MCF5482:
xprintf("MCF5482");
break;
case MCF_SIU_JTAGID_MCF5481:
xprintf("MCF5481");
break;
case MCF_SIU_JTAGID_MCF5480:
xprintf("MCF5480");
break;
case MCF_SIU_JTAGID_MCF5475:
xprintf("MCF5475");
break;
case MCF_SIU_JTAGID_MCF5474:
xprintf("MCF5474");
break;
case MCF_SIU_JTAGID_MCF5473:
xprintf("MCF5473");
break;
case MCF_SIU_JTAGID_MCF5472:
xprintf("MCF5472");
break;
case MCF_SIU_JTAGID_MCF5471:
xprintf("MCF5471");
break;
case MCF_SIU_JTAGID_MCF5470:
xprintf("MCF5470");
break;
}
/* make sure MMU is disabled */
MCF_MMU_MMUCR = 0; /* MMU off */
NOP(); /* force pipeline sync */
/*
* Determine the processor revision
*/
xprintf(" (revision %d)\r\n", ((MCF_SIU_JTAGID & MCF_SIU_JTAGID_REV) >> 28));
init_slt();
init_fbcs();
coldboot = init_ddram();
/*
* install (preliminary) exception vectors
*/
setup_vectors();
#ifdef _NOT_USED_
/* make sure the handlers are called */
__asm__ __volatile__("dc.w 0xafff"); /* should trigger a line-A exception */
#endif /* _NOT_USED_ */
/*
* save the planet (and reduce case heat): disable clocks of unused SOC modules
*/
MCF_CLOCK_SPCR = 0xffffffff & ~(
0 | /* leave memory clock enabled */
0 | /* leave PCI clock enabled */
0 | /* leave FlexBus clock enabled */
MCF_CLOCK_SPCR_CAN0EN | /* disable CAN0 */
0 | /* leave DMA clock enabled */
0 | /* leave FEC0 clock enabled */
MCF_CLOCK_SPCR_FEC1EN | /* disable FEC1 */
MCF_CLOCK_SPCR_USBEN | /* disable USB slave */
0 | /* leave PSC clock enabled */
MCF_CLOCK_SPCR_CAN1EN | /* disable CAN1 */
MCF_CLOCK_SPCR_CRYENA | /* disable crypto clock A */
MCF_CLOCK_SPCR_CRYENB | /* disable crypto clock B */
0 /* leave core clock enabled */
);
/* the following only makes sense _after_ DDRAM has been initialized */
clear_bss_segment();
if (BAS_LMA != BAS_IN_RAM)
{
memcpy((void *) BAS_IN_RAM, BAS_LMA, BAS_SIZE);
/* we have copied a code area, so flush the caches */
flush_and_invalidate_caches();
}
#if MACHINE_FIREBEE
if (coldboot) /* does not work with BDM */
;
init_fpga();
init_pll();
init_video_ddr();
dvi_on();
#ifdef _NOT_USED_
/* experimental */
{
int i;
uint32_t *scradr = (uint32_t *) 0xd00000;
for (i = 0; i < 100; i++)
{
uint32_t *p = scradr;
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0xffffffff;
}
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0x0;
}
}
}
#endif /* _NOT_USED_ */
#endif /* MACHINE_FIREBEE */
driver_mem_init();
init_pci();
video_init();
/* do not try to init USB for now on the Firebee, it hangs the machine */
#ifndef MACHINE_FIREBEE
//init_usb();
#endif
#if MACHINE_FIREBEE
init_ac97();
#endif /* MACHINE_FIREBEE */
dma_init();
/* jump into the BaS */
extern void BaS(void);
BaS();
}