Merge branch 'master' of git://git.denx.de/u-boot-mips
This commit is contained in:
commit
a0573d1988
@ -36,6 +36,7 @@ config TARGET_VCT
|
||||
select SUPPORTS_BIG_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
|
||||
config TARGET_DBAU1X00
|
||||
bool "Support dbau1x00"
|
||||
@ -43,12 +44,14 @@ config TARGET_DBAU1X00
|
||||
select SUPPORTS_LITTLE_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
|
||||
config TARGET_PB1X00
|
||||
bool "Support pb1x00"
|
||||
select SUPPORTS_LITTLE_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
|
||||
|
||||
endchoice
|
||||
@ -185,6 +188,9 @@ config 64BIT
|
||||
config SWAP_IO_SPACE
|
||||
bool
|
||||
|
||||
config SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
bool
|
||||
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
@ -2,9 +2,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
head-$(CONFIG_CPU_MIPS32) := arch/mips/cpu/mips32/start.o
|
||||
head-$(CONFIG_CPU_MIPS64) := arch/mips/cpu/mips64/start.o
|
||||
head-y := arch/mips/cpu/start.o
|
||||
|
||||
libs-$(CONFIG_CPU_MIPS32) += arch/mips/cpu/mips32/
|
||||
libs-$(CONFIG_CPU_MIPS64) += arch/mips/cpu/mips64/
|
||||
libs-y += arch/mips/cpu/
|
||||
libs-y += arch/mips/lib/
|
||||
|
||||
libs-$(CONFIG_SOC_AU1X00) += arch/mips/mach-au1x00/
|
||||
|
9
arch/mips/cpu/Makefile
Normal file
9
arch/mips/cpu/Makefile
Normal 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
38
arch/mips/cpu/cpu.c
Normal 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();
|
||||
}
|
@ -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/
|
@ -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
|
@ -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)
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
@ -20,6 +21,23 @@
|
||||
CONFIG_SYS_INIT_SP_OFFSET)
|
||||
#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
|
||||
* set ST0_KX so that the CPU does not spit fire when using
|
||||
@ -98,13 +116,13 @@ _start:
|
||||
reset:
|
||||
|
||||
/* Clear watch registers */
|
||||
mtc0 zero, CP0_WATCHLO
|
||||
mtc0 zero, CP0_WATCHHI
|
||||
MTC0 zero, CP0_WATCHLO
|
||||
MTC0 zero, CP0_WATCHHI
|
||||
|
||||
/* WP(Watch Pending), SW0/1 should be cleared */
|
||||
mtc0 zero, CP0_CAUSE
|
||||
|
||||
setup_c0_status 0 0
|
||||
setup_c0_status STATUS_SET 0
|
||||
|
||||
/* Init Timer */
|
||||
mtc0 zero, CP0_COUNT
|
||||
@ -116,21 +134,26 @@ reset:
|
||||
mtc0 t0, CP0_CONFIG
|
||||
#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
|
||||
nop
|
||||
.word _gp
|
||||
PTR _gp
|
||||
1:
|
||||
lw gp, 0(ra)
|
||||
PTR_L gp, 0(ra)
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
/* Initialize any external memory */
|
||||
la t9, lowlevel_init
|
||||
PTR_LA t9, lowlevel_init
|
||||
jalr t9
|
||||
nop
|
||||
|
||||
/* Initialize caches... */
|
||||
la t9, mips_cache_reset
|
||||
PTR_LA t9, mips_cache_reset
|
||||
jalr t9
|
||||
nop
|
||||
|
||||
@ -140,15 +163,15 @@ reset:
|
||||
#endif
|
||||
|
||||
/* Set up temporary stack */
|
||||
li t0, -16
|
||||
li t1, CONFIG_SYS_INIT_SP_ADDR
|
||||
PTR_LI t0, -16
|
||||
PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
|
||||
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
|
||||
move k0, sp # save gd pointer
|
||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||
li t2, CONFIG_SYS_MALLOC_F_LEN
|
||||
sub sp, sp, t2 # reserve space for early malloc
|
||||
PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN
|
||||
PTR_SUB sp, sp, t2 # reserve space for early malloc
|
||||
and sp, sp, t0 # force 16 byte alignment
|
||||
#endif
|
||||
move fp, sp
|
||||
@ -158,14 +181,14 @@ reset:
|
||||
1:
|
||||
sw zero, 0(t0)
|
||||
blt t0, t1, 1b
|
||||
addi t0, 4
|
||||
PTR_ADDI t0, 4
|
||||
|
||||
#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)
|
||||
#endif
|
||||
|
||||
la t9, board_init_f
|
||||
PTR_LA t9, board_init_f
|
||||
jr t9
|
||||
move ra, zero
|
||||
|
||||
@ -188,14 +211,14 @@ relocate_code:
|
||||
move s0, a1 # save gd in s0
|
||||
move s2, a2 # save destination address in s2
|
||||
|
||||
li t0, CONFIG_SYS_MONITOR_BASE
|
||||
sub s1, s2, t0 # s1 <-- relocation offset
|
||||
PTR_LI t0, CONFIG_SYS_MONITOR_BASE
|
||||
PTR_SUB s1, s2, t0 # s1 <-- relocation offset
|
||||
|
||||
la t3, in_ram
|
||||
lw t2, -12(t3) # t2 <-- __image_copy_end
|
||||
PTR_LA t3, in_ram
|
||||
PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end
|
||||
move t1, a2
|
||||
|
||||
add gp, s1 # adjust gp
|
||||
PTR_ADD gp, s1 # adjust gp
|
||||
|
||||
/*
|
||||
* t0 = source address
|
||||
@ -205,26 +228,26 @@ relocate_code:
|
||||
1:
|
||||
lw t3, 0(t0)
|
||||
sw t3, 0(t1)
|
||||
addu t0, 4
|
||||
PTR_ADDU t0, 4
|
||||
blt t0, t2, 1b
|
||||
addu t1, 4
|
||||
PTR_ADDU t1, 4
|
||||
|
||||
/* If caches were enabled, we would have to flush them here. */
|
||||
sub a1, t1, s2 # a1 <-- size
|
||||
la t9, flush_cache
|
||||
PTR_SUB a1, t1, s2 # a1 <-- size
|
||||
PTR_LA t9, flush_cache
|
||||
jalr t9
|
||||
move a0, s2 # a0 <-- destination address
|
||||
|
||||
/* Jump to where we've relocated ourselves */
|
||||
addi t0, s2, in_ram - _start
|
||||
PTR_ADDI t0, s2, in_ram - _start
|
||||
jr t0
|
||||
nop
|
||||
|
||||
.word __rel_dyn_end
|
||||
.word __rel_dyn_start
|
||||
.word __image_copy_end
|
||||
.word _GLOBAL_OFFSET_TABLE_
|
||||
.word num_got_entries
|
||||
PTR __rel_dyn_end
|
||||
PTR __rel_dyn_start
|
||||
PTR __image_copy_end
|
||||
PTR _GLOBAL_OFFSET_TABLE_
|
||||
PTR num_got_entries
|
||||
|
||||
in_ram:
|
||||
/*
|
||||
@ -233,46 +256,46 @@ in_ram:
|
||||
* GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
|
||||
* generated by GNU ld. Skip these reserved entries from relocation.
|
||||
*/
|
||||
lw t3, -4(t0) # t3 <-- num_got_entries
|
||||
lw t8, -8(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
|
||||
add t8, s1 # t8 now holds relocated _G_O_T_
|
||||
addi t8, t8, 8 # skipping first two entries
|
||||
li t2, 2
|
||||
PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries
|
||||
PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
|
||||
PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_
|
||||
PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries
|
||||
PTR_LI t2, 2
|
||||
1:
|
||||
lw t1, 0(t8)
|
||||
PTR_L t1, 0(t8)
|
||||
beqz t1, 2f
|
||||
add t1, s1
|
||||
sw t1, 0(t8)
|
||||
PTR_ADD t1, s1
|
||||
PTR_S t1, 0(t8)
|
||||
2:
|
||||
addi t2, 1
|
||||
PTR_ADDI t2, 1
|
||||
blt t2, t3, 1b
|
||||
addi t8, 4
|
||||
PTR_ADDI t8, PTRSIZE
|
||||
|
||||
/* Update dynamic relocations */
|
||||
lw t1, -16(t0) # t1 <-- __rel_dyn_start
|
||||
lw t2, -20(t0) # t2 <-- __rel_dyn_end
|
||||
PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start
|
||||
PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end
|
||||
|
||||
b 2f # skip first reserved entry
|
||||
addi t1, 8
|
||||
PTR_ADDI t1, 2 * PTRSIZE
|
||||
|
||||
1:
|
||||
lw t8, -4(t1) # t8 <-- relocation info
|
||||
|
||||
li t3, 3
|
||||
bne t8, t3, 2f # skip non R_MIPS_REL32 entries
|
||||
PTR_LI t3, MIPS_RELOC
|
||||
bne t8, t3, 2f # skip non-MIPS_RELOC entries
|
||||
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
|
||||
add t8, s1 # t8 <-- adjusted pointer
|
||||
PTR_L t8, 0(t3) # t8 <-- original pointer
|
||||
PTR_ADD t8, s1 # t8 <-- adjusted pointer
|
||||
|
||||
add t3, s1 # t3 <-- location to fix up in RAM
|
||||
sw t8, 0(t3)
|
||||
PTR_ADD t3, s1 # t3 <-- location to fix up in RAM
|
||||
PTR_S t8, 0(t3)
|
||||
|
||||
2:
|
||||
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
|
||||
@ -280,17 +303,17 @@ in_ram:
|
||||
* GOT is now relocated. Thus __bss_start and __bss_end can be
|
||||
* accessed directly via $gp.
|
||||
*/
|
||||
la t1, __bss_start # t1 <-- __bss_start
|
||||
la t2, __bss_end # t2 <-- __bss_end
|
||||
PTR_LA t1, __bss_start # t1 <-- __bss_start
|
||||
PTR_LA t2, __bss_end # t2 <-- __bss_end
|
||||
|
||||
1:
|
||||
sw zero, 0(t1)
|
||||
PTR_S zero, 0(t1)
|
||||
blt t1, t2, 1b
|
||||
addi t1, 4
|
||||
PTR_ADDI t1, PTRSIZE
|
||||
|
||||
move a0, s0 # a0 <-- gd
|
||||
move a1, s2
|
||||
la t9, board_init_r
|
||||
PTR_LA t9, board_init_r
|
||||
jr t9
|
||||
move ra, zero
|
||||
|
@ -11,6 +11,19 @@
|
||||
#ifndef __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
|
||||
*/
|
||||
|
@ -64,4 +64,9 @@
|
||||
|
||||
#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 */
|
||||
|
@ -5,6 +5,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += cache.o
|
||||
obj-y += cache_init.o
|
||||
obj-y += io.o
|
||||
|
||||
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
||||
|
@ -6,33 +6,8 @@
|
||||
*/
|
||||
|
||||
#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 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;
|
||||
}
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
#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 dlsize = dcache_line_size();
|
||||
unsigned long addr, aend;
|
||||
const void *addr, *aend;
|
||||
|
||||
/* aend will be miscalculated when size is zero, so we return here */
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
addr = start_addr & ~(dlsize - 1);
|
||||
aend = (start_addr + size - 1) & ~(dlsize - 1);
|
||||
addr = (const void *)(start_addr & ~(dlsize - 1));
|
||||
aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
|
||||
|
||||
if (ilsize == dlsize) {
|
||||
/* flush I-cache & D-cache simultaneously */
|
||||
while (1) {
|
||||
cache_op(HIT_WRITEBACK_INV_D, addr);
|
||||
cache_op(HIT_INVALIDATE_I, addr);
|
||||
mips_cache(HIT_WRITEBACK_INV_D, addr);
|
||||
mips_cache(HIT_INVALIDATE_I, addr);
|
||||
if (addr == aend)
|
||||
break;
|
||||
addr += dlsize;
|
||||
@ -97,17 +72,17 @@ void flush_cache(ulong start_addr, ulong size)
|
||||
|
||||
/* flush D-cache */
|
||||
while (1) {
|
||||
cache_op(HIT_WRITEBACK_INV_D, addr);
|
||||
mips_cache(HIT_WRITEBACK_INV_D, addr);
|
||||
if (addr == aend)
|
||||
break;
|
||||
addr += dlsize;
|
||||
}
|
||||
|
||||
/* flush I-cache */
|
||||
addr = start_addr & ~(ilsize - 1);
|
||||
aend = (start_addr + size - 1) & ~(ilsize - 1);
|
||||
addr = (const void *)(start_addr & ~(ilsize - 1));
|
||||
aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
|
||||
while (1) {
|
||||
cache_op(HIT_INVALIDATE_I, addr);
|
||||
mips_cache(HIT_INVALIDATE_I, addr);
|
||||
if (addr == aend)
|
||||
break;
|
||||
addr += ilsize;
|
||||
@ -117,11 +92,11 @@ void flush_cache(ulong start_addr, ulong size)
|
||||
void flush_dcache_range(ulong start_addr, ulong stop)
|
||||
{
|
||||
unsigned long lsize = dcache_line_size();
|
||||
unsigned long addr = start_addr & ~(lsize - 1);
|
||||
unsigned long aend = (stop - 1) & ~(lsize - 1);
|
||||
const void *addr = (const void *)(start_addr & ~(lsize - 1));
|
||||
const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
|
||||
|
||||
while (1) {
|
||||
cache_op(HIT_WRITEBACK_INV_D, addr);
|
||||
mips_cache(HIT_WRITEBACK_INV_D, addr);
|
||||
if (addr == aend)
|
||||
break;
|
||||
addr += lsize;
|
||||
@ -131,31 +106,13 @@ void flush_dcache_range(ulong start_addr, ulong stop)
|
||||
void invalidate_dcache_range(ulong start_addr, ulong stop)
|
||||
{
|
||||
unsigned long lsize = dcache_line_size();
|
||||
unsigned long addr = start_addr & ~(lsize - 1);
|
||||
unsigned long aend = (stop - 1) & ~(lsize - 1);
|
||||
const void *addr = (const void *)(start_addr & ~(lsize - 1));
|
||||
const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
|
||||
|
||||
while (1) {
|
||||
cache_op(HIT_INVALIDATE_D, addr);
|
||||
mips_cache(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();
|
||||
}
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
#ifdef CONFIG_SOC_AU1X00
|
||||
au1x00_enet_initialize(bis);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -18,18 +18,8 @@
|
||||
#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
|
||||
#endif
|
||||
|
||||
#define RA t9
|
||||
|
||||
#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)
|
||||
@ -51,56 +41,49 @@
|
||||
#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)
|
||||
.macro cache_loop curr, end, line_sz, op
|
||||
10: cache \op, 0(\curr)
|
||||
PTR_ADDU \curr, \curr, \line_sz
|
||||
bne \curr, \end, 10b
|
||||
.endm
|
||||
|
||||
/*
|
||||
* 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)
|
||||
.macro l1_info sz, line_sz, off
|
||||
.set push
|
||||
.set noat
|
||||
|
||||
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
|
||||
*
|
||||
@ -115,75 +98,23 @@ LEAF(mips_init_dcache)
|
||||
* RETURNS: N/A
|
||||
*
|
||||
*/
|
||||
NESTED(mips_cache_reset, 0, ra)
|
||||
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
|
||||
|
||||
LEAF(mips_cache_reset)
|
||||
#ifdef CONFIG_SYS_ICACHE_SIZE
|
||||
li t2, CONFIG_SYS_ICACHE_SIZE
|
||||
li t8, CONFIG_SYS_CACHELINE_SIZE
|
||||
#else
|
||||
/* Detect I-cache size. */
|
||||
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
|
||||
l1_info t2, t8, MIPS_CONF1_IA_SHIFT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_DCACHE_SIZE
|
||||
li t3, CONFIG_SYS_DCACHE_SIZE
|
||||
li t9, CONFIG_SYS_CACHELINE_SIZE
|
||||
#else
|
||||
/* Detect D-cache size. */
|
||||
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
|
||||
l1_info t3, t9, MIPS_CONF1_DA_SHIFT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
|
||||
/* Determine the largest L1 cache size */
|
||||
#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(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
|
||||
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.
|
||||
*/
|
||||
#endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
|
||||
|
||||
/*
|
||||
* 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,
|
||||
*/
|
||||
move a1, t2
|
||||
move a2, t8
|
||||
PTR_LA v1, mips_init_icache
|
||||
jalr v1
|
||||
blez t2, 1f
|
||||
PTR_LI t0, INDEX_BASE
|
||||
PTR_ADDU t1, t0, t2
|
||||
/* 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.
|
||||
*/
|
||||
move a1, t3
|
||||
move a2, t7
|
||||
PTR_LA v1, mips_init_dcache
|
||||
jalr v1
|
||||
1: blez t3, 3f
|
||||
PTR_LI t0, INDEX_BASE
|
||||
PTR_ADDU t1, t0, t3
|
||||
/* 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)
|
||||
|
||||
/*
|
@ -294,3 +294,9 @@ int au1x00_enet_initialize(bd_t *bis){
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
au1x00_enet_initialize(bis);
|
||||
return 0;
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ide.h>
|
||||
#include <netdev.h>
|
||||
#include <pci.h>
|
||||
#include <pci_gt64120.h>
|
||||
@ -123,6 +124,7 @@ void _machine_restart(void)
|
||||
|
||||
reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE);
|
||||
__raw_writel(GORESET, reset_base);
|
||||
mdelay(1000);
|
||||
}
|
||||
|
||||
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);
|
||||
val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT;
|
||||
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);
|
||||
}
|
||||
|
@ -71,6 +71,7 @@
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
#define CONFIG_SYS_MAXARGS 16
|
||||
|
||||
#define CONFIG_SYS_HUSH_PARSER
|
||||
#define CONFIG_AUTO_COMPLETE
|
||||
#define CONFIG_CMDLINE_EDITING
|
||||
|
||||
@ -106,6 +107,16 @@
|
||||
#define CONFIG_ENV_ADDR \
|
||||
(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
|
||||
*/
|
||||
@ -118,6 +129,8 @@
|
||||
|
||||
#define CONFIG_CMD_DATE
|
||||
#define CONFIG_CMD_DHCP
|
||||
#define CONFIG_CMD_ELF
|
||||
#define CONFIG_CMD_IDE
|
||||
#define CONFIG_CMD_PCI
|
||||
#define CONFIG_CMD_PING
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user