diff options
Diffstat (limited to 'arch/mips/mipssim')
| -rw-r--r-- | arch/mips/mipssim/Makefile | 23 | ||||
| -rw-r--r-- | arch/mips/mipssim/Platform | 6 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_console.c | 40 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_int.c | 87 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_mem.c | 115 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_platform.c | 35 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_setup.c | 99 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_smtc.c | 117 | ||||
| -rw-r--r-- | arch/mips/mipssim/sim_time.c | 116 |
9 files changed, 638 insertions, 0 deletions
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile new file mode 100644 index 00000000000..01410a3f172 --- /dev/null +++ b/arch/mips/mipssim/Makefile | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | # | ||
| 2 | # Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
| 3 | # Copyright (C) 2007 MIPS Technologies, Inc. | ||
| 4 | # written by Ralf Baechle (ralf@linux-mips.org) | ||
| 5 | # | ||
| 6 | # This program is free software; you can distribute it and/or modify it | ||
| 7 | # under the terms of the GNU General Public License (Version 2) as | ||
| 8 | # published by the Free Software Foundation. | ||
| 9 | # | ||
| 10 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 13 | # for more details. | ||
| 14 | # | ||
| 15 | # You should have received a copy of the GNU General Public License along | ||
| 16 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
| 17 | # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 18 | # | ||
| 19 | |||
| 20 | obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o | ||
| 21 | |||
| 22 | obj-$(CONFIG_EARLY_PRINTK) += sim_console.o | ||
| 23 | obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o | ||
diff --git a/arch/mips/mipssim/Platform b/arch/mips/mipssim/Platform new file mode 100644 index 00000000000..3df60b8a12e --- /dev/null +++ b/arch/mips/mipssim/Platform | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | # | ||
| 2 | # MIPS SIM | ||
| 3 | # | ||
| 4 | platform-$(CONFIG_MIPS_SIM) += mipssim/ | ||
| 5 | cflags-$(CONFIG_MIPS_SIM) += -I$(srctree)/arch/mips/include/asm/mach-mipssim | ||
| 6 | load-$(CONFIG_MIPS_SIM) += 0x80100000 | ||
diff --git a/arch/mips/mipssim/sim_console.c b/arch/mips/mipssim/sim_console.c new file mode 100644 index 00000000000..a2f41672cd5 --- /dev/null +++ b/arch/mips/mipssim/sim_console.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can distribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License (Version 2) as | ||
| 4 | * published by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 7 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 8 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 9 | * for more details. | ||
| 10 | * | ||
| 11 | * You should have received a copy of the GNU General Public License along | ||
| 12 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 13 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 14 | * | ||
| 15 | * Carsten Langgaard, carstenl@mips.com | ||
| 16 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
| 17 | * Copyright (C) 2007 MIPS Technologies, Inc. | ||
| 18 | * written by Ralf Baechle | ||
| 19 | */ | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/serial_reg.h> | ||
| 23 | |||
| 24 | static inline unsigned int serial_in(int offset) | ||
| 25 | { | ||
| 26 | return inb(0x3f8 + offset); | ||
| 27 | } | ||
| 28 | |||
| 29 | static inline void serial_out(int offset, int value) | ||
| 30 | { | ||
| 31 | outb(value, 0x3f8 + offset); | ||
| 32 | } | ||
| 33 | |||
| 34 | void __init prom_putchar(char c) | ||
| 35 | { | ||
| 36 | while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) | ||
| 37 | ; | ||
| 38 | |||
| 39 | serial_out(UART_TX, c); | ||
| 40 | } | ||
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c new file mode 100644 index 00000000000..5c779be6f08 --- /dev/null +++ b/arch/mips/mipssim/sim_int.c | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can distribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License (Version 2) as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 11 | * for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/sched.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/kernel_stat.h> | ||
| 22 | #include <asm/mips-boards/simint.h> | ||
| 23 | #include <asm/irq_cpu.h> | ||
| 24 | |||
| 25 | static inline int clz(unsigned long x) | ||
| 26 | { | ||
| 27 | __asm__( | ||
| 28 | " .set push \n" | ||
| 29 | " .set mips32 \n" | ||
| 30 | " clz %0, %1 \n" | ||
| 31 | " .set pop \n" | ||
| 32 | : "=r" (x) | ||
| 33 | : "r" (x)); | ||
| 34 | |||
| 35 | return x; | ||
| 36 | } | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Version of ffs that only looks at bits 12..15. | ||
| 40 | */ | ||
| 41 | static inline unsigned int irq_ffs(unsigned int pending) | ||
| 42 | { | ||
| 43 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
| 44 | return -clz(pending) + 31 - CAUSEB_IP; | ||
| 45 | #else | ||
| 46 | unsigned int a0 = 7; | ||
| 47 | unsigned int t0; | ||
| 48 | |||
| 49 | t0 = s0 & 0xf000; | ||
| 50 | t0 = t0 < 1; | ||
| 51 | t0 = t0 << 2; | ||
| 52 | a0 = a0 - t0; | ||
| 53 | s0 = s0 << t0; | ||
| 54 | |||
| 55 | t0 = s0 & 0xc000; | ||
| 56 | t0 = t0 < 1; | ||
| 57 | t0 = t0 << 1; | ||
| 58 | a0 = a0 - t0; | ||
| 59 | s0 = s0 << t0; | ||
| 60 | |||
| 61 | t0 = s0 & 0x8000; | ||
| 62 | t0 = t0 < 1; | ||
| 63 | /* t0 = t0 << 2; */ | ||
| 64 | a0 = a0 - t0; | ||
| 65 | /* s0 = s0 << t0; */ | ||
| 66 | |||
| 67 | return a0; | ||
| 68 | #endif | ||
| 69 | } | ||
| 70 | |||
| 71 | asmlinkage void plat_irq_dispatch(void) | ||
| 72 | { | ||
| 73 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
| 74 | int irq; | ||
| 75 | |||
| 76 | irq = irq_ffs(pending); | ||
| 77 | |||
| 78 | if (irq > 0) | ||
| 79 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
| 80 | else | ||
| 81 | spurious_interrupt(); | ||
| 82 | } | ||
| 83 | |||
| 84 | void __init arch_init_irq(void) | ||
| 85 | { | ||
| 86 | mips_cpu_irq_init(); | ||
| 87 | } | ||
diff --git a/arch/mips/mipssim/sim_mem.c b/arch/mips/mipssim/sim_mem.c new file mode 100644 index 00000000000..953d836a771 --- /dev/null +++ b/arch/mips/mipssim/sim_mem.c | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can distribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License (Version 2) as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 11 | * for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/mm.h> | ||
| 20 | #include <linux/bootmem.h> | ||
| 21 | #include <linux/pfn.h> | ||
| 22 | |||
| 23 | #include <asm/bootinfo.h> | ||
| 24 | #include <asm/page.h> | ||
| 25 | #include <asm/sections.h> | ||
| 26 | |||
| 27 | #include <asm/mips-boards/prom.h> | ||
| 28 | |||
| 29 | /*#define DEBUG*/ | ||
| 30 | |||
| 31 | enum simmem_memtypes { | ||
| 32 | simmem_reserved = 0, | ||
| 33 | simmem_free, | ||
| 34 | }; | ||
| 35 | struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; | ||
| 36 | |||
| 37 | #ifdef DEBUG | ||
| 38 | static char *mtypes[3] = { | ||
| 39 | "SIM reserved memory", | ||
| 40 | "SIM free memory", | ||
| 41 | }; | ||
| 42 | #endif | ||
| 43 | |||
| 44 | struct prom_pmemblock * __init prom_getmdesc(void) | ||
| 45 | { | ||
| 46 | unsigned int memsize; | ||
| 47 | |||
| 48 | memsize = 0x02000000; | ||
| 49 | pr_info("Setting default memory size 0x%08x\n", memsize); | ||
| 50 | |||
| 51 | memset(mdesc, 0, sizeof(mdesc)); | ||
| 52 | |||
| 53 | mdesc[0].type = simmem_reserved; | ||
| 54 | mdesc[0].base = 0x00000000; | ||
| 55 | mdesc[0].size = 0x00001000; | ||
| 56 | |||
| 57 | mdesc[1].type = simmem_free; | ||
| 58 | mdesc[1].base = 0x00001000; | ||
| 59 | mdesc[1].size = 0x000ff000; | ||
| 60 | |||
| 61 | mdesc[2].type = simmem_reserved; | ||
| 62 | mdesc[2].base = 0x00100000; | ||
| 63 | mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base; | ||
| 64 | |||
| 65 | mdesc[3].type = simmem_free; | ||
| 66 | mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end)); | ||
| 67 | mdesc[3].size = memsize - mdesc[3].base; | ||
| 68 | |||
| 69 | return &mdesc[0]; | ||
| 70 | } | ||
| 71 | |||
| 72 | static int __init prom_memtype_classify(unsigned int type) | ||
| 73 | { | ||
| 74 | switch (type) { | ||
| 75 | case simmem_free: | ||
| 76 | return BOOT_MEM_RAM; | ||
| 77 | case simmem_reserved: | ||
| 78 | default: | ||
| 79 | return BOOT_MEM_RESERVED; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | void __init prom_meminit(void) | ||
| 84 | { | ||
| 85 | struct prom_pmemblock *p; | ||
| 86 | |||
| 87 | p = prom_getmdesc(); | ||
| 88 | |||
| 89 | while (p->size) { | ||
| 90 | long type; | ||
| 91 | unsigned long base, size; | ||
| 92 | |||
| 93 | type = prom_memtype_classify(p->type); | ||
| 94 | base = p->base; | ||
| 95 | size = p->size; | ||
| 96 | |||
| 97 | add_memory_region(base, size, type); | ||
| 98 | p++; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | void __init prom_free_prom_memory(void) | ||
| 103 | { | ||
| 104 | int i; | ||
| 105 | unsigned long addr; | ||
| 106 | |||
| 107 | for (i = 0; i < boot_mem_map.nr_map; i++) { | ||
| 108 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | ||
| 109 | continue; | ||
| 110 | |||
| 111 | addr = boot_mem_map.map[i].addr; | ||
| 112 | free_init_pages("prom memory", | ||
| 113 | addr, addr + boot_mem_map.map[i].size); | ||
| 114 | } | ||
| 115 | } | ||
diff --git a/arch/mips/mipssim/sim_platform.c b/arch/mips/mipssim/sim_platform.c new file mode 100644 index 00000000000..53210a8c5de --- /dev/null +++ b/arch/mips/mipssim/sim_platform.c | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 by Ralf Baechle (ralf@linux-mips.org) | ||
| 7 | */ | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <linux/if_ether.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | |||
| 13 | static char mipsnet_string[] = "mipsnet"; | ||
| 14 | |||
| 15 | static struct platform_device eth1_device = { | ||
| 16 | .name = mipsnet_string, | ||
| 17 | .id = 0, | ||
| 18 | }; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Create a platform device for the GPI port that receives the | ||
| 22 | * image data from the embedded camera. | ||
| 23 | */ | ||
| 24 | static int __init mipsnet_devinit(void) | ||
| 25 | { | ||
| 26 | int err; | ||
| 27 | |||
| 28 | err = platform_device_register(ð1_device); | ||
| 29 | if (err) | ||
| 30 | printk(KERN_ERR "%s: registration failed\n", mipsnet_string); | ||
| 31 | |||
| 32 | return err; | ||
| 33 | } | ||
| 34 | |||
| 35 | device_initcall(mipsnet_devinit); | ||
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c new file mode 100644 index 00000000000..256e0cdaa49 --- /dev/null +++ b/arch/mips/mipssim/sim_setup.c | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can distribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License (Version 2) as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 11 | * for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/string.h> | ||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/irq.h> | ||
| 24 | #include <linux/ioport.h> | ||
| 25 | #include <linux/tty.h> | ||
| 26 | #include <linux/serial.h> | ||
| 27 | #include <linux/serial_core.h> | ||
| 28 | #include <linux/serial_8250.h> | ||
| 29 | |||
| 30 | #include <asm/cpu.h> | ||
| 31 | #include <asm/bootinfo.h> | ||
| 32 | #include <asm/mips-boards/generic.h> | ||
| 33 | #include <asm/mips-boards/prom.h> | ||
| 34 | #include <asm/time.h> | ||
| 35 | #include <asm/mips-boards/sim.h> | ||
| 36 | #include <asm/mips-boards/simint.h> | ||
| 37 | #include <asm/smp-ops.h> | ||
| 38 | |||
| 39 | |||
| 40 | static void __init serial_init(void); | ||
| 41 | unsigned int _isbonito; | ||
| 42 | |||
| 43 | const char *get_system_type(void) | ||
| 44 | { | ||
| 45 | return "MIPSsim"; | ||
| 46 | } | ||
| 47 | |||
| 48 | void __init plat_mem_setup(void) | ||
| 49 | { | ||
| 50 | set_io_port_base(0xbfd00000); | ||
| 51 | |||
| 52 | serial_init(); | ||
| 53 | } | ||
| 54 | |||
| 55 | extern struct plat_smp_ops ssmtc_smp_ops; | ||
| 56 | |||
| 57 | void __init prom_init(void) | ||
| 58 | { | ||
| 59 | set_io_port_base(0xbfd00000); | ||
| 60 | |||
| 61 | prom_meminit(); | ||
| 62 | |||
| 63 | if (cpu_has_mipsmt) { | ||
| 64 | if (!register_vsmp_smp_ops()) | ||
| 65 | return; | ||
| 66 | |||
| 67 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 68 | register_smp_ops(&ssmtc_smp_ops); | ||
| 69 | return; | ||
| 70 | #endif | ||
| 71 | } | ||
| 72 | |||
| 73 | register_up_smp_ops(); | ||
| 74 | } | ||
| 75 | |||
| 76 | static void __init serial_init(void) | ||
| 77 | { | ||
| 78 | #ifdef CONFIG_SERIAL_8250 | ||
| 79 | struct uart_port s; | ||
| 80 | |||
| 81 | memset(&s, 0, sizeof(s)); | ||
| 82 | |||
| 83 | s.iobase = 0x3f8; | ||
| 84 | |||
| 85 | /* hardware int 4 - the serial int, is CPU int 6 | ||
| 86 | but poll for now */ | ||
| 87 | s.irq = 0; | ||
| 88 | s.uartclk = 1843200; | ||
| 89 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | ||
| 90 | s.iotype = UPIO_PORT; | ||
| 91 | s.regshift = 0; | ||
| 92 | s.timeout = 4; | ||
| 93 | |||
| 94 | if (early_serial_setup(&s) != 0) { | ||
| 95 | printk(KERN_ERR "Serial setup failed!\n"); | ||
| 96 | } | ||
| 97 | |||
| 98 | #endif | ||
| 99 | } | ||
diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c new file mode 100644 index 00000000000..915063991f6 --- /dev/null +++ b/arch/mips/mipssim/sim_smtc.c | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can distribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License (Version 2) as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 11 | * for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | /* | ||
| 19 | * Simulator Platform-specific hooks for SMTC operation | ||
| 20 | */ | ||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/sched.h> | ||
| 23 | #include <linux/cpumask.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/smp.h> | ||
| 26 | |||
| 27 | #include <linux/atomic.h> | ||
| 28 | #include <asm/cpu.h> | ||
| 29 | #include <asm/processor.h> | ||
| 30 | #include <asm/smtc.h> | ||
| 31 | #include <asm/system.h> | ||
| 32 | #include <asm/mmu_context.h> | ||
| 33 | #include <asm/smtc_ipi.h> | ||
| 34 | |||
| 35 | /* VPE/SMP Prototype implements platform interfaces directly */ | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Cause the specified action to be performed on a targeted "CPU" | ||
| 39 | */ | ||
| 40 | |||
| 41 | static void ssmtc_send_ipi_single(int cpu, unsigned int action) | ||
| 42 | { | ||
| 43 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | ||
| 44 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | ||
| 45 | } | ||
| 46 | |||
| 47 | static inline void ssmtc_send_ipi_mask(const struct cpumask *mask, | ||
| 48 | unsigned int action) | ||
| 49 | { | ||
| 50 | unsigned int i; | ||
| 51 | |||
| 52 | for_each_cpu(i, mask) | ||
| 53 | ssmtc_send_ipi_single(i, action); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Post-config but pre-boot cleanup entry point | ||
| 58 | */ | ||
| 59 | static void __cpuinit ssmtc_init_secondary(void) | ||
| 60 | { | ||
| 61 | smtc_init_secondary(); | ||
| 62 | } | ||
| 63 | |||
| 64 | /* | ||
| 65 | * SMP initialization finalization entry point | ||
| 66 | */ | ||
| 67 | static void __cpuinit ssmtc_smp_finish(void) | ||
| 68 | { | ||
| 69 | smtc_smp_finish(); | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Hook for after all CPUs are online | ||
| 74 | */ | ||
| 75 | static void ssmtc_cpus_done(void) | ||
| 76 | { | ||
| 77 | } | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Platform "CPU" startup hook | ||
| 81 | */ | ||
| 82 | static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle) | ||
| 83 | { | ||
| 84 | smtc_boot_secondary(cpu, idle); | ||
| 85 | } | ||
| 86 | |||
| 87 | static void __init ssmtc_smp_setup(void) | ||
| 88 | { | ||
| 89 | if (read_c0_config3() & (1 << 2)) | ||
| 90 | mipsmt_build_cpu_map(0); | ||
| 91 | } | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Platform SMP pre-initialization | ||
| 95 | */ | ||
| 96 | static void ssmtc_prepare_cpus(unsigned int max_cpus) | ||
| 97 | { | ||
| 98 | /* | ||
| 99 | * As noted above, we can assume a single CPU for now | ||
| 100 | * but it may be multithreaded. | ||
| 101 | */ | ||
| 102 | |||
| 103 | if (read_c0_config3() & (1 << 2)) { | ||
| 104 | mipsmt_prepare_cpus(); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | struct plat_smp_ops ssmtc_smp_ops = { | ||
| 109 | .send_ipi_single = ssmtc_send_ipi_single, | ||
| 110 | .send_ipi_mask = ssmtc_send_ipi_mask, | ||
| 111 | .init_secondary = ssmtc_init_secondary, | ||
| 112 | .smp_finish = ssmtc_smp_finish, | ||
| 113 | .cpus_done = ssmtc_cpus_done, | ||
| 114 | .boot_secondary = ssmtc_boot_secondary, | ||
| 115 | .smp_setup = ssmtc_smp_setup, | ||
| 116 | .prepare_cpus = ssmtc_prepare_cpus, | ||
| 117 | }; | ||
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c new file mode 100644 index 00000000000..5492c42f765 --- /dev/null +++ b/arch/mips/mipssim/sim_time.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | #include <linux/types.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <linux/kernel_stat.h> | ||
| 4 | #include <linux/sched.h> | ||
| 5 | #include <linux/spinlock.h> | ||
| 6 | #include <linux/interrupt.h> | ||
| 7 | #include <linux/mc146818rtc.h> | ||
| 8 | #include <linux/smp.h> | ||
| 9 | #include <linux/timex.h> | ||
| 10 | |||
| 11 | #include <asm/hardirq.h> | ||
| 12 | #include <asm/div64.h> | ||
| 13 | #include <asm/cpu.h> | ||
| 14 | #include <asm/time.h> | ||
| 15 | #include <asm/irq.h> | ||
| 16 | #include <asm/mc146818-time.h> | ||
| 17 | #include <asm/msc01_ic.h> | ||
| 18 | |||
| 19 | #include <asm/mips-boards/generic.h> | ||
| 20 | #include <asm/mips-boards/prom.h> | ||
| 21 | #include <asm/mips-boards/simint.h> | ||
| 22 | |||
| 23 | |||
| 24 | unsigned long cpu_khz; | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect | ||
| 28 | */ | ||
| 29 | static unsigned int __init estimate_cpu_frequency(void) | ||
| 30 | { | ||
| 31 | unsigned int prid = read_c0_prid() & 0xffff00; | ||
| 32 | unsigned int count; | ||
| 33 | |||
| 34 | #if 1 | ||
| 35 | /* | ||
| 36 | * hardwire the board frequency to 12MHz. | ||
| 37 | */ | ||
| 38 | |||
| 39 | if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) || | ||
| 40 | (prid == (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
| 41 | count = 12000000; | ||
| 42 | else | ||
| 43 | count = 6000000; | ||
| 44 | #else | ||
| 45 | unsigned int flags; | ||
| 46 | |||
| 47 | local_irq_save(flags); | ||
| 48 | |||
| 49 | /* Start counter exactly on falling edge of update flag */ | ||
| 50 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
| 51 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
| 52 | |||
| 53 | /* Start r4k counter. */ | ||
| 54 | write_c0_count(0); | ||
| 55 | |||
| 56 | /* Read counter exactly on falling edge of update flag */ | ||
| 57 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
| 58 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
| 59 | |||
| 60 | count = read_c0_count(); | ||
| 61 | |||
| 62 | /* restore interrupts */ | ||
| 63 | local_irq_restore(flags); | ||
| 64 | #endif | ||
| 65 | |||
| 66 | mips_hpt_frequency = count; | ||
| 67 | |||
| 68 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | ||
| 69 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
| 70 | count *= 2; | ||
| 71 | |||
| 72 | count += 5000; /* round */ | ||
| 73 | count -= count%10000; | ||
| 74 | |||
| 75 | return count; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int mips_cpu_timer_irq; | ||
| 79 | |||
| 80 | static void mips_timer_dispatch(void) | ||
| 81 | { | ||
| 82 | do_IRQ(mips_cpu_timer_irq); | ||
| 83 | } | ||
| 84 | |||
| 85 | |||
| 86 | unsigned __cpuinit get_c0_compare_int(void) | ||
| 87 | { | ||
| 88 | #ifdef MSC01E_INT_BASE | ||
| 89 | if (cpu_has_veic) { | ||
| 90 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); | ||
| 91 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | ||
| 92 | |||
| 93 | return mips_cpu_timer_irq; | ||
| 94 | } | ||
| 95 | #endif | ||
| 96 | if (cpu_has_vint) | ||
| 97 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | ||
| 98 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | ||
| 99 | |||
| 100 | return mips_cpu_timer_irq; | ||
| 101 | } | ||
| 102 | |||
| 103 | void __init plat_time_init(void) | ||
| 104 | { | ||
| 105 | unsigned int est_freq; | ||
| 106 | |||
| 107 | /* Set Data mode - binary. */ | ||
| 108 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
| 109 | |||
| 110 | est_freq = estimate_cpu_frequency(); | ||
| 111 | |||
| 112 | printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, | ||
| 113 | (est_freq % 1000000) * 100 / 1000000); | ||
| 114 | |||
| 115 | cpu_khz = est_freq / 1000; | ||
| 116 | } | ||
