Merge branch 'master' of git://git.denx.de/u-boot-arm

This commit is contained in:
Minkyu Kang
2009-10-12 14:40:42 +09:00
69 changed files with 4987 additions and 2074 deletions

View File

@@ -31,14 +31,15 @@ COBJS += bcm5221.o
COBJS += dm9161.o
COBJS += ether.o
COBJS += i2c.o
COBJS-$(CONFIG_KS8721_PHY) += ks8721.o
COBJS += lxt972.o
COBJS += reset.o
COBJS += spi.o
COBJS += timer.o
COBJS += usb.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y))
all: $(obj).depend $(LIB)

View File

@@ -0,0 +1,249 @@
/*
* (C) Copyright 2006
* Author : Eric Benard (Eukrea Electromatique)
* based on dm9161.c which is :
* (C) Copyright 2003
* Author : Hamid Ikdoumi (Atmel)
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program 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 2 of
* the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <at91rm9200_net.h>
#include <net.h>
#include <ks8721.h>
#ifdef CONFIG_DRIVER_ETHER
#if defined(CONFIG_CMD_NET)
/*
* Name:
* ks8721_isphyconnected
* Description:
* Reads the 2 PHY ID registers
* Arguments:
* p_mac - pointer to AT91S_EMAC struct
* Return value:
* 1 - if id read successfully
* 0 - if error
*/
unsigned int ks8721_isphyconnected(AT91PS_EMAC p_mac)
{
unsigned short id1, id2;
at91rm9200_EmacEnableMDIO(p_mac);
at91rm9200_EmacReadPhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_PHYID1, &id1);
at91rm9200_EmacReadPhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_PHYID2, &id2);
at91rm9200_EmacDisableMDIO(p_mac);
if ((id1 == (KS8721_PHYID_OUI >> 6)) &&
((id2 >> 10) == (KS8721_PHYID_OUI & KS8721_LSB_MASK))) {
if ((id2 & KS8721_MODELMASK) == KS8721BL_MODEL)
printf("Micrel KS8721bL PHY detected : ");
else
printf("Unknown Micrel PHY detected : ");
return 1;
}
return 0;
}
/*
* Name:
* ks8721_getlinkspeed
* Description:
* Link parallel detection status of MAC is checked and set in the
* MAC configuration registers
* Arguments:
* p_mac - pointer to MAC
* Return value:
* 1 - if link status set succesfully
* 0 - if link status not set
*/
unsigned char ks8721_getlinkspeed(AT91PS_EMAC p_mac)
{
unsigned short stat1;
if (!at91rm9200_EmacReadPhy(p_mac, KS8721_BMSR, &stat1))
return 0;
if (!(stat1 & KS8721_LINK_STATUS)) {
/* link status up? */
printf("Link Down !\n");
return 0;
}
if (stat1 & KS8721_100BASE_TX_FD) {
/* set Emac for 100BaseTX and Full Duplex */
printf("100BT FD\n");
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
return 1;
}
if (stat1 & KS8721_10BASE_T_FD) {
/* set MII for 10BaseT and Full Duplex */
printf("10BT FD\n");
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
| AT91C_EMAC_FD;
return 1;
}
if (stat1 & KS8721_100BASE_T4_HD) {
/* set MII for 100BaseTX and Half Duplex */
printf("100BT HD\n");
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
| AT91C_EMAC_SPD;
return 1;
}
if (stat1 & KS8721_10BASE_T_HD) {
/* set MII for 10BaseT and Half Duplex */
printf("10BT HD\n");
p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
return 1;
}
return 0;
}
/*
* Name:
* ks8721_initphy
* Description:
* MAC starts checking its link by using parallel detection and
* Autonegotiation and the same is set in the MAC configuration registers
* Arguments:
* p_mac - pointer to struct AT91S_EMAC
* Return value:
* 1 - if link status set succesfully
* 0 - if link status not set
*/
unsigned char ks8721_initphy(AT91PS_EMAC p_mac)
{
unsigned char ret = 1;
unsigned short intvalue;
at91rm9200_EmacEnableMDIO(p_mac);
/* Try another time */
if (!ks8721_getlinkspeed(p_mac))
ret = ks8721_getlinkspeed(p_mac);
/* Disable PHY Interrupts */
intvalue = 0;
at91rm9200_EmacWritePhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_MDINTR, &intvalue);
at91rm9200_EmacDisableMDIO(p_mac);
return ret;
}
/*
* Name:
* ks8721_autonegotiate
* Description:
* MAC Autonegotiates with the partner status of same is set in the
* MAC configuration registers
* Arguments:
* dev - pointer to struct net_device
* Return value:
* 1 - if link status set successfully
* 0 - if link status not set
*/
unsigned char ks8721_autonegotiate(AT91PS_EMAC p_mac, int *status)
{
unsigned short value;
unsigned short phyanar;
unsigned short phyanalpar;
/* Set ks8721 control register */
if (!at91rm9200_EmacReadPhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_BMCR, &value))
return 0;
/* remove autonegotiation enable */
value &= ~KS8721_AUTONEG;
/* Electrically isolate PHY */
value |= KS8721_ISOLATE;
if (!at91rm9200_EmacWritePhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) {
return 0;
}
/*
* Set the Auto_negotiation Advertisement Register
* MII advertising for Next page, 100BaseTxFD and HD,
* 10BaseTFD and HD, IEEE 802.3
*/
phyanar = KS8721_NP | KS8721_TX_FDX | KS8721_TX_HDX |
KS8721_10_FDX | KS8721_10_HDX | KS8721_AN_IEEE_802_3;
if (!at91rm9200_EmacWritePhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_ANAR, &phyanar)) {
return 0;
}
/* Read the Control Register */
if (!at91rm9200_EmacReadPhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) {
return 0;
}
value |= KS8721_SPEED_SELECT | KS8721_AUTONEG | KS8721_DUPLEX_MODE;
if (!at91rm9200_EmacWritePhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) {
return 0;
}
/* Restart Auto_negotiation */
value |= KS8721_RESTART_AUTONEG;
value &= ~KS8721_ISOLATE;
if (!at91rm9200_EmacWritePhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_BMCR, &value)) {
return 0;
}
/* Check AutoNegotiate complete */
udelay(10000);
at91rm9200_EmacReadPhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_BMSR, &value);
if (!(value & KS8721_AUTONEG_COMP))
return 0;
/* Get the AutoNeg Link partner base page */
if (!at91rm9200_EmacReadPhy(p_mac,
CONFIG_PHY_ADDRESS | KS8721_ANLPAR, &phyanalpar)) {
return 0;
}
if ((phyanar & KS8721_TX_FDX) && (phyanalpar & KS8721_TX_FDX)) {
/* Set MII for 100BaseTX and Full Duplex */
p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
return 1;
}
if ((phyanar & KS8721_10_FDX) && (phyanalpar & KS8721_10_FDX)) {
/* Set MII for 10BaseT and Full Duplex */
p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
| AT91C_EMAC_FD;
return 1;
}
return 0;
}
#endif /* CONFIG_CMD_NET */
#endif /* CONFIG_DRIVER_ETHER */

View File

@@ -194,7 +194,8 @@ SMRDATA:
.word CONFIG_SYS_PIOD_PPUDR_VAL
.word (AT91_BASE_SYS + AT91_PIOD + PIO_ASR)
.word CONFIG_SYS_PIOD_PPUDR_VAL
#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261)
#elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) \
|| defined(CONFIG_AT91SAM9G20)
.word (AT91_BASE_SYS + AT91_PIOC + PIO_PDR)
.word CONFIG_SYS_PIOC_PDR_VAL1
.word (AT91_BASE_SYS + AT91_PIOC + PIO_PUDR)

View File

@@ -31,6 +31,7 @@ COBJS-y += cpu.o timer.o psc.o
COBJS-$(CONFIG_SOC_DM355) += dm355.o
COBJS-$(CONFIG_SOC_DM365) += dm365.o
COBJS-$(CONFIG_SOC_DM644X) += dm644x.o
COBJS-$(CONFIG_SOC_DM646X) += dm646x.o
COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o
SOBJS = reset.o

View File

@@ -0,0 +1,41 @@
/*
* SoC-specific code for TMS320DM646x chips
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <asm/arch/hardware.h>
void davinci_enable_uart0(void)
{
lpsc_on(DAVINCI_DM646X_LPSC_UART0);
}
#ifdef CONFIG_DRIVER_TI_EMAC
void davinci_enable_emac(void)
{
lpsc_on(DAVINCI_DM646X_LPSC_EMAC);
}
#endif
#ifdef CONFIG_DRIVER_DAVINCI_I2C
void davinci_enable_i2c(void)
{
lpsc_on(DAVINCI_DM646X_LPSC_I2C);
}
#endif

View File

@@ -27,6 +27,7 @@
#include <asm/cache.h>
#include <u-boot/md5.h>
#include <asm/arch/kirkwood.h>
#include <hush.h>
#define BUFLEN 16

View File

@@ -64,7 +64,7 @@ int cleanup_before_linux(void)
/* turn off L2 cache */
l2_cache_disable();
/* invalidate L2 cache also */
v7_flush_dcache_all(get_device_type());
invalidate_dcache(get_device_type());
#endif
i = 0;
/* mem barrier to sync up things */

View File

@@ -26,10 +26,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
SOBJS := lowlevel_init.o
SOBJS += cache.o
SOBJS += reset.o
COBJS += board.o
COBJS += cache.o
COBJS += clock.o
COBJS += gpio.o
COBJS += mem.o

View File

@@ -201,7 +201,7 @@ void s_init(void)
* Right now flushing at low MPU speed.
* Need to move after clock init
*/
v7_flush_dcache_all(get_device_type());
invalidate_dcache(get_device_type());
#ifndef CONFIG_ICACHE_OFF
icache_enable();
#endif

View File

@@ -0,0 +1,191 @@
/*
* Copyright (c) 2009 Wind River Systems, Inc.
* Tom Rix <Tom.Rix@windriver.com>
*
* This file is based on and replaces the existing cache.c file
* The copyrights for the cache.c file are:
*
* (C) Copyright 2008 Texas Insturments
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program 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 2 of
* the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <asm/arch/omap3.h>
/*
* omap3 cache code
*/
.align 5
.global invalidate_dcache
.global l2_cache_enable
.global l2_cache_disable
/*
* invalidate_dcache()
*
* Invalidate the whole D-cache.
*
* Corrupted registers: r0-r5, r7, r9-r11
*
* - mm - mm_struct describing address space
*/
invalidate_dcache:
stmfd r13!, {r0 - r5, r7, r9 - r12, r14}
mov r7, r0 @ take a backup of device type
cmp r0, #0x3 @ check if the device type is
@ GP
moveq r12, #0x1 @ set up to invalide L2
smi: .word 0x01600070 @ Call SMI monitor (smieq)
cmp r7, #0x3 @ compare again in case its
@ lost
beq finished_inval @ if GP device, inval done
@ above
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq finished_inval @ if loc is 0, then no need to
@ clean
mov r10, #0 @ start clean at cache level 0
inval_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache
@ level
mov r1, r0, lsr r2 @ extract cache type bits from
@ clidr
and r1, r1, #7 @ mask of the bits for current
@ cache only
cmp r1, #2 @ see what cache we have at
@ this level
blt skip_inval @ skip if no cache, or just
@ i-cache
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
@ in cssr
mov r2, #0 @ operand for mcr SBZ
mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to
@ sych the new cssr&csidr,
@ with armv7 this is 'isb',
@ but we compile with armv5
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the
@ cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the
@ way size
clz r5, r4 @ find bit position of way
@ size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the
@ index size
inval_loop2:
mov r9, r4 @ create working copy of max
@ way size
inval_loop3:
orr r11, r10, r9, lsl r5 @ factor way and cache number
@ into r11
orr r11, r11, r7, lsl r2 @ factor index number into r11
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge inval_loop3
subs r7, r7, #1 @ decrement the index
bge inval_loop2
skip_inval:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt inval_loop1
finished_inval:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
@ in cssr
mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer,
@ with armv7 this is 'isb',
@ but we compile with armv5
ldmfd r13!, {r0 - r5, r7, r9 - r12, pc}
l2_cache_enable:
push {r0, r1, r2, lr}
@ ES2 onwards we can disable/enable L2 ourselves
bl get_cpu_rev
cmp r0, #CPU_3XX_ES20
blt l2_cache_disable_EARLIER_THAN_ES2
mrc 15, 0, r3, cr1, cr0, 1
orr r3, r3, #2
mcr 15, 0, r3, cr1, cr0, 1
b l2_cache_enable_END
l2_cache_enable_EARLIER_THAN_ES2:
@ Save r0, r12 and restore them after usage
mov r3, ip
str r3, [sp, #4]
mov r3, r0
@
@ GP Device ROM code API usage here
@ r12 = AUXCR Write function and r0 value
@
mov ip, #3
mrc 15, 0, r0, cr1, cr0, 1
orr r0, r0, #2
@ SMI instruction to call ROM Code API
.word 0xe1600070
mov r0, r3
mov ip, r3
str r3, [sp, #4]
l2_cache_enable_END:
pop {r1, r2, r3, pc}
l2_cache_disable:
push {r0, r1, r2, lr}
@ ES2 onwards we can disable/enable L2 ourselves
bl get_cpu_rev
cmp r0, #CPU_3XX_ES20
blt l2_cache_disable_EARLIER_THAN_ES2
mrc 15, 0, r3, cr1, cr0, 1
bic r3, r3, #2
mcr 15, 0, r3, cr1, cr0, 1
b l2_cache_disable_END
l2_cache_disable_EARLIER_THAN_ES2:
@ Save r0, r12 and restore them after usage
mov r3, ip
str r3, [sp, #4]
mov r3, r0
@
@ GP Device ROM code API usage here
@ r12 = AUXCR Write function and r0 value
@
mov ip, #3
mrc 15, 0, r0, cr1, cr0, 1
bic r0, r0, #2
@ SMI instruction to call ROM Code API
.word 0xe1600070
mov r0, r3
mov ip, r3
str r3, [sp, #4]
l2_cache_disable_END:
pop {r1, r2, r3, pc}

View File

@@ -1,95 +0,0 @@
/*
* (C) Copyright 2008 Texas Insturments
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program 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 2 of
* the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* omap3 L2 cache code
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
#include <asm/cache.h>
void l2_cache_enable(void)
{
unsigned long i;
volatile unsigned int j;
/* ES2 onwards we can disable/enable L2 ourselves */
if (get_cpu_rev() >= CPU_3XX_ES20) {
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
__asm__ __volatile__("orr %0, %0, #0x2":"=r"(i));
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
} else {
/* Save r0, r12 and restore them after usage */
__asm__ __volatile__("mov %0, r12":"=r"(j));
__asm__ __volatile__("mov %0, r0":"=r"(i));
/*
* GP Device ROM code API usage here
* r12 = AUXCR Write function and r0 value
*/
__asm__ __volatile__("mov r12, #0x3");
__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
__asm__ __volatile__("orr r0, r0, #0x2");
/* SMI instruction to call ROM Code API */
__asm__ __volatile__(".word 0xE1600070");
__asm__ __volatile__("mov r0, %0":"=r"(i));
__asm__ __volatile__("mov r12, %0":"=r"(j));
}
}
void l2_cache_disable(void)
{
unsigned long i;
volatile unsigned int j;
/* ES2 onwards we can disable/enable L2 ourselves */
if (get_cpu_rev() >= CPU_3XX_ES20) {
__asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
__asm__ __volatile__("bic %0, %0, #0x2":"=r"(i));
__asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
} else {
/* Save r0, r12 and restore them after usage */
__asm__ __volatile__("mov %0, r12":"=r"(j));
__asm__ __volatile__("mov %0, r0":"=r"(i));
/*
* GP Device ROM code API usage here
* r12 = AUXCR Write function and r0 value
*/
__asm__ __volatile__("mov r12, #0x3");
__asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
__asm__ __volatile__("bic r0, r0, #0x2");
/* SMI instruction to call ROM Code API */
__asm__ __volatile__(".word 0xE1600070");
__asm__ __volatile__("mov r0, %0":"=r"(i));
__asm__ __volatile__("mov r12, %0":"=r"(j));
}
}

View File

@@ -415,88 +415,3 @@ fiq:
#endif
/*
* v7_flush_dcache_all()
*
* Flush the whole D-cache.
*
* Corrupted registers: r0-r5, r7, r9-r11
*
* - mm - mm_struct describing address space
*/
.align 5
.global v7_flush_dcache_all
v7_flush_dcache_all:
stmfd r13!, {r0 - r5, r7, r9 - r12, r14}
mov r7, r0 @ take a backup of device type
cmp r0, #0x3 @ check if the device type is
@ GP
moveq r12, #0x1 @ set up to invalide L2
smi: .word 0x01600070 @ Call SMI monitor (smieq)
cmp r7, #0x3 @ compare again in case its
@ lost
beq finished_inval @ if GP device, inval done
@ above
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq finished_inval @ if loc is 0, then no need to
@ clean
mov r10, #0 @ start clean at cache level 0
inval_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache
@ level
mov r1, r0, lsr r2 @ extract cache type bits from
@ clidr
and r1, r1, #7 @ mask of the bits for current
@ cache only
cmp r1, #2 @ see what cache we have at
@ this level
blt skip_inval @ skip if no cache, or just
@ i-cache
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
@ in cssr
mov r2, #0 @ operand for mcr SBZ
mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to
@ sych the new cssr&csidr,
@ with armv7 this is 'isb',
@ but we compile with armv5
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the
@ cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the
@ way size
clz r5, r4 @ find bit position of way
@ size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the
@ index size
inval_loop2:
mov r9, r4 @ create working copy of max
@ way size
inval_loop3:
orr r11, r10, r9, lsl r5 @ factor way and cache number
@ into r11
orr r11, r11, r7, lsl r2 @ factor index number into r11
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge inval_loop3
subs r7, r7, #1 @ decrement the index
bge inval_loop2
skip_inval:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt inval_loop1
finished_inval:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level
@ in cssr
mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer,
@ with armv7 this is 'isb',
@ but we compile with armv5
ldmfd r13!, {r0 - r5, r7, r9 - r12, pc}