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

This commit is contained in:
Tom Rini 2015-01-30 13:56:15 -05:00
commit a0573d1988
28 changed files with 304 additions and 913 deletions

View File

@ -36,6 +36,7 @@ config TARGET_VCT
select SUPPORTS_BIG_ENDIAN select SUPPORTS_BIG_ENDIAN
select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R2
select SYS_MIPS_CACHE_INIT_RAM_LOAD
config TARGET_DBAU1X00 config TARGET_DBAU1X00
bool "Support dbau1x00" bool "Support dbau1x00"
@ -43,12 +44,14 @@ config TARGET_DBAU1X00
select SUPPORTS_LITTLE_ENDIAN select SUPPORTS_LITTLE_ENDIAN
select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R2
select SYS_MIPS_CACHE_INIT_RAM_LOAD
config TARGET_PB1X00 config TARGET_PB1X00
bool "Support pb1x00" bool "Support pb1x00"
select SUPPORTS_LITTLE_ENDIAN select SUPPORTS_LITTLE_ENDIAN
select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R2
select SYS_MIPS_CACHE_INIT_RAM_LOAD
endchoice endchoice
@ -185,6 +188,9 @@ config 64BIT
config SWAP_IO_SPACE config SWAP_IO_SPACE
bool bool
config SYS_MIPS_CACHE_INIT_RAM_LOAD
bool
endif endif
endmenu endmenu

View File

@ -2,9 +2,9 @@
# SPDX-License-Identifier: GPL-2.0+ # SPDX-License-Identifier: GPL-2.0+
# #
head-$(CONFIG_CPU_MIPS32) := arch/mips/cpu/mips32/start.o head-y := arch/mips/cpu/start.o
head-$(CONFIG_CPU_MIPS64) := arch/mips/cpu/mips64/start.o
libs-$(CONFIG_CPU_MIPS32) += arch/mips/cpu/mips32/ libs-y += arch/mips/cpu/
libs-$(CONFIG_CPU_MIPS64) += arch/mips/cpu/mips64/
libs-y += arch/mips/lib/ libs-y += arch/mips/lib/
libs-$(CONFIG_SOC_AU1X00) += arch/mips/mach-au1x00/

9
arch/mips/cpu/Makefile Normal file
View File

@ -0,0 +1,9 @@
#
# SPDX-License-Identifier: GPL-2.0+
#
extra-y = start.o
obj-y += time.o
obj-y += interrupts.o
obj-y += cpu.o

38
arch/mips/cpu/cpu.c Normal file
View File

@ -0,0 +1,38 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <netdev.h>
#include <linux/compiler.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
void __weak _machine_restart(void)
{
fprintf(stderr, "*** reset failed ***\n");
while (1)
/* NOP */;
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
_machine_restart();
return 0;
}
void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
{
write_c0_entrylo0(low0);
write_c0_pagemask(pagemask);
write_c0_entrylo1(low1);
write_c0_entryhi(hi);
write_c0_index(index);
tlb_write_indexed();
}

View File

@ -1,12 +0,0 @@
#
# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
extra-y = start.o
obj-y = cache.o
obj-y += cpu.o interrupts.o time.o
obj-$(CONFIG_SOC_AU1X00) += au1x00/

View File

@ -1,9 +0,0 @@
#
# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
extra-y = start.o
obj-y = cpu.o interrupts.o time.o cache.o

View File

@ -1,213 +0,0 @@
/*
* Cache-handling routined for MIPS CPUs
*
* Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm-offsets.h>
#include <config.h>
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
#define RA t9
/*
* 16kB is the maximum size of instruction and data caches on MIPS 4K,
* 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
*
* Note that the above size is the maximum size of primary cache. U-Boot
* doesn't have L2 cache support for now.
*/
#define MIPS_MAX_CACHE_SIZE 0x10000
#define INDEX_BASE CKSEG0
.macro cache_op op addr
.set push
.set noreorder
.set mips3
cache \op, 0(\addr)
.set pop
.endm
.macro f_fill64 dst, offset, val
LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
#if LONGSIZE == 4
LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
#endif
.endm
/*
* mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
*/
LEAF(mips_init_icache)
blez a1, 9f
mtc0 zero, CP0_TAGLO
/* clear tag to invalidate */
PTR_LI t0, INDEX_BASE
PTR_ADDU t1, t0, a1
1: cache_op INDEX_STORE_TAG_I t0
PTR_ADDU t0, a2
bne t0, t1, 1b
/* fill once, so data field parity is correct */
PTR_LI t0, INDEX_BASE
2: cache_op FILL t0
PTR_ADDU t0, a2
bne t0, t1, 2b
/* invalidate again - prudent but not strictly neccessary */
PTR_LI t0, INDEX_BASE
1: cache_op INDEX_STORE_TAG_I t0
PTR_ADDU t0, a2
bne t0, t1, 1b
9: jr ra
END(mips_init_icache)
/*
* mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
*/
LEAF(mips_init_dcache)
blez a1, 9f
mtc0 zero, CP0_TAGLO
/* clear all tags */
PTR_LI t0, INDEX_BASE
PTR_ADDU t1, t0, a1
1: cache_op INDEX_STORE_TAG_D t0
PTR_ADDU t0, a2
bne t0, t1, 1b
/* load from each line (in cached space) */
PTR_LI t0, INDEX_BASE
2: LONG_L zero, 0(t0)
PTR_ADDU t0, a2
bne t0, t1, 2b
/* clear all tags */
PTR_LI t0, INDEX_BASE
1: cache_op INDEX_STORE_TAG_D t0
PTR_ADDU t0, a2
bne t0, t1, 1b
9: jr ra
END(mips_init_dcache)
/*
* mips_cache_reset - low level initialisation of the primary caches
*
* This routine initialises the primary caches to ensure that they have good
* parity. It must be called by the ROM before any cached locations are used
* to prevent the possibility of data with bad parity being written to memory.
*
* To initialise the instruction cache it is essential that a source of data
* with good parity is available. This routine will initialise an area of
* memory starting at location zero to be used as a source of parity.
*
* RETURNS: N/A
*
*/
NESTED(mips_cache_reset, 0, ra)
move RA, ra
li t2, CONFIG_SYS_ICACHE_SIZE
li t3, CONFIG_SYS_DCACHE_SIZE
li t8, CONFIG_SYS_CACHELINE_SIZE
li v0, MIPS_MAX_CACHE_SIZE
/*
* Now clear that much memory starting from zero.
*/
PTR_LI a0, CKSEG1
PTR_ADDU a1, a0, v0
2: PTR_ADDIU a0, 64
f_fill64 a0, -64, zero
bne a0, a1, 2b
/*
* The caches are probably in an indeterminate state,
* so we force good parity into them by doing an
* invalidate, load/fill, invalidate for each line.
*/
/*
* Assume bottom of RAM will generate good parity for the cache.
*/
/*
* Initialize the I-cache first,
*/
move a1, t2
move a2, t8
PTR_LA v1, mips_init_icache
jalr v1
/*
* then initialize D-cache.
*/
move a1, t3
move a2, t8
PTR_LA v1, mips_init_dcache
jalr v1
jr RA
END(mips_cache_reset)
/*
* dcache_status - get cache status
*
* RETURNS: 0 - cache disabled; 1 - cache enabled
*
*/
LEAF(dcache_status)
mfc0 t0, CP0_CONFIG
li t1, CONF_CM_UNCACHED
andi t0, t0, CONF_CM_CMASK
move v0, zero
beq t0, t1, 2f
li v0, 1
2: jr ra
END(dcache_status)
/*
* dcache_disable - disable cache
*
* RETURNS: N/A
*
*/
LEAF(dcache_disable)
mfc0 t0, CP0_CONFIG
li t1, -8
and t0, t0, t1
ori t0, t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
jr ra
END(dcache_disable)
/*
* dcache_enable - enable cache
*
* RETURNS: N/A
*
*/
LEAF(dcache_enable)
mfc0 t0, CP0_CONFIG
ori t0, CONF_CM_CMASK
xori t0, CONF_CM_CMASK
ori t0, CONF_CM_CACHABLE_NONCOHERENT
mtc0 t0, CP0_CONFIG
jr ra
END(dcache_enable)

View File

@ -1,95 +0,0 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <netdev.h>
#include <asm/mipsregs.h>
#include <asm/cacheops.h>
#include <asm/reboot.h>
#define cache_op(op, addr) \
__asm__ __volatile__( \
" .set push\n" \
" .set noreorder\n" \
" .set mips64\n" \
" cache %0, %1\n" \
" .set pop\n" \
: \
: "i" (op), "R" (*(unsigned char *)(addr)))
void __attribute__((weak)) _machine_restart(void)
{
fprintf(stderr, "*** reset failed ***\n");
while (1)
/* NOP */;
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
_machine_restart();
return 0;
}
void flush_cache(ulong start_addr, ulong size)
{
unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
unsigned long addr = start_addr & ~(lsize - 1);
unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
/* aend will be miscalculated when size is zero, so we return here */
if (size == 0)
return;
while (1) {
cache_op(HIT_WRITEBACK_INV_D, addr);
cache_op(HIT_INVALIDATE_I, addr);
if (addr == aend)
break;
addr += lsize;
}
}
void flush_dcache_range(ulong start_addr, ulong stop)
{
unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
unsigned long addr = start_addr & ~(lsize - 1);
unsigned long aend = (stop - 1) & ~(lsize - 1);
while (1) {
cache_op(HIT_WRITEBACK_INV_D, addr);
if (addr == aend)
break;
addr += lsize;
}
}
void invalidate_dcache_range(ulong start_addr, ulong stop)
{
unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
unsigned long addr = start_addr & ~(lsize - 1);
unsigned long aend = (stop - 1) & ~(lsize - 1);
while (1) {
cache_op(HIT_INVALIDATE_D, addr);
if (addr == aend)
break;
addr += lsize;
}
}
void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
{
write_c0_entrylo0(low0);
write_c0_pagemask(pagemask);
write_c0_entrylo1(low1);
write_c0_entryhi(hi);
write_c0_index(index);
tlb_write_indexed();
}

View File

@ -1,22 +0,0 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
int interrupt_init(void)
{
return 0;
}
void enable_interrupts(void)
{
}
int disable_interrupts(void)
{
return 0;
}

View File

@ -1,291 +0,0 @@
/*
* Startup Code for MIPS64 CPU-core
*
* Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm-offsets.h>
#include <config.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#ifndef CONFIG_SYS_MIPS_CACHE_MODE
#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
#endif
#ifndef CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
CONFIG_SYS_INIT_SP_OFFSET)
#endif
#ifdef CONFIG_SYS_LITTLE_ENDIAN
#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
(((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
#else
#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
#endif
/*
* For the moment disable interrupts, mark the kernel mode and
* set ST0_KX so that the CPU does not spit fire when using
* 64-bit addresses.
*/
.macro setup_c0_status set clr
.set push
mfc0 t0, CP0_STATUS
or t0, ST0_CU0 | \set | 0x1f | \clr
xor t0, 0x1f | \clr
mtc0 t0, CP0_STATUS
.set noreorder
sll zero, 3 # ehb
.set pop
.endm
.set noreorder
.globl _start
.text
_start:
/* U-boot entry point */
b reset
nop
.org 0x200
/* TLB refill, 32 bit task */
1: b 1b
nop
.org 0x280
/* XTLB refill, 64 bit task */
1: b 1b
nop
.org 0x300
/* Cache error exception */
1: b 1b
nop
.org 0x380
/* General exception */
1: b 1b
nop
.org 0x400
/* Catch interrupt exceptions */
1: b 1b
nop
.org 0x480
/* EJTAG debug exception */
1: b 1b
nop
.align 4
reset:
/* Clear watch registers */
dmtc0 zero, CP0_WATCHLO
dmtc0 zero, CP0_WATCHHI
/* WP(Watch Pending), SW0/1 should be cleared */
mtc0 zero, CP0_CAUSE
setup_c0_status ST0_KX 0
/* Init Timer */
mtc0 zero, CP0_COUNT
mtc0 zero, CP0_COMPARE
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/* CONFIG0 register */
dli t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
#endif
/*
* Initialize $gp, force 8 byte alignment of bal instruction to forbid
* the compiler to put nop's between bal and _gp. This is required to
* keep _gp and ra aligned to 8 byte.
*/
.align 3
bal 1f
nop
.dword _gp
1:
ld gp, 0(ra)
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/* Initialize any external memory */
dla t9, lowlevel_init
jalr t9
nop
/* Initialize caches... */
dla t9, mips_cache_reset
jalr t9
nop
/* ... and enable them */
dli t0, CONFIG_SYS_MIPS_CACHE_MODE
mtc0 t0, CP0_CONFIG
#endif
/* Set up temporary stack */
dli t0, -16
dli t1, CONFIG_SYS_INIT_SP_ADDR
and sp, t1, t0 # force 16 byte alignment
dsub sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment
move k0, sp # save gd pointer
#ifdef CONFIG_SYS_MALLOC_F_LEN
dli t2, CONFIG_SYS_MALLOC_F_LEN
dsub sp, sp, t2 # reserve space for early malloc
and sp, sp, t0 # force 16 byte alignment
#endif
move fp, sp
/* Clear gd */
move t0, k0
1:
sw zero, 0(t0)
blt t0, t1, 1b
daddi t0, 4
#ifdef CONFIG_SYS_MALLOC_F_LEN
daddu t0, k0, GD_MALLOC_BASE # gd->malloc_base offset
sw sp, 0(t0)
#endif
dla t9, board_init_f
jr t9
move ra, zero
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
* a0 = addr_sp
* a1 = gd
* a2 = destination address
*/
.globl relocate_code
.ent relocate_code
relocate_code:
move sp, a0 # set new stack pointer
move fp, sp
move s0, a1 # save gd in s0
move s2, a2 # save destination address in s2
dli t0, CONFIG_SYS_MONITOR_BASE
dsub s1, s2, t0 # s1 <-- relocation offset
dla t3, in_ram
ld t2, -24(t3) # t2 <-- __image_copy_end
move t1, a2
dadd gp, s1 # adjust gp
/*
* t0 = source address
* t1 = target address
* t2 = source end address
*/
1:
lw t3, 0(t0)
sw t3, 0(t1)
daddu t0, 4
blt t0, t2, 1b
daddu t1, 4
/* If caches were enabled, we would have to flush them here. */
dsub a1, t1, s2 # a1 <-- size
dla t9, flush_cache
jalr t9
move a0, s2 # a0 <-- destination address
/* Jump to where we've relocated ourselves */
daddi t0, s2, in_ram - _start
jr t0
nop
.dword __rel_dyn_end
.dword __rel_dyn_start
.dword __image_copy_end
.dword _GLOBAL_OFFSET_TABLE_
.dword num_got_entries
in_ram:
/*
* Now we want to update GOT.
*
* GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
* generated by GNU ld. Skip these reserved entries from relocation.
*/
ld t3, -8(t0) # t3 <-- num_got_entries
ld t8, -16(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
dadd t8, s1 # t8 now holds relocated _G_O_T_
daddi t8, t8, 16 # skipping first two entries
dli t2, 2
1:
ld t1, 0(t8)
beqz t1, 2f
dadd t1, s1
sd t1, 0(t8)
2:
daddi t2, 1
blt t2, t3, 1b
daddi t8, 8
/* Update dynamic relocations */
ld t1, -32(t0) # t1 <-- __rel_dyn_start
ld t2, -40(t0) # t2 <-- __rel_dyn_end
b 2f # skip first reserved entry
daddi t1, 16
1:
lw t8, -4(t1) # t8 <-- relocation info
dli t3, MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
bne t8, t3, 2f # skip non R_MIPS_REL32 entries
nop
ld t3, -16(t1) # t3 <-- location to fix up in FLASH
ld t8, 0(t3) # t8 <-- original pointer
dadd t8, s1 # t8 <-- adjusted pointer
dadd t3, s1 # t3 <-- location to fix up in RAM
sd t8, 0(t3)
2:
blt t1, t2, 1b
daddi t1, 16 # each rel.dyn entry is 16 bytes
/*
* Clear BSS
*
* GOT is now relocated. Thus __bss_start and __bss_end can be
* accessed directly via $gp.
*/
dla t1, __bss_start # t1 <-- __bss_start
dla t2, __bss_end # t2 <-- __bss_end
1:
sd zero, 0(t1)
blt t1, t2, 1b
daddi t1, 8
move a0, s0 # a0 <-- gd
move a1, s2
dla t9, board_init_r
jr t9
move ra, zero
.end relocate_code

View File

@ -1,19 +0,0 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/mipsregs.h>
unsigned long notrace timer_read_counter(void)
{
return read_c0_count();
}
ulong notrace get_tbclk(void)
{
return CONFIG_SYS_MIPS_TIMER_FREQ;
}

View File

@ -8,6 +8,7 @@
#include <asm-offsets.h> #include <asm-offsets.h>
#include <config.h> #include <config.h>
#include <asm/asm.h>
#include <asm/regdef.h> #include <asm/regdef.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
@ -20,6 +21,23 @@
CONFIG_SYS_INIT_SP_OFFSET) CONFIG_SYS_INIT_SP_OFFSET)
#endif #endif
#ifdef CONFIG_32BIT
# define MIPS_RELOC 3
# define STATUS_SET 0
#endif
#ifdef CONFIG_64BIT
# ifdef CONFIG_SYS_LITTLE_ENDIAN
# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
(((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
# else
# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
# endif
# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
# define STATUS_SET ST0_KX
#endif
/* /*
* For the moment disable interrupts, mark the kernel mode and * For the moment disable interrupts, mark the kernel mode and
* set ST0_KX so that the CPU does not spit fire when using * set ST0_KX so that the CPU does not spit fire when using
@ -98,13 +116,13 @@ _start:
reset: reset:
/* Clear watch registers */ /* Clear watch registers */
mtc0 zero, CP0_WATCHLO MTC0 zero, CP0_WATCHLO
mtc0 zero, CP0_WATCHHI MTC0 zero, CP0_WATCHHI
/* WP(Watch Pending), SW0/1 should be cleared */ /* WP(Watch Pending), SW0/1 should be cleared */
mtc0 zero, CP0_CAUSE mtc0 zero, CP0_CAUSE
setup_c0_status 0 0 setup_c0_status STATUS_SET 0
/* Init Timer */ /* Init Timer */
mtc0 zero, CP0_COUNT mtc0 zero, CP0_COUNT
@ -116,21 +134,26 @@ reset:
mtc0 t0, CP0_CONFIG mtc0 t0, CP0_CONFIG
#endif #endif
/* Initialize $gp */ /*
* Initialize $gp, force pointer sized alignment of bal instruction to
* forbid the compiler to put nop's between bal and _gp. This is
* required to keep _gp and ra aligned to 8 byte.
*/
.align PTRLOG
bal 1f bal 1f
nop nop
.word _gp PTR _gp
1: 1:
lw gp, 0(ra) PTR_L gp, 0(ra)
#ifndef CONFIG_SKIP_LOWLEVEL_INIT #ifndef CONFIG_SKIP_LOWLEVEL_INIT
/* Initialize any external memory */ /* Initialize any external memory */
la t9, lowlevel_init PTR_LA t9, lowlevel_init
jalr t9 jalr t9
nop nop
/* Initialize caches... */ /* Initialize caches... */
la t9, mips_cache_reset PTR_LA t9, mips_cache_reset
jalr t9 jalr t9
nop nop
@ -140,15 +163,15 @@ reset:
#endif #endif
/* Set up temporary stack */ /* Set up temporary stack */
li t0, -16 PTR_LI t0, -16
li t1, CONFIG_SYS_INIT_SP_ADDR PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
and sp, t1, t0 # force 16 byte alignment and sp, t1, t0 # force 16 byte alignment
sub sp, sp, GD_SIZE # reserve space for gd PTR_SUB sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment and sp, sp, t0 # force 16 byte alignment
move k0, sp # save gd pointer move k0, sp # save gd pointer
#ifdef CONFIG_SYS_MALLOC_F_LEN #ifdef CONFIG_SYS_MALLOC_F_LEN
li t2, CONFIG_SYS_MALLOC_F_LEN PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN
sub sp, sp, t2 # reserve space for early malloc PTR_SUB sp, sp, t2 # reserve space for early malloc
and sp, sp, t0 # force 16 byte alignment and sp, sp, t0 # force 16 byte alignment
#endif #endif
move fp, sp move fp, sp
@ -158,14 +181,14 @@ reset:
1: 1:
sw zero, 0(t0) sw zero, 0(t0)
blt t0, t1, 1b blt t0, t1, 1b
addi t0, 4 PTR_ADDI t0, 4
#ifdef CONFIG_SYS_MALLOC_F_LEN #ifdef CONFIG_SYS_MALLOC_F_LEN
addu t0, k0, GD_MALLOC_BASE # gd->malloc_base offset PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset
sw sp, 0(t0) sw sp, 0(t0)
#endif #endif
la t9, board_init_f PTR_LA t9, board_init_f
jr t9 jr t9
move ra, zero move ra, zero
@ -188,14 +211,14 @@ relocate_code:
move s0, a1 # save gd in s0 move s0, a1 # save gd in s0
move s2, a2 # save destination address in s2 move s2, a2 # save destination address in s2
li t0, CONFIG_SYS_MONITOR_BASE PTR_LI t0, CONFIG_SYS_MONITOR_BASE
sub s1, s2, t0 # s1 <-- relocation offset PTR_SUB s1, s2, t0 # s1 <-- relocation offset
la t3, in_ram PTR_LA t3, in_ram
lw t2, -12(t3) # t2 <-- __image_copy_end PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end
move t1, a2 move t1, a2
add gp, s1 # adjust gp PTR_ADD gp, s1 # adjust gp
/* /*
* t0 = source address * t0 = source address
@ -205,26 +228,26 @@ relocate_code:
1: 1:
lw t3, 0(t0) lw t3, 0(t0)
sw t3, 0(t1) sw t3, 0(t1)
addu t0, 4 PTR_ADDU t0, 4
blt t0, t2, 1b blt t0, t2, 1b
addu t1, 4 PTR_ADDU t1, 4
/* If caches were enabled, we would have to flush them here. */ /* If caches were enabled, we would have to flush them here. */
sub a1, t1, s2 # a1 <-- size PTR_SUB a1, t1, s2 # a1 <-- size
la t9, flush_cache PTR_LA t9, flush_cache
jalr t9 jalr t9
move a0, s2 # a0 <-- destination address move a0, s2 # a0 <-- destination address
/* Jump to where we've relocated ourselves */ /* Jump to where we've relocated ourselves */
addi t0, s2, in_ram - _start PTR_ADDI t0, s2, in_ram - _start
jr t0 jr t0
nop nop
.word __rel_dyn_end PTR __rel_dyn_end
.word __rel_dyn_start PTR __rel_dyn_start
.word __image_copy_end PTR __image_copy_end
.word _GLOBAL_OFFSET_TABLE_ PTR _GLOBAL_OFFSET_TABLE_
.word num_got_entries PTR num_got_entries
in_ram: in_ram:
/* /*
@ -233,46 +256,46 @@ in_ram:
* GOT[0] is reserved. GOT[1] is also reserved for the dynamic object * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
* generated by GNU ld. Skip these reserved entries from relocation. * generated by GNU ld. Skip these reserved entries from relocation.
*/ */
lw t3, -4(t0) # t3 <-- num_got_entries PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries
lw t8, -8(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
add t8, s1 # t8 now holds relocated _G_O_T_ PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_
addi t8, t8, 8 # skipping first two entries PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries
li t2, 2 PTR_LI t2, 2
1: 1:
lw t1, 0(t8) PTR_L t1, 0(t8)
beqz t1, 2f beqz t1, 2f
add t1, s1 PTR_ADD t1, s1
sw t1, 0(t8) PTR_S t1, 0(t8)
2: 2:
addi t2, 1 PTR_ADDI t2, 1
blt t2, t3, 1b blt t2, t3, 1b
addi t8, 4 PTR_ADDI t8, PTRSIZE
/* Update dynamic relocations */ /* Update dynamic relocations */
lw t1, -16(t0) # t1 <-- __rel_dyn_start PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start
lw t2, -20(t0) # t2 <-- __rel_dyn_end PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end
b 2f # skip first reserved entry b 2f # skip first reserved entry
addi t1, 8 PTR_ADDI t1, 2 * PTRSIZE
1: 1:
lw t8, -4(t1) # t8 <-- relocation info lw t8, -4(t1) # t8 <-- relocation info
li t3, 3 PTR_LI t3, MIPS_RELOC
bne t8, t3, 2f # skip non R_MIPS_REL32 entries bne t8, t3, 2f # skip non-MIPS_RELOC entries
nop nop
lw t3, -8(t1) # t3 <-- location to fix up in FLASH PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH
lw t8, 0(t3) # t8 <-- original pointer PTR_L t8, 0(t3) # t8 <-- original pointer
add t8, s1 # t8 <-- adjusted pointer PTR_ADD t8, s1 # t8 <-- adjusted pointer
add t3, s1 # t3 <-- location to fix up in RAM PTR_ADD t3, s1 # t3 <-- location to fix up in RAM
sw t8, 0(t3) PTR_S t8, 0(t3)
2: 2:
blt t1, t2, 1b blt t1, t2, 1b
addi t1, 8 # each rel.dyn entry is 8 bytes PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes
/* /*
* Clear BSS * Clear BSS
@ -280,17 +303,17 @@ in_ram:
* GOT is now relocated. Thus __bss_start and __bss_end can be * GOT is now relocated. Thus __bss_start and __bss_end can be
* accessed directly via $gp. * accessed directly via $gp.
*/ */
la t1, __bss_start # t1 <-- __bss_start PTR_LA t1, __bss_start # t1 <-- __bss_start
la t2, __bss_end # t2 <-- __bss_end PTR_LA t2, __bss_end # t2 <-- __bss_end
1: 1:
sw zero, 0(t1) PTR_S zero, 0(t1)
blt t1, t2, 1b blt t1, t2, 1b
addi t1, 4 PTR_ADDI t1, PTRSIZE
move a0, s0 # a0 <-- gd move a0, s0 # a0 <-- gd
move a1, s2 move a1, s2
la t9, board_init_r PTR_LA t9, board_init_r
jr t9 jr t9
move ra, zero move ra, zero

View File

@ -11,6 +11,19 @@
#ifndef __ASM_CACHEOPS_H #ifndef __ASM_CACHEOPS_H
#define __ASM_CACHEOPS_H #define __ASM_CACHEOPS_H
#ifndef __ASSEMBLY__
static inline void mips_cache(int op, const volatile void *addr)
{
#ifdef __GCC_HAVE_BUILTIN_MIPS_CACHE
__builtin_mips_cache(op, addr);
#else
__asm__ __volatile__("cache %0, %1" : : "i"(op), "R"(addr))
#endif
}
#endif /* !__ASSEMBLY__ */
/* /*
* Cache Operations available on all MIPS processors with R4000-style caches * Cache Operations available on all MIPS processors with R4000-style caches
*/ */

View File

@ -64,4 +64,9 @@
#define PCI_CFG_PIIX4_GENCFG_SERIRQ (1 << 16) #define PCI_CFG_PIIX4_GENCFG_SERIRQ (1 << 16)
#define PCI_CFG_PIIX4_IDETIM_PRI 0x40
#define PCI_CFG_PIIX4_IDETIM_SEC 0x42
#define PCI_CFG_PIIX4_IDETIM_IDE (1 << 15)
#endif /* _MIPS_ASM_MALTA_H */ #endif /* _MIPS_ASM_MALTA_H */

View File

@ -5,6 +5,8 @@
# SPDX-License-Identifier: GPL-2.0+ # SPDX-License-Identifier: GPL-2.0+
# #
obj-y += cache.o
obj-y += cache_init.o
obj-y += io.o obj-y += io.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTM) += bootm.o

View File

@ -6,33 +6,8 @@
*/ */
#include <common.h> #include <common.h>
#include <command.h>
#include <netdev.h>
#include <asm/mipsregs.h>
#include <asm/cacheops.h> #include <asm/cacheops.h>
#include <asm/reboot.h> #include <asm/mipsregs.h>
#define cache_op(op,addr) \
__asm__ __volatile__( \
" .set push \n" \
" .set noreorder \n" \
" .set mips3\n\t \n" \
" cache %0, %1 \n" \
" .set pop \n" \
: \
: "i" (op), "R" (*(unsigned char *)(addr)))
void __attribute__((weak)) _machine_restart(void)
{
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
_machine_restart();
fprintf(stderr, "*** reset failed ***\n");
return 0;
}
#ifdef CONFIG_SYS_CACHELINE_SIZE #ifdef CONFIG_SYS_CACHELINE_SIZE
@ -74,20 +49,20 @@ void flush_cache(ulong start_addr, ulong size)
{ {
unsigned long ilsize = icache_line_size(); unsigned long ilsize = icache_line_size();
unsigned long dlsize = dcache_line_size(); unsigned long dlsize = dcache_line_size();
unsigned long addr, aend; const void *addr, *aend;
/* aend will be miscalculated when size is zero, so we return here */ /* aend will be miscalculated when size is zero, so we return here */
if (size == 0) if (size == 0)
return; return;
addr = start_addr & ~(dlsize - 1); addr = (const void *)(start_addr & ~(dlsize - 1));
aend = (start_addr + size - 1) & ~(dlsize - 1); aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
if (ilsize == dlsize) { if (ilsize == dlsize) {
/* flush I-cache & D-cache simultaneously */ /* flush I-cache & D-cache simultaneously */
while (1) { while (1) {
cache_op(HIT_WRITEBACK_INV_D, addr); mips_cache(HIT_WRITEBACK_INV_D, addr);
cache_op(HIT_INVALIDATE_I, addr); mips_cache(HIT_INVALIDATE_I, addr);
if (addr == aend) if (addr == aend)
break; break;
addr += dlsize; addr += dlsize;
@ -97,17 +72,17 @@ void flush_cache(ulong start_addr, ulong size)
/* flush D-cache */ /* flush D-cache */
while (1) { while (1) {
cache_op(HIT_WRITEBACK_INV_D, addr); mips_cache(HIT_WRITEBACK_INV_D, addr);
if (addr == aend) if (addr == aend)
break; break;
addr += dlsize; addr += dlsize;
} }
/* flush I-cache */ /* flush I-cache */
addr = start_addr & ~(ilsize - 1); addr = (const void *)(start_addr & ~(ilsize - 1));
aend = (start_addr + size - 1) & ~(ilsize - 1); aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
while (1) { while (1) {
cache_op(HIT_INVALIDATE_I, addr); mips_cache(HIT_INVALIDATE_I, addr);
if (addr == aend) if (addr == aend)
break; break;
addr += ilsize; addr += ilsize;
@ -117,11 +92,11 @@ void flush_cache(ulong start_addr, ulong size)
void flush_dcache_range(ulong start_addr, ulong stop) void flush_dcache_range(ulong start_addr, ulong stop)
{ {
unsigned long lsize = dcache_line_size(); unsigned long lsize = dcache_line_size();
unsigned long addr = start_addr & ~(lsize - 1); const void *addr = (const void *)(start_addr & ~(lsize - 1));
unsigned long aend = (stop - 1) & ~(lsize - 1); const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
while (1) { while (1) {
cache_op(HIT_WRITEBACK_INV_D, addr); mips_cache(HIT_WRITEBACK_INV_D, addr);
if (addr == aend) if (addr == aend)
break; break;
addr += lsize; addr += lsize;
@ -131,31 +106,13 @@ void flush_dcache_range(ulong start_addr, ulong stop)
void invalidate_dcache_range(ulong start_addr, ulong stop) void invalidate_dcache_range(ulong start_addr, ulong stop)
{ {
unsigned long lsize = dcache_line_size(); unsigned long lsize = dcache_line_size();
unsigned long addr = start_addr & ~(lsize - 1); const void *addr = (const void *)(start_addr & ~(lsize - 1));
unsigned long aend = (stop - 1) & ~(lsize - 1); const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
while (1) { while (1) {
cache_op(HIT_INVALIDATE_D, addr); mips_cache(HIT_INVALIDATE_D, addr);
if (addr == aend) if (addr == aend)
break; break;
addr += lsize; addr += lsize;
} }
} }
void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
{
write_c0_entrylo0(low0);
write_c0_pagemask(pagemask);
write_c0_entrylo1(low1);
write_c0_entryhi(hi);
write_c0_index(index);
tlb_write_indexed();
}
int cpu_eth_init(bd_t *bis)
{
#ifdef CONFIG_SOC_AU1X00
au1x00_enet_initialize(bis);
#endif
return 0;
}

View File

@ -18,18 +18,8 @@
#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
#endif #endif
#define RA t9
#define INDEX_BASE CKSEG0 #define INDEX_BASE CKSEG0
.macro cache_op op addr
.set push
.set noreorder
.set mips3
cache \op, 0(\addr)
.set pop
.endm
.macro f_fill64 dst, offset, val .macro f_fill64 dst, offset, val
LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
@ -51,56 +41,49 @@
#endif #endif
.endm .endm
/* .macro cache_loop curr, end, line_sz, op
* mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) 10: cache \op, 0(\curr)
*/ PTR_ADDU \curr, \curr, \line_sz
LEAF(mips_init_icache) bne \curr, \end, 10b
blez a1, 9f .endm
mtc0 zero, CP0_TAGLO
/* clear tag to invalidate */
PTR_LI t0, INDEX_BASE
PTR_ADDU t1, t0, a1
1: cache_op INDEX_STORE_TAG_I t0
PTR_ADDU t0, a2
bne t0, t1, 1b
/* fill once, so data field parity is correct */
PTR_LI t0, INDEX_BASE
2: cache_op FILL t0
PTR_ADDU t0, a2
bne t0, t1, 2b
/* invalidate again - prudent but not strictly neccessary */
PTR_LI t0, INDEX_BASE
1: cache_op INDEX_STORE_TAG_I t0
PTR_ADDU t0, a2
bne t0, t1, 1b
9: jr ra
END(mips_init_icache)
/* .macro l1_info sz, line_sz, off
* mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz) .set push
*/ .set noat
LEAF(mips_init_dcache)
blez a1, 9f
mtc0 zero, CP0_TAGLO
/* clear all tags */
PTR_LI t0, INDEX_BASE
PTR_ADDU t1, t0, a1
1: cache_op INDEX_STORE_TAG_D t0
PTR_ADDU t0, a2
bne t0, t1, 1b
/* load from each line (in cached space) */
PTR_LI t0, INDEX_BASE
2: LONG_L zero, 0(t0)
PTR_ADDU t0, a2
bne t0, t1, 2b
/* clear all tags */
PTR_LI t0, INDEX_BASE
1: cache_op INDEX_STORE_TAG_D t0
PTR_ADDU t0, a2
bne t0, t1, 1b
9: jr ra
END(mips_init_dcache)
mfc0 $1, CP0_CONFIG, 1
/* detect line size */
srl \line_sz, $1, \off + MIPS_CONF1_DL_SHIFT - MIPS_CONF1_DA_SHIFT
andi \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT)
move \sz, zero
beqz \line_sz, 10f
li \sz, 2
sllv \line_sz, \sz, \line_sz
/* detect associativity */
srl \sz, $1, \off + MIPS_CONF1_DA_SHIFT - MIPS_CONF1_DA_SHIFT
andi \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT)
addi \sz, \sz, 1
/* sz *= line_sz */
mul \sz, \sz, \line_sz
/* detect log32(sets) */
srl $1, $1, \off + MIPS_CONF1_DS_SHIFT - MIPS_CONF1_DA_SHIFT
andi $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT)
addiu $1, $1, 1
andi $1, $1, 0x7
/* sz <<= log32(sets) */
sllv \sz, \sz, $1
/* sz *= 32 */
li $1, 32
mul \sz, \sz, $1
10:
.set pop
.endm
/* /*
* mips_cache_reset - low level initialisation of the primary caches * mips_cache_reset - low level initialisation of the primary caches
* *
@ -115,75 +98,23 @@ LEAF(mips_init_dcache)
* RETURNS: N/A * RETURNS: N/A
* *
*/ */
NESTED(mips_cache_reset, 0, ra) LEAF(mips_cache_reset)
move RA, ra
#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \
!defined(CONFIG_SYS_CACHELINE_SIZE)
/* read Config1 for use below */
mfc0 t5, CP0_CONFIG, 1
#endif
#ifdef CONFIG_SYS_CACHELINE_SIZE
li t7, CONFIG_SYS_CACHELINE_SIZE
li t8, CONFIG_SYS_CACHELINE_SIZE
#else
/* Detect I-cache line size. */
srl t8, t5, MIPS_CONF1_IL_SHIFT
andi t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT)
beqz t8, 1f
li t6, 2
sllv t8, t6, t8
1: /* Detect D-cache line size. */
srl t7, t5, MIPS_CONF1_DL_SHIFT
andi t7, t7, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT)
beqz t7, 1f
li t6, 2
sllv t7, t6, t7
1:
#endif
#ifdef CONFIG_SYS_ICACHE_SIZE #ifdef CONFIG_SYS_ICACHE_SIZE
li t2, CONFIG_SYS_ICACHE_SIZE li t2, CONFIG_SYS_ICACHE_SIZE
li t8, CONFIG_SYS_CACHELINE_SIZE
#else #else
/* Detect I-cache size. */ l1_info t2, t8, MIPS_CONF1_IA_SHIFT
srl t6, t5, MIPS_CONF1_IS_SHIFT
andi t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT)
li t4, 32
xori t2, t6, 0x7
beqz t2, 1f
addi t6, t6, 1
sllv t4, t4, t6
1: /* At this point t4 == I-cache sets. */
mul t2, t4, t8
srl t6, t5, MIPS_CONF1_IA_SHIFT
andi t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT)
addi t6, t6, 1
/* At this point t6 == I-cache ways. */
mul t2, t2, t6
#endif #endif
#ifdef CONFIG_SYS_DCACHE_SIZE #ifdef CONFIG_SYS_DCACHE_SIZE
li t3, CONFIG_SYS_DCACHE_SIZE li t3, CONFIG_SYS_DCACHE_SIZE
li t9, CONFIG_SYS_CACHELINE_SIZE
#else #else
/* Detect D-cache size. */ l1_info t3, t9, MIPS_CONF1_DA_SHIFT
srl t6, t5, MIPS_CONF1_DS_SHIFT
andi t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT)
li t4, 32
xori t3, t6, 0x7
beqz t3, 1f
addi t6, t6, 1
sllv t4, t4, t6
1: /* At this point t4 == I-cache sets. */
mul t3, t4, t7
srl t6, t5, MIPS_CONF1_DA_SHIFT
andi t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT)
addi t6, t6, 1
/* At this point t6 == I-cache ways. */
mul t3, t3, t6
#endif #endif
#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
/* Determine the largest L1 cache size */ /* Determine the largest L1 cache size */
#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) #if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE)
#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
@ -205,33 +136,62 @@ NESTED(mips_cache_reset, 0, ra)
f_fill64 a0, -64, zero f_fill64 a0, -64, zero
bne a0, a1, 2b bne a0, a1, 2b
/* #endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
* The caches are probably in an indeterminate state,
* so we force good parity into them by doing an
* invalidate, load/fill, invalidate for each line.
*/
/* /*
* Assume bottom of RAM will generate good parity for the cache. * The TagLo registers used depend upon the CPU implementation, but the
* architecture requires that it is safe for software to write to both
* TagLo selects 0 & 2 covering supported cases.
*/
mtc0 zero, CP0_TAGLO
mtc0 zero, CP0_TAGLO, 2
/*
* The caches are probably in an indeterminate state, so we force good
* parity into them by doing an invalidate for each line. If
* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to
* perform a load/fill & a further invalidate for each line, assuming
* that the bottom of RAM (having just been cleared) will generate good
* parity for the cache.
*/ */
/* /*
* Initialize the I-cache first, * Initialize the I-cache first,
*/ */
move a1, t2 blez t2, 1f
move a2, t8 PTR_LI t0, INDEX_BASE
PTR_LA v1, mips_init_icache PTR_ADDU t1, t0, t2
jalr v1 /* clear tag to invalidate */
cache_loop t0, t1, t8, INDEX_STORE_TAG_I
#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
/* fill once, so data field parity is correct */
PTR_LI t0, INDEX_BASE
cache_loop t0, t1, t8, FILL
/* invalidate again - prudent but not strictly neccessary */
PTR_LI t0, INDEX_BASE
cache_loop t0, t1, t8, INDEX_STORE_TAG_I
#endif
/* /*
* then initialize D-cache. * then initialize D-cache.
*/ */
move a1, t3 1: blez t3, 3f
move a2, t7 PTR_LI t0, INDEX_BASE
PTR_LA v1, mips_init_dcache PTR_ADDU t1, t0, t3
jalr v1 /* clear all tags */
cache_loop t0, t1, t9, INDEX_STORE_TAG_D
#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
/* load from each line (in cached space) */
PTR_LI t0, INDEX_BASE
2: LONG_L zero, 0(t0)
PTR_ADDU t0, t9
bne t0, t1, 2b
/* clear all tags */
PTR_LI t0, INDEX_BASE
cache_loop t0, t1, t9, INDEX_STORE_TAG_D
#endif
jr RA 3: jr ra
END(mips_cache_reset) END(mips_cache_reset)
/* /*

View File

@ -294,3 +294,9 @@ int au1x00_enet_initialize(bd_t *bis){
return 1; return 1;
} }
int cpu_eth_init(bd_t *bis)
{
au1x00_enet_initialize(bis);
return 0;
}

View File

@ -6,6 +6,7 @@
*/ */
#include <common.h> #include <common.h>
#include <ide.h>
#include <netdev.h> #include <netdev.h>
#include <pci.h> #include <pci.h>
#include <pci_gt64120.h> #include <pci_gt64120.h>
@ -123,6 +124,7 @@ void _machine_restart(void)
reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE); reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE);
__raw_writel(GORESET, reset_base); __raw_writel(GORESET, reset_base);
mdelay(1000);
} }
int board_early_init_f(void) int board_early_init_f(void)
@ -217,4 +219,22 @@ void pci_init_board(void)
pci_read_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, &val8); pci_read_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, &val8);
val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT; val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT;
pci_write_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, val8); pci_write_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, val8);
bdf = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB, 0);
if (bdf == -1)
panic("Failed to find PIIX4 IDE controller\n");
/* enable bus master & IO access */
val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
pci_write_config_dword(bdf, PCI_COMMAND, val32);
/* set latency */
pci_write_config_byte(bdf, PCI_LATENCY_TIMER, 0x40);
/* enable IDE/ATA */
pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_PRI,
PCI_CFG_PIIX4_IDETIM_IDE);
pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC,
PCI_CFG_PIIX4_IDETIM_IDE);
} }

View File

@ -71,6 +71,7 @@
sizeof(CONFIG_SYS_PROMPT) + 16) sizeof(CONFIG_SYS_PROMPT) + 16)
#define CONFIG_SYS_MAXARGS 16 #define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_AUTO_COMPLETE #define CONFIG_AUTO_COMPLETE
#define CONFIG_CMDLINE_EDITING #define CONFIG_CMDLINE_EDITING
@ -106,6 +107,16 @@
#define CONFIG_ENV_ADDR \ #define CONFIG_ENV_ADDR \
(CONFIG_SYS_FLASH_BASE + (4 << 20) - CONFIG_ENV_SIZE) (CONFIG_SYS_FLASH_BASE + (4 << 20) - CONFIG_ENV_SIZE)
/*
* IDE/ATA
*/
#define CONFIG_SYS_IDE_MAXBUS 1
#define CONFIG_SYS_IDE_MAXDEVICE 2
#define CONFIG_SYS_ATA_BASE_ADDR CONFIG_SYS_ISA_IO_BASE_ADDRESS
#define CONFIG_SYS_ATA_IDE0_OFFSET 0x01f0
#define CONFIG_SYS_ATA_DATA_OFFSET 0
#define CONFIG_SYS_ATA_REG_OFFSET 0
/* /*
* Commands * Commands
*/ */
@ -118,6 +129,8 @@
#define CONFIG_CMD_DATE #define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP #define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
#define CONFIG_CMD_IDE
#define CONFIG_CMD_PCI #define CONFIG_CMD_PCI
#define CONFIG_CMD_PING #define CONFIG_CMD_PING