9
0
Fork 0
barebox/arch/m68k/cpu/cpu.c

186 lines
3.9 KiB
C

/*
* Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
* See file CREDITS for list of people who contributed to this project.
*
* This file is part of barebox.
*
* barebox 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.
*
* barebox 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 barebox. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file
* A few helper functions for M6kK/Coldfire
*/
#include <common.h>
#include <command.h>
#include <init.h>
#include <proc/processor.h> // FIXME -stup place
#include <mach/mcf54xx-regs.h>
static uint32_t CACR_shadow = MCF5XXX_CACR_BEC;
/*
* Reset init value := 0x010C0100
* MCF5XXX_CACR_DCINVA
* MCF5XXX_CACR_BEC
* MCF5XXX_CACR_BCINVA
* MCF5XXX_CACR_ICINVA
*/
/**
* Enable processor's instruction cache
*/
void icache_enable (void)
{
CACR_shadow |= MCF5XXX_CACR_IEC;
mcf5xxx_wr_cacr( CACR_shadow );
}
/**
* Disable processor's instruction cache
*/
void icache_disable (void)
{
CACR_shadow &= ~MCF5XXX_CACR_IEC;
mcf5xxx_wr_cacr( CACR_shadow );
}
/**
* Detect processor's current instruction cache status
* @return 0=disabled, 1=enabled
*/
int icache_status (void)
{
return (CACR_shadow & MCF5XXX_CACR_IEC)?1:0;
}
/**
* Enable processor's data cache
*/
void dcache_enable (void)
{
CACR_shadow |= MCF5XXX_CACR_DEC;
mcf5xxx_wr_cacr( CACR_shadow );
}
/**
* Disable processor's data cache
*/
void dcache_disable (void)
{
CACR_shadow &= ~MCF5XXX_CACR_DEC;
mcf5xxx_wr_cacr( CACR_shadow );
}
/**
* Detect processor's current instruction cache status
* @return 0=disabled, 1=enabled
*/
int dcache_status (void)
{
return (CACR_shadow & MCF5XXX_CACR_DEC)?1:0;
}
/**
* Flush CPU caches to memory
*/
void cpu_cache_flush(void)
{
uint32_t way, set;
void *addr;
for ( way=0; way < 4; way++ ) {
addr = (void*)way;
for ( set=0; set < 512; set++ ) {
mcf5xxx_cpushl_bc ( addr );
addr += 0x10;
}
}
}
/**
* Flush CPU caches to memory and disable them.
*/
void cpu_cache_disable(void)
{
uint32_t lastipl;
lastipl = asm_set_ipl( 7 );
cpu_cache_flush();
mcf5xxx_wr_acr0( 0 );
mcf5xxx_wr_acr1( 0 );
mcf5xxx_wr_acr2( 0 );
mcf5xxx_wr_acr3( 0 );
CACR_shadow &= ~MCF5XXX_CACR_IEC;
CACR_shadow &= ~MCF5XXX_CACR_DEC;
mcf5xxx_wr_cacr( CACR_shadow | (MCF5XXX_CACR_DCINVA|MCF5XXX_CACR_ICINVA));
lastipl = asm_set_ipl( lastipl );
}
/**
* Prepare a "clean" CPU for Linux to run
* @return 0 (always)
*
* This function is called by the generic barebox part just before we call
* Linux. It prepares the processor for Linux.
*/
int cleanup_before_linux (void)
{
/*
* we never enable dcache so we do not need to disable
* it. Linux can be called with icache enabled, so just
* do nothing here
*/
/* flush I/D-cache */
cpu_cache_disable();
/* reenable icache */
icache_enable();
return (0);
}
/** @page m68k_boot_preparation Linux Preparation on M68k/Coldfire
*
* For M68K we never enable data cache so we do not need to disable it again.
*
* Linux can be called with instruction cache enabled. As this is the
* default setting we are running in barebox, there's no special preparation
* required.
*/
/** Early init of Coldfire V4E CPU
*/
static int cpu_init (void)
{
/* Enable ICache - branch cache is already on */
icache_enable();
/*
* setup up stacks if necessary
* setup other CPU specifics here to prepare
* handling of exceptions and interrupts
*/
#ifdef CONFIG_USE_IRQ
printf("Prepare CPU interrupts for handlers\n");
mcf_interrupts_initialize();
#endif
return 0;
}
core_initcall(cpu_init);