Support for MIPSsim, the cycle accurate MIPS simulator.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
b288f13587
commit
c78cbf49c4
|
@ -448,6 +448,17 @@ config MOMENCO_OCELOT_3
|
||||||
The Ocelot-3 is based off Discovery III System Controller and
|
The Ocelot-3 is based off Discovery III System Controller and
|
||||||
PMC-Sierra Rm79000 core.
|
PMC-Sierra Rm79000 core.
|
||||||
|
|
||||||
|
config MIPS_SIM
|
||||||
|
bool 'Support for MIPS simulator (MIPSsim)'
|
||||||
|
select DMA_NONCOHERENT
|
||||||
|
select IRQ_CPU
|
||||||
|
select SYS_SUPPORTS_32BIT_KERNEL
|
||||||
|
select SYS_SUPPORTS_BIG_ENDIAN
|
||||||
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
help
|
||||||
|
This option enables support for MIPS Technologies MIPSsim software
|
||||||
|
emulator.
|
||||||
|
|
||||||
config MOMENCO_JAGUAR_ATX
|
config MOMENCO_JAGUAR_ATX
|
||||||
bool "Support for Momentum Jaguar board"
|
bool "Support for Momentum Jaguar board"
|
||||||
select BOOT_ELF32
|
select BOOT_ELF32
|
||||||
|
|
|
@ -436,6 +436,13 @@ load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
|
||||||
core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/
|
core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/
|
||||||
load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
|
load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
|
||||||
|
|
||||||
|
#
|
||||||
|
# MIPS SIM
|
||||||
|
#
|
||||||
|
core-$(CONFIG_MIPS_SIM) += arch/mips/mips-boards/sim/
|
||||||
|
cflags-$(CONFIG_MIPS_SIM) += -Iinclude/asm-mips/mach-sim
|
||||||
|
load-$(CONFIG_MIPS_SIM) += 0x80100000
|
||||||
|
|
||||||
#
|
#
|
||||||
# Momentum Ocelot board
|
# Momentum Ocelot board
|
||||||
#
|
#
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
EXPORT(stext) # used for profiling
|
EXPORT(stext) # used for profiling
|
||||||
EXPORT(_stext)
|
EXPORT(_stext)
|
||||||
|
|
||||||
#ifdef CONFIG_QEMU
|
#if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM)
|
||||||
/*
|
/*
|
||||||
* Give us a fighting chance of running if execution beings at the
|
* Give us a fighting chance of running if execution beings at the
|
||||||
* kernel load address. This is needed because this platform does
|
* kernel load address. This is needed because this platform does
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can distribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License (Version 2) as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
obj-y := sim_setup.o sim_mem.o sim_time.o sim_printf.o sim_int.o sim_irq.o \
|
||||||
|
sim_cmdline.o
|
||||||
|
obj-$(CONFIG_SMP) += sim_smp.o
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Carsten Langgaard, carstenl@mips.com
|
||||||
|
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*
|
||||||
|
* Kernel command line creation using the prom monitor (YAMON) argc/argv.
|
||||||
|
*/
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
|
||||||
|
extern int prom_argc;
|
||||||
|
extern int *_prom_argv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
|
||||||
|
* This macro take care of sign extension.
|
||||||
|
*/
|
||||||
|
#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
|
||||||
|
|
||||||
|
char arcs_cmdline[CL_SIZE];
|
||||||
|
|
||||||
|
char * __init prom_getcmdline(void)
|
||||||
|
{
|
||||||
|
return &(arcs_cmdline[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void __init prom_init_cmdline(void)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
int actr;
|
||||||
|
|
||||||
|
actr = 1; /* Always ignore argv[0] */
|
||||||
|
|
||||||
|
cp = &(arcs_cmdline[0]);
|
||||||
|
while(actr < prom_argc) {
|
||||||
|
strcpy(cp, prom_argv(actr));
|
||||||
|
cp += strlen(prom_argv(actr));
|
||||||
|
*cp++ = ' ';
|
||||||
|
actr++;
|
||||||
|
}
|
||||||
|
if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
|
||||||
|
--cp;
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Carsten Langgaard, carstenl@mips.com
|
||||||
|
* Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*
|
||||||
|
* Interrupt exception dispatch code.
|
||||||
|
*/
|
||||||
|
#include <linux/config.h>
|
||||||
|
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/regdef.h>
|
||||||
|
#include <asm/stackframe.h>
|
||||||
|
|
||||||
|
/* A lot of complication here is taken away because:
|
||||||
|
*
|
||||||
|
* 1) We handle one interrupt and return, sitting in a loop and moving across
|
||||||
|
* all the pending IRQ bits in the cause register is _NOT_ the answer, the
|
||||||
|
* common case is one pending IRQ so optimize in that direction.
|
||||||
|
*
|
||||||
|
* 2) We need not check against bits in the status register IRQ mask, that
|
||||||
|
* would make this routine slow as hell.
|
||||||
|
*
|
||||||
|
* 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
|
||||||
|
* between like BSD spl() brain-damage.
|
||||||
|
*
|
||||||
|
* Furthermore, the IRQs on the MIPS board look basically (barring software
|
||||||
|
* IRQs which we don't use at all and all external interrupt sources are
|
||||||
|
* combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
|
||||||
|
*
|
||||||
|
* MIPS IRQ Source
|
||||||
|
* -------- ------
|
||||||
|
* 0 Software (ignored)
|
||||||
|
* 1 Software (ignored)
|
||||||
|
* 2 Combined hardware interrupt (hw0)
|
||||||
|
* 3 Hardware (ignored)
|
||||||
|
* 4 Hardware (ignored)
|
||||||
|
* 5 Hardware (ignored)
|
||||||
|
* 6 Hardware (ignored)
|
||||||
|
* 7 R4k timer (what we use)
|
||||||
|
*
|
||||||
|
* Note: On the SEAD board thing are a little bit different.
|
||||||
|
* Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
|
||||||
|
* wired to UART1.
|
||||||
|
*
|
||||||
|
* We handle the IRQ according to _our_ priority which is:
|
||||||
|
*
|
||||||
|
* Highest ---- R4k Timer
|
||||||
|
* Lowest ---- Combined hardware interrupt
|
||||||
|
*
|
||||||
|
* then we just return, if multiple IRQs are pending then we will just take
|
||||||
|
* another exception, big deal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
.set noat
|
||||||
|
.align 5
|
||||||
|
NESTED(mipsIRQ, PT_SIZE, sp)
|
||||||
|
SAVE_ALL
|
||||||
|
CLI
|
||||||
|
.set at
|
||||||
|
|
||||||
|
mfc0 s0, CP0_CAUSE # get irq bits
|
||||||
|
mfc0 s1, CP0_STATUS # get irq mask
|
||||||
|
and s0, s1
|
||||||
|
|
||||||
|
/* First we check for r4k counter/timer IRQ. */
|
||||||
|
andi a0, s0, CAUSEF_IP7
|
||||||
|
beq a0, zero, 1f
|
||||||
|
andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
|
||||||
|
|
||||||
|
/* Wheee, a timer interrupt. */
|
||||||
|
move a0, sp
|
||||||
|
jal mips_timer_interrupt
|
||||||
|
nop
|
||||||
|
|
||||||
|
j ret_from_irq
|
||||||
|
nop
|
||||||
|
|
||||||
|
1:
|
||||||
|
#if defined(CONFIG_MIPS_SEAD)
|
||||||
|
beq a0, zero, 1f
|
||||||
|
andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt
|
||||||
|
#else
|
||||||
|
beq a0, zero, 1f # delay slot, check hw3 interrupt
|
||||||
|
andi a0, s0, CAUSEF_IP5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wheee, combined hardware level zero interrupt. */
|
||||||
|
#if defined(CONFIG_MIPS_ATLAS)
|
||||||
|
jal atlas_hw0_irqdispatch
|
||||||
|
#elif defined(CONFIG_MIPS_MALTA)
|
||||||
|
jal malta_hw0_irqdispatch
|
||||||
|
#elif defined(CONFIG_MIPS_SEAD)
|
||||||
|
jal sead_hw0_irqdispatch
|
||||||
|
#else
|
||||||
|
#error "MIPS board not supported\n"
|
||||||
|
#endif
|
||||||
|
move a0, sp # delay slot
|
||||||
|
|
||||||
|
j ret_from_irq
|
||||||
|
nop # delay slot
|
||||||
|
|
||||||
|
1:
|
||||||
|
#if defined(CONFIG_MIPS_SEAD)
|
||||||
|
beq a0, zero, 1f
|
||||||
|
andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt
|
||||||
|
jal sead_hw1_irqdispatch
|
||||||
|
move a0, sp # delay slot
|
||||||
|
j ret_from_irq
|
||||||
|
nop # delay slot
|
||||||
|
1:
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_MIPS_MALTA)
|
||||||
|
beq a0, zero, 1f # check hw3 (coreHI) interrupt
|
||||||
|
nop
|
||||||
|
jal corehi_irqdispatch
|
||||||
|
move a0, sp
|
||||||
|
j ret_from_irq
|
||||||
|
nop
|
||||||
|
1:
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Here by mistake? This is possible, what can happen is that by the
|
||||||
|
* time we take the exception the IRQ pin goes low, so just leave if
|
||||||
|
* this is the case.
|
||||||
|
*/
|
||||||
|
move a1,s0
|
||||||
|
PRINT("Got interrupt: c0_cause = %08x\n")
|
||||||
|
mfc0 a1, CP0_EPC
|
||||||
|
PRINT("c0_epc = %08x\n")
|
||||||
|
|
||||||
|
j ret_from_irq
|
||||||
|
nop
|
||||||
|
END(mipsIRQ)
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
|
||||||
|
extern char arcs_cmdline[];
|
||||||
|
|
||||||
|
char * __init prom_getcmdline(void)
|
||||||
|
{
|
||||||
|
return arcs_cmdline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void __init prom_init_cmdline(void)
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 <linux/init.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/kernel_stat.h>
|
||||||
|
#include <asm/mips-boards/simint.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern void mips_cpu_irq_init(int);
|
||||||
|
|
||||||
|
extern asmlinkage void simIRQ(void);
|
||||||
|
|
||||||
|
asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
do_IRQ(2, regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init arch_init_irq(void)
|
||||||
|
{
|
||||||
|
/* Now safe to set the exception vector. */
|
||||||
|
set_except_vector(0, simIRQ);
|
||||||
|
|
||||||
|
mips_cpu_irq_init(MIPSCPU_INT_BASE);
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*
|
||||||
|
* Interrupt exception dispatch code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/config.h>
|
||||||
|
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/regdef.h>
|
||||||
|
#include <asm/stackframe.h>
|
||||||
|
|
||||||
|
#include <asm/mips-boards/simint.h>
|
||||||
|
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
.set noat
|
||||||
|
.align 5
|
||||||
|
NESTED(simIRQ, PT_SIZE, sp)
|
||||||
|
SAVE_ALL
|
||||||
|
CLI
|
||||||
|
.set at
|
||||||
|
|
||||||
|
mfc0 s0, CP0_CAUSE # get irq bits
|
||||||
|
mfc0 s1, CP0_STATUS # get irq mask
|
||||||
|
andi s0, ST0_IM # CAUSE.CE may be non-zero!
|
||||||
|
and s0, s1
|
||||||
|
|
||||||
|
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
|
||||||
|
.set mips32
|
||||||
|
clz a0, s0
|
||||||
|
.set mips0
|
||||||
|
negu a0
|
||||||
|
addu a0, 31-CAUSEB_IP
|
||||||
|
bltz a0, spurious
|
||||||
|
#else
|
||||||
|
beqz s0, spurious
|
||||||
|
li a0, 7
|
||||||
|
|
||||||
|
and t0, s0, 0xf000
|
||||||
|
sltiu t0, t0, 1
|
||||||
|
sll t0, 2
|
||||||
|
subu a0, t0
|
||||||
|
sll s0, t0
|
||||||
|
|
||||||
|
and t0, s0, 0xc000
|
||||||
|
sltiu t0, t0, 1
|
||||||
|
sll t0, 1
|
||||||
|
subu a0, t0
|
||||||
|
sll s0, t0
|
||||||
|
|
||||||
|
and t0, s0, 0x8000
|
||||||
|
sltiu t0, t0, 1
|
||||||
|
# sll t0, 0
|
||||||
|
subu a0, t0
|
||||||
|
# sll s0, t0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CASCADE_IRQ
|
||||||
|
li a1, CASCADE_IRQ
|
||||||
|
bne a0, a1, 1f
|
||||||
|
addu a0, MIPSCPU_INT_BASE
|
||||||
|
|
||||||
|
jal CASCADE_DISPATCH
|
||||||
|
move a0, sp
|
||||||
|
|
||||||
|
j ret_from_irq
|
||||||
|
nop
|
||||||
|
1:
|
||||||
|
#else
|
||||||
|
addu a0, MIPSCPU_INT_BASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jal do_IRQ
|
||||||
|
move a1, sp
|
||||||
|
|
||||||
|
j ret_from_irq
|
||||||
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
spurious:
|
||||||
|
j spurious_interrupt
|
||||||
|
nop
|
||||||
|
END(simIRQ)
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 <linux/init.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/bootmem.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
#include <asm/mips-boards/prom.h>
|
||||||
|
|
||||||
|
/*#define DEBUG*/
|
||||||
|
|
||||||
|
enum simmem_memtypes {
|
||||||
|
simmem_reserved = 0,
|
||||||
|
simmem_free,
|
||||||
|
};
|
||||||
|
struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static char *mtypes[3] = {
|
||||||
|
"SIM reserved memory",
|
||||||
|
"SIM free memory",
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* References to section boundaries */
|
||||||
|
extern char _end;
|
||||||
|
|
||||||
|
#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
|
||||||
|
|
||||||
|
|
||||||
|
struct prom_pmemblock * __init prom_getmdesc(void)
|
||||||
|
{
|
||||||
|
unsigned int memsize;
|
||||||
|
|
||||||
|
memsize = 0x02000000;
|
||||||
|
prom_printf("Setting default memory size 0x%08x\n", memsize);
|
||||||
|
|
||||||
|
memset(mdesc, 0, sizeof(mdesc));
|
||||||
|
|
||||||
|
mdesc[0].type = simmem_reserved;
|
||||||
|
mdesc[0].base = 0x00000000;
|
||||||
|
mdesc[0].size = 0x00001000;
|
||||||
|
|
||||||
|
mdesc[1].type = simmem_free;
|
||||||
|
mdesc[1].base = 0x00001000;
|
||||||
|
mdesc[1].size = 0x000ff000;
|
||||||
|
|
||||||
|
mdesc[2].type = simmem_reserved;
|
||||||
|
mdesc[2].base = 0x00100000;
|
||||||
|
mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
|
||||||
|
|
||||||
|
mdesc[3].type = simmem_free;
|
||||||
|
mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
|
||||||
|
mdesc[3].size = memsize - mdesc[3].base;
|
||||||
|
|
||||||
|
return &mdesc[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init prom_memtype_classify (unsigned int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case simmem_free:
|
||||||
|
return BOOT_MEM_RAM;
|
||||||
|
case simmem_reserved:
|
||||||
|
default:
|
||||||
|
return BOOT_MEM_RESERVED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init prom_meminit(void)
|
||||||
|
{
|
||||||
|
struct prom_pmemblock *p;
|
||||||
|
|
||||||
|
p = prom_getmdesc();
|
||||||
|
|
||||||
|
while (p->size) {
|
||||||
|
long type;
|
||||||
|
unsigned long base, size;
|
||||||
|
|
||||||
|
type = prom_memtype_classify (p->type);
|
||||||
|
base = p->base;
|
||||||
|
size = p->size;
|
||||||
|
|
||||||
|
add_memory_region(base, size, type);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long __init prom_free_prom_memory(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned long freed = 0;
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||||
|
if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
addr = boot_mem_map.map[i].addr;
|
||||||
|
while (addr < boot_mem_map.map[i].addr
|
||||||
|
+ boot_mem_map.map[i].size) {
|
||||||
|
ClearPageReserved(virt_to_page(__va(addr)));
|
||||||
|
set_page_count(virt_to_page(__va(addr)), 1);
|
||||||
|
free_page((unsigned long)__va(addr));
|
||||||
|
addr += PAGE_SIZE;
|
||||||
|
freed += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
|
||||||
|
|
||||||
|
return freed;
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Carsten Langgaard, carstenl@mips.com
|
||||||
|
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*
|
||||||
|
* Putting things on the screen/serial line using YAMONs facilities.
|
||||||
|
*/
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/serial_reg.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
static inline unsigned int serial_in(int offset)
|
||||||
|
{
|
||||||
|
return inb(0x3f8 + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void serial_out(int offset, int value)
|
||||||
|
{
|
||||||
|
outb(value, 0x3f8 + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int putPromChar(char c)
|
||||||
|
{
|
||||||
|
while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
serial_out(UART_TX, c);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char getPromChar(void)
|
||||||
|
{
|
||||||
|
while (!(serial_in(UART_LSR) & 1))
|
||||||
|
;
|
||||||
|
|
||||||
|
return serial_in(UART_RX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prom_printf(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int l;
|
||||||
|
char *p, *buf_end;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
buf_end = buf + l;
|
||||||
|
|
||||||
|
for (p = buf; p < buf_end; p++) {
|
||||||
|
/* Crude cr/nl handling is better than none */
|
||||||
|
if (*p == '\n')
|
||||||
|
putPromChar('\r');
|
||||||
|
putPromChar(*p);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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 <linux/config.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#include <linux/serial_core.h>
|
||||||
|
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/mips-boards/generic.h>
|
||||||
|
#include <asm/mips-boards/prom.h>
|
||||||
|
#include <asm/serial.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <asm/mips-boards/sim.h>
|
||||||
|
#include <asm/mips-boards/simint.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern void sim_time_init(void);
|
||||||
|
extern void sim_timer_setup(struct irqaction *irq);
|
||||||
|
static void __init serial_init(void);
|
||||||
|
unsigned int _isbonito = 0;
|
||||||
|
|
||||||
|
extern void __init sanitize_tlb_entries(void);
|
||||||
|
|
||||||
|
|
||||||
|
const char *get_system_type(void)
|
||||||
|
{
|
||||||
|
return "MIPSsim";
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init plat_setup(void)
|
||||||
|
{
|
||||||
|
set_io_port_base(0xbfd00000);
|
||||||
|
|
||||||
|
serial_init();
|
||||||
|
|
||||||
|
board_time_init = sim_time_init;
|
||||||
|
board_timer_setup = sim_timer_setup;
|
||||||
|
prom_printf("Linux started...\n");
|
||||||
|
|
||||||
|
#ifdef CONFIG_MT_SMP
|
||||||
|
sanitize_tlb_entries();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void prom_init(void)
|
||||||
|
{
|
||||||
|
set_io_port_base(0xbfd00000);
|
||||||
|
|
||||||
|
prom_printf("\nLINUX started...\n");
|
||||||
|
prom_init_cmdline();
|
||||||
|
prom_meminit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void __init serial_init(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SERIAL_8250
|
||||||
|
struct uart_port s;
|
||||||
|
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
|
||||||
|
s.iobase = 0x3f8;
|
||||||
|
|
||||||
|
/* hardware int 4 - the serial int, is CPU int 6
|
||||||
|
but poll for now */
|
||||||
|
s.irq = 0;
|
||||||
|
s.uartclk = BASE_BAUD * 16;
|
||||||
|
s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST;
|
||||||
|
s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST;
|
||||||
|
s.regshift = 0;
|
||||||
|
s.timeout = 4;
|
||||||
|
|
||||||
|
if (early_serial_setup(&s) != 0) {
|
||||||
|
prom_printf(KERN_ERR "Serial setup failed!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Simulator Platform-specific hooks for SMP operation
|
||||||
|
*/
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <asm/atomic.h>
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/hardirq.h>
|
||||||
|
#include <asm/mmu_context.h>
|
||||||
|
#include <asm/smp.h>
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
#include <asm/smtc_ipi.h>
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
|
||||||
|
/* VPE/SMP Prototype implements platform interfaces directly */
|
||||||
|
#if !defined(CONFIG_MIPS_MT_SMP)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cause the specified action to be performed on a targeted "CPU"
|
||||||
|
*/
|
||||||
|
|
||||||
|
void core_send_ipi(int cpu, unsigned int action)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
void smtc_send_ipi(int, int, unsigned int);
|
||||||
|
|
||||||
|
smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __init prom_build_cpu_map(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
extern int mipsmt_build_cpu_map(int startslot);
|
||||||
|
int nextslot;
|
||||||
|
|
||||||
|
cpus_clear(phys_cpu_present_map);
|
||||||
|
|
||||||
|
/* Register the boot CPU */
|
||||||
|
|
||||||
|
smp_prepare_boot_cpu();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As of November, 2004, MIPSsim only simulates one core
|
||||||
|
* at a time. However, that core may be a MIPS MT core
|
||||||
|
* with multiple virtual processors and thread contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (read_c0_config3() & (1<<2)) {
|
||||||
|
nextslot = mipsmt_build_cpu_map(1);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Platform "CPU" startup hook
|
||||||
|
*/
|
||||||
|
|
||||||
|
void prom_boot_secondary(int cpu, struct task_struct *idle)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
extern void smtc_boot_secondary(int cpu, struct task_struct *t);
|
||||||
|
|
||||||
|
smtc_boot_secondary(cpu, idle);
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Post-config but pre-boot cleanup entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
void prom_init_secondary(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
void smtc_init_secondary(void);
|
||||||
|
|
||||||
|
smtc_init_secondary();
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Platform SMP pre-initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
void prom_prepare_cpus(unsigned int max_cpus)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
void mipsmt_prepare_cpus(int c);
|
||||||
|
/*
|
||||||
|
* As noted above, we can assume a single CPU for now
|
||||||
|
* but it may be multithreaded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (read_c0_config3() & (1<<2)) {
|
||||||
|
mipsmt_prepare_cpus(max_cpus);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SMP initialization finalization entry point
|
||||||
|
*/
|
||||||
|
|
||||||
|
void prom_smp_finish(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
void smtc_smp_finish(void);
|
||||||
|
|
||||||
|
smtc_smp_finish();
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hook for after all CPUs are online
|
||||||
|
*/
|
||||||
|
|
||||||
|
void prom_cpus_done(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_MIPS_MT_SMTC
|
||||||
|
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_MIPS32R2_MT_SMP */
|
|
@ -0,0 +1,215 @@
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/kernel_stat.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
#include <asm/hardirq.h>
|
||||||
|
#include <asm/div64.h>
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/mc146818rtc.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/ptrace.h>
|
||||||
|
#include <asm/hardirq.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/div64.h>
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <asm/mc146818-time.h>
|
||||||
|
#include <asm/msc01_ic.h>
|
||||||
|
|
||||||
|
#include <asm/mips-boards/generic.h>
|
||||||
|
#include <asm/mips-boards/prom.h>
|
||||||
|
#include <asm/mips-boards/simint.h>
|
||||||
|
#include <asm/mc146818-time.h>
|
||||||
|
#include <asm/smp.h>
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long cpu_khz;
|
||||||
|
|
||||||
|
extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
|
||||||
|
|
||||||
|
irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU 0 handles the global timer interrupt job
|
||||||
|
* resets count/compare registers to trigger next timer int.
|
||||||
|
*/
|
||||||
|
#ifndef CONFIG_MIPS_MT_SMTC
|
||||||
|
if (cpu == 0) {
|
||||||
|
timer_interrupt(irq, dev_id, regs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Everyone else needs to reset the timer int here as
|
||||||
|
ll_local_timer_interrupt doesn't */
|
||||||
|
/*
|
||||||
|
* FIXME: need to cope with counter underflow.
|
||||||
|
* More support needs to be added to kernel/time for
|
||||||
|
* counter/timer interrupts on multiple CPU's
|
||||||
|
*/
|
||||||
|
write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
|
||||||
|
}
|
||||||
|
#else /* SMTC */
|
||||||
|
/*
|
||||||
|
* In SMTC system, one Count/Compare set exists per VPE.
|
||||||
|
* Which TC within a VPE gets the interrupt is essentially
|
||||||
|
* random - we only know that it shouldn't be one with
|
||||||
|
* IXMT set. Whichever TC gets the interrupt needs to
|
||||||
|
* send special interprocessor interrupts to the other
|
||||||
|
* TCs to make sure that they schedule, etc.
|
||||||
|
*
|
||||||
|
* That code is specific to the SMTC kernel, not to
|
||||||
|
* the simulation platform, so it's invoked from
|
||||||
|
* the general MIPS timer_interrupt routine.
|
||||||
|
*
|
||||||
|
* We have a problem in that the interrupt vector code
|
||||||
|
* had to turn off the timer IM bit to avoid redundant
|
||||||
|
* entries, but we may never get to mips_cpu_irq_end
|
||||||
|
* to turn it back on again if the scheduler gets
|
||||||
|
* involved. So we clear the pending timer here,
|
||||||
|
* and re-enable the mask...
|
||||||
|
*/
|
||||||
|
|
||||||
|
int vpflags = dvpe();
|
||||||
|
write_c0_compare (read_c0_count() - 1);
|
||||||
|
clear_c0_cause(0x100 << MIPSCPU_INT_CPUCTR);
|
||||||
|
set_c0_status(0x100 << MIPSCPU_INT_CPUCTR);
|
||||||
|
irq_enable_hazard();
|
||||||
|
evpe(vpflags);
|
||||||
|
|
||||||
|
if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id, regs);
|
||||||
|
else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
|
||||||
|
smtc_timer_broadcast(cpu_data[cpu].vpe_id);
|
||||||
|
|
||||||
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* every CPU should do profiling and process accounting
|
||||||
|
*/
|
||||||
|
local_timer_interrupt (irq, dev_id, regs);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
#else
|
||||||
|
return timer_interrupt (irq, dev_id, regs);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
|
||||||
|
*/
|
||||||
|
static unsigned int __init estimate_cpu_frequency(void)
|
||||||
|
{
|
||||||
|
unsigned int prid = read_c0_prid() & 0xffff00;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/*
|
||||||
|
* hardwire the board frequency to 12MHz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
|
||||||
|
(prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
|
||||||
|
count = 12000000;
|
||||||
|
else
|
||||||
|
count = 6000000;
|
||||||
|
#else
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
/* Start counter exactly on falling edge of update flag */
|
||||||
|
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
|
||||||
|
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
|
||||||
|
|
||||||
|
/* Start r4k counter. */
|
||||||
|
write_c0_count(0);
|
||||||
|
|
||||||
|
/* Read counter exactly on falling edge of update flag */
|
||||||
|
while (CMOS_READ(RTC_REG_A) & RTC_UIP);
|
||||||
|
while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
|
||||||
|
|
||||||
|
count = read_c0_count();
|
||||||
|
|
||||||
|
/* restore interrupts */
|
||||||
|
local_irq_restore(flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mips_hpt_frequency = count;
|
||||||
|
|
||||||
|
if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
|
||||||
|
(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
|
||||||
|
count *= 2;
|
||||||
|
|
||||||
|
count += 5000; /* round */
|
||||||
|
count -= count%10000;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init sim_time_init(void)
|
||||||
|
{
|
||||||
|
unsigned int est_freq, flags;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
|
||||||
|
/* Set Data mode - binary. */
|
||||||
|
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
|
||||||
|
|
||||||
|
|
||||||
|
est_freq = estimate_cpu_frequency ();
|
||||||
|
|
||||||
|
printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
|
||||||
|
(est_freq%1000000)*100/1000000);
|
||||||
|
|
||||||
|
cpu_khz = est_freq / 1000;
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mips_cpu_timer_irq;
|
||||||
|
|
||||||
|
static void mips_timer_dispatch (struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
do_IRQ (mips_cpu_timer_irq, regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void __init sim_timer_setup(struct irqaction *irq)
|
||||||
|
{
|
||||||
|
if (cpu_has_veic) {
|
||||||
|
set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
|
||||||
|
mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (cpu_has_vint)
|
||||||
|
set_vi_handler(MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
|
||||||
|
mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we are using the cpu counter for timer interrupts */
|
||||||
|
irq->handler = sim_timer_interrupt;
|
||||||
|
setup_irq(mips_cpu_timer_irq, irq);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* irq_desc(riptor) is a global resource, when the interrupt overlaps
|
||||||
|
on seperate cpu's the first one tries to handle the second interrupt.
|
||||||
|
The effect is that the int remains disabled on the second cpu.
|
||||||
|
Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
|
||||||
|
irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* to generate the first timer interrupt */
|
||||||
|
write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ));
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003, 2004 Chris Dearman
|
||||||
|
*/
|
||||||
|
#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
|
||||||
|
#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU feature overrides for MIPS boards
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_CPU_MIPS32
|
||||||
|
#define cpu_has_tlb 1
|
||||||
|
#define cpu_has_4kex 1
|
||||||
|
#define cpu_has_4ktlb 1
|
||||||
|
#define cpu_has_fpu 0
|
||||||
|
/* #define cpu_has_32fpr ? */
|
||||||
|
#define cpu_has_counter 1
|
||||||
|
/* #define cpu_has_watch ? */
|
||||||
|
#define cpu_has_divec 1
|
||||||
|
#define cpu_has_vce 0
|
||||||
|
/* #define cpu_has_cache_cdex_p ? */
|
||||||
|
/* #define cpu_has_cache_cdex_s ? */
|
||||||
|
/* #define cpu_has_prefetch ? */
|
||||||
|
#define cpu_has_mcheck 1
|
||||||
|
/* #define cpu_has_ejtag ? */
|
||||||
|
#define cpu_has_llsc 1
|
||||||
|
/* #define cpu_has_vtag_icache ? */
|
||||||
|
/* #define cpu_has_dc_aliases ? */
|
||||||
|
/* #define cpu_has_ic_fills_f_dc ? */
|
||||||
|
#define cpu_has_nofpuex 0
|
||||||
|
/* #define cpu_has_64bits ? */
|
||||||
|
/* #define cpu_has_64bit_zero_reg ? */
|
||||||
|
/* #define cpu_has_subset_pcaches ? */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_MIPS64
|
||||||
|
#define cpu_has_tlb 1
|
||||||
|
#define cpu_has_4kex 1
|
||||||
|
#define cpu_has_4ktlb 1
|
||||||
|
/* #define cpu_has_fpu ? */
|
||||||
|
/* #define cpu_has_32fpr ? */
|
||||||
|
#define cpu_has_counter 1
|
||||||
|
/* #define cpu_has_watch ? */
|
||||||
|
#define cpu_has_divec 1
|
||||||
|
#define cpu_has_vce 0
|
||||||
|
/* #define cpu_has_cache_cdex_p ? */
|
||||||
|
/* #define cpu_has_cache_cdex_s ? */
|
||||||
|
/* #define cpu_has_prefetch ? */
|
||||||
|
#define cpu_has_mcheck 1
|
||||||
|
/* #define cpu_has_ejtag ? */
|
||||||
|
#define cpu_has_llsc 1
|
||||||
|
/* #define cpu_has_vtag_icache ? */
|
||||||
|
/* #define cpu_has_dc_aliases ? */
|
||||||
|
/* #define cpu_has_ic_fills_f_dc ? */
|
||||||
|
#define cpu_has_nofpuex 0
|
||||||
|
/* #define cpu_has_64bits ? */
|
||||||
|
/* #define cpu_has_64bit_zero_reg ? */
|
||||||
|
/* #define cpu_has_subset_pcaches ? */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ASM_MIPS_BOARDS_SIM_H
|
||||||
|
#define _ASM_MIPS_BOARDS_SIM_H
|
||||||
|
|
||||||
|
#define STATS_ON 1
|
||||||
|
#define STATS_OFF 2
|
||||||
|
#define STATS_CLEAR 3
|
||||||
|
#define STATS_DUMP 4
|
||||||
|
#define TRACE_ON 5
|
||||||
|
#define TRACE_OFF 6
|
||||||
|
|
||||||
|
|
||||||
|
#define simcfg(code) \
|
||||||
|
({ \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"sltiu $0,$0, %0" \
|
||||||
|
::"i"(code) \
|
||||||
|
); \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope 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.
|
||||||
|
*/
|
||||||
|
#ifndef _MIPS_SIMINT_H
|
||||||
|
#define _MIPS_SIMINT_H
|
||||||
|
|
||||||
|
|
||||||
|
#define SIM_INT_BASE 0
|
||||||
|
#define MIPSCPU_INT_MB0 2
|
||||||
|
#define MIPSCPU_INT_BASE 16
|
||||||
|
#define MIPS_CPU_TIMER_IRQ 7
|
||||||
|
|
||||||
|
|
||||||
|
#define MIPSCPU_INT_CPUCTR 7
|
||||||
|
|
||||||
|
#define MSC01E_INT_BASE 64
|
||||||
|
|
||||||
|
#define MIPSCPU_INT_CPUCTR 7
|
||||||
|
#define MSC01E_INT_CPUCTR 11
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue