diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-07-10 12:32:56 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-07-10 12:32:56 -0400 |
commit | f6e2373ad6148476464fc7bb2610c6450c18cd2a (patch) | |
tree | f73cb9a4d26b30b2cbf8530047c3825809867be5 /arch/mips/mips-boards/sim | |
parent | 24e9d0b96dac5503c0b6f034d553030c604228a7 (diff) |
[MIPS] MIPSsim: Move code away from the other MIPS Inc. BSP code.
It shares no code at all. While at it also fix up the beginning bitrot.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mips-boards/sim')
-rw-r--r-- | arch/mips/mips-boards/sim/Makefile | 24 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_cmdline.c | 35 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_console.c | 40 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_mem.c | 115 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_platform.c | 35 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_setup.c | 98 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_smp.c | 115 | ||||
-rw-r--r-- | arch/mips/mips-boards/sim/sim_time.c | 202 |
8 files changed, 0 insertions, 664 deletions
diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mips-boards/sim/Makefile deleted file mode 100644 index dc0bfda11427..000000000000 --- a/arch/mips/mips-boards/sim/Makefile +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
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 | sim_cmdline.o | ||
22 | |||
23 | obj-$(CONFIG_EARLY_PRINTK) += sim_console.o | ||
24 | obj-$(CONFIG_SMP) += sim_smp.o | ||
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c deleted file mode 100644 index c63021a5dc6c..000000000000 --- a/arch/mips/mips-boards/sim/sim_cmdline.c +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
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/string.h> | ||
20 | #include <asm/bootinfo.h> | ||
21 | |||
22 | extern char arcs_cmdline[]; | ||
23 | |||
24 | char * __init prom_getcmdline(void) | ||
25 | { | ||
26 | return arcs_cmdline; | ||
27 | } | ||
28 | |||
29 | void __init prom_init_cmdline(void) | ||
30 | { | ||
31 | char *cp; | ||
32 | cp = arcs_cmdline; | ||
33 | /* Get boot line from environment? */ | ||
34 | *cp = '\0'; | ||
35 | } | ||
diff --git a/arch/mips/mips-boards/sim/sim_console.c b/arch/mips/mips-boards/sim/sim_console.c deleted file mode 100644 index de595a9ccb27..000000000000 --- a/arch/mips/mips-boards/sim/sim_console.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
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/serial_reg.h> | ||
22 | #include <asm/io.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/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c deleted file mode 100644 index e408ef0bcd6e..000000000000 --- a/arch/mips/mips-boards/sim/sim_mem.c +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
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/mips-boards/sim/sim_platform.c b/arch/mips/mips-boards/sim/sim_platform.c deleted file mode 100644 index 53210a8c5dec..000000000000 --- a/arch/mips/mips-boards/sim/sim_platform.c +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
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/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c deleted file mode 100644 index b705f09e57c3..000000000000 --- a/arch/mips/mips-boards/sim/sim_setup.c +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
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/ioport.h> | ||
23 | #include <linux/tty.h> | ||
24 | #include <linux/serial.h> | ||
25 | #include <linux/serial_core.h> | ||
26 | |||
27 | #include <asm/cpu.h> | ||
28 | #include <asm/bootinfo.h> | ||
29 | #include <asm/irq.h> | ||
30 | #include <asm/mips-boards/generic.h> | ||
31 | #include <asm/mips-boards/prom.h> | ||
32 | #include <asm/serial.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/time.h> | ||
35 | #include <asm/mips-boards/sim.h> | ||
36 | #include <asm/mips-boards/simint.h> | ||
37 | |||
38 | |||
39 | extern void sim_time_init(void); | ||
40 | static void __init serial_init(void); | ||
41 | unsigned int _isbonito = 0; | ||
42 | |||
43 | extern void __init sanitize_tlb_entries(void); | ||
44 | |||
45 | |||
46 | const char *get_system_type(void) | ||
47 | { | ||
48 | return "MIPSsim"; | ||
49 | } | ||
50 | |||
51 | void __init plat_mem_setup(void) | ||
52 | { | ||
53 | set_io_port_base(0xbfd00000); | ||
54 | |||
55 | serial_init(); | ||
56 | |||
57 | board_time_init = sim_time_init; | ||
58 | pr_info("Linux started...\n"); | ||
59 | |||
60 | #ifdef CONFIG_MIPS_MT_SMP | ||
61 | sanitize_tlb_entries(); | ||
62 | #endif | ||
63 | } | ||
64 | |||
65 | void prom_init(void) | ||
66 | { | ||
67 | set_io_port_base(0xbfd00000); | ||
68 | |||
69 | pr_info("\nLINUX started...\n"); | ||
70 | prom_init_cmdline(); | ||
71 | prom_meminit(); | ||
72 | } | ||
73 | |||
74 | |||
75 | static void __init serial_init(void) | ||
76 | { | ||
77 | #ifdef CONFIG_SERIAL_8250 | ||
78 | struct uart_port s; | ||
79 | |||
80 | memset(&s, 0, sizeof(s)); | ||
81 | |||
82 | s.iobase = 0x3f8; | ||
83 | |||
84 | /* hardware int 4 - the serial int, is CPU int 6 | ||
85 | but poll for now */ | ||
86 | s.irq = 0; | ||
87 | s.uartclk = BASE_BAUD * 16; | ||
88 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | ||
89 | s.iotype = UPIO_PORT; | ||
90 | s.regshift = 0; | ||
91 | s.timeout = 4; | ||
92 | |||
93 | if (early_serial_setup(&s) != 0) { | ||
94 | printk(KERN_ERR "Serial setup failed!\n"); | ||
95 | } | ||
96 | |||
97 | #endif | ||
98 | } | ||
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c deleted file mode 100644 index cb47863ecf10..000000000000 --- a/arch/mips/mips-boards/sim/sim_smp.c +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
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 SMP operation | ||
20 | */ | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/cpumask.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <asm/atomic.h> | ||
26 | #include <asm/cpu.h> | ||
27 | #include <asm/processor.h> | ||
28 | #include <asm/system.h> | ||
29 | #include <asm/hardirq.h> | ||
30 | #include <asm/mmu_context.h> | ||
31 | #include <asm/smp.h> | ||
32 | #ifdef CONFIG_MIPS_MT_SMTC | ||
33 | #include <asm/smtc_ipi.h> | ||
34 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
35 | |||
36 | /* VPE/SMP Prototype implements platform interfaces directly */ | ||
37 | #if !defined(CONFIG_MIPS_MT_SMP) | ||
38 | |||
39 | /* | ||
40 | * Cause the specified action to be performed on a targeted "CPU" | ||
41 | */ | ||
42 | |||
43 | void core_send_ipi(int cpu, unsigned int action) | ||
44 | { | ||
45 | #ifdef CONFIG_MIPS_MT_SMTC | ||
46 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | ||
47 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
48 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | ||
49 | |||
50 | } | ||
51 | |||
52 | /* | ||
53 | * Platform "CPU" startup hook | ||
54 | */ | ||
55 | |||
56 | void prom_boot_secondary(int cpu, struct task_struct *idle) | ||
57 | { | ||
58 | #ifdef CONFIG_MIPS_MT_SMTC | ||
59 | smtc_boot_secondary(cpu, idle); | ||
60 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Post-config but pre-boot cleanup entry point | ||
65 | */ | ||
66 | |||
67 | void prom_init_secondary(void) | ||
68 | { | ||
69 | #ifdef CONFIG_MIPS_MT_SMTC | ||
70 | void smtc_init_secondary(void); | ||
71 | |||
72 | smtc_init_secondary(); | ||
73 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Platform SMP pre-initialization | ||
78 | */ | ||
79 | |||
80 | void prom_prepare_cpus(unsigned int max_cpus) | ||
81 | { | ||
82 | #ifdef CONFIG_MIPS_MT_SMTC | ||
83 | /* | ||
84 | * As noted above, we can assume a single CPU for now | ||
85 | * but it may be multithreaded. | ||
86 | */ | ||
87 | |||
88 | if (read_c0_config3() & (1<<2)) { | ||
89 | mipsmt_prepare_cpus(max_cpus); | ||
90 | } | ||
91 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * SMP initialization finalization entry point | ||
96 | */ | ||
97 | |||
98 | void prom_smp_finish(void) | ||
99 | { | ||
100 | #ifdef CONFIG_MIPS_MT_SMTC | ||
101 | smtc_smp_finish(); | ||
102 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Hook for after all CPUs are online | ||
107 | */ | ||
108 | |||
109 | void prom_cpus_done(void) | ||
110 | { | ||
111 | #ifdef CONFIG_MIPS_MT_SMTC | ||
112 | |||
113 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
114 | } | ||
115 | #endif /* CONFIG_MIPS32R2_MT_SMP */ | ||
diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c deleted file mode 100644 index 7224ffe31d36..000000000000 --- a/arch/mips/mips-boards/sim/sim_time.c +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
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/timex.h> | ||
9 | |||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/ptrace.h> | ||
12 | #include <asm/hardirq.h> | ||
13 | #include <asm/div64.h> | ||
14 | #include <asm/cpu.h> | ||
15 | #include <asm/time.h> | ||
16 | #include <asm/irq.h> | ||
17 | #include <asm/mc146818-time.h> | ||
18 | #include <asm/msc01_ic.h> | ||
19 | #include <asm/smp.h> | ||
20 | |||
21 | #include <asm/mips-boards/generic.h> | ||
22 | #include <asm/mips-boards/prom.h> | ||
23 | #include <asm/mips-boards/simint.h> | ||
24 | |||
25 | |||
26 | unsigned long cpu_khz; | ||
27 | |||
28 | irqreturn_t sim_timer_interrupt(int irq, void *dev_id) | ||
29 | { | ||
30 | #ifdef CONFIG_SMP | ||
31 | int cpu = smp_processor_id(); | ||
32 | |||
33 | /* | ||
34 | * CPU 0 handles the global timer interrupt job | ||
35 | * resets count/compare registers to trigger next timer int. | ||
36 | */ | ||
37 | #ifndef CONFIG_MIPS_MT_SMTC | ||
38 | if (cpu == 0) { | ||
39 | timer_interrupt(irq, dev_id); | ||
40 | } | ||
41 | else { | ||
42 | /* Everyone else needs to reset the timer int here as | ||
43 | ll_local_timer_interrupt doesn't */ | ||
44 | /* | ||
45 | * FIXME: need to cope with counter underflow. | ||
46 | * More support needs to be added to kernel/time for | ||
47 | * counter/timer interrupts on multiple CPU's | ||
48 | */ | ||
49 | write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); | ||
50 | } | ||
51 | #else /* SMTC */ | ||
52 | /* | ||
53 | * In SMTC system, one Count/Compare set exists per VPE. | ||
54 | * Which TC within a VPE gets the interrupt is essentially | ||
55 | * random - we only know that it shouldn't be one with | ||
56 | * IXMT set. Whichever TC gets the interrupt needs to | ||
57 | * send special interprocessor interrupts to the other | ||
58 | * TCs to make sure that they schedule, etc. | ||
59 | * | ||
60 | * That code is specific to the SMTC kernel, not to | ||
61 | * the simulation platform, so it's invoked from | ||
62 | * the general MIPS timer_interrupt routine. | ||
63 | * | ||
64 | * We have a problem in that the interrupt vector code | ||
65 | * had to turn off the timer IM bit to avoid redundant | ||
66 | * entries, but we may never get to mips_cpu_irq_end | ||
67 | * to turn it back on again if the scheduler gets | ||
68 | * involved. So we clear the pending timer here, | ||
69 | * and re-enable the mask... | ||
70 | */ | ||
71 | |||
72 | int vpflags = dvpe(); | ||
73 | write_c0_compare (read_c0_count() - 1); | ||
74 | clear_c0_cause(0x100 << cp0_compare_irq); | ||
75 | set_c0_status(0x100 << cp0_compare_irq); | ||
76 | irq_enable_hazard(); | ||
77 | evpe(vpflags); | ||
78 | |||
79 | if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id); | ||
80 | else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); | ||
81 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | ||
82 | |||
83 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
84 | |||
85 | /* | ||
86 | * every CPU should do profiling and process accounting | ||
87 | */ | ||
88 | local_timer_interrupt (irq, dev_id); | ||
89 | return IRQ_HANDLED; | ||
90 | #else | ||
91 | return timer_interrupt (irq, dev_id); | ||
92 | #endif | ||
93 | } | ||
94 | |||
95 | |||
96 | |||
97 | /* | ||
98 | * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect | ||
99 | */ | ||
100 | static unsigned int __init estimate_cpu_frequency(void) | ||
101 | { | ||
102 | unsigned int prid = read_c0_prid() & 0xffff00; | ||
103 | unsigned int count; | ||
104 | |||
105 | #if 1 | ||
106 | /* | ||
107 | * hardwire the board frequency to 12MHz. | ||
108 | */ | ||
109 | |||
110 | if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) || | ||
111 | (prid == (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
112 | count = 12000000; | ||
113 | else | ||
114 | count = 6000000; | ||
115 | #else | ||
116 | unsigned int flags; | ||
117 | |||
118 | local_irq_save(flags); | ||
119 | |||
120 | /* Start counter exactly on falling edge of update flag */ | ||
121 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
122 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
123 | |||
124 | /* Start r4k counter. */ | ||
125 | write_c0_count(0); | ||
126 | |||
127 | /* Read counter exactly on falling edge of update flag */ | ||
128 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
129 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
130 | |||
131 | count = read_c0_count(); | ||
132 | |||
133 | /* restore interrupts */ | ||
134 | local_irq_restore(flags); | ||
135 | #endif | ||
136 | |||
137 | mips_hpt_frequency = count; | ||
138 | |||
139 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | ||
140 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
141 | count *= 2; | ||
142 | |||
143 | count += 5000; /* round */ | ||
144 | count -= count%10000; | ||
145 | |||
146 | return count; | ||
147 | } | ||
148 | |||
149 | void __init sim_time_init(void) | ||
150 | { | ||
151 | unsigned int est_freq, flags; | ||
152 | |||
153 | local_irq_save(flags); | ||
154 | |||
155 | |||
156 | /* Set Data mode - binary. */ | ||
157 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
158 | |||
159 | |||
160 | est_freq = estimate_cpu_frequency (); | ||
161 | |||
162 | printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, | ||
163 | (est_freq%1000000)*100/1000000); | ||
164 | |||
165 | cpu_khz = est_freq / 1000; | ||
166 | |||
167 | local_irq_restore(flags); | ||
168 | } | ||
169 | |||
170 | static int mips_cpu_timer_irq; | ||
171 | |||
172 | static void mips_timer_dispatch(void) | ||
173 | { | ||
174 | do_IRQ(mips_cpu_timer_irq); | ||
175 | } | ||
176 | |||
177 | |||
178 | void __init plat_timer_setup(struct irqaction *irq) | ||
179 | { | ||
180 | if (cpu_has_veic) { | ||
181 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); | ||
182 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | ||
183 | } | ||
184 | else { | ||
185 | if (cpu_has_vint) | ||
186 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | ||
187 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | ||
188 | } | ||
189 | |||
190 | /* we are using the cpu counter for timer interrupts */ | ||
191 | irq->handler = sim_timer_interrupt; | ||
192 | setup_irq(mips_cpu_timer_irq, irq); | ||
193 | |||
194 | #ifdef CONFIG_SMP | ||
195 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps | ||
196 | on seperate cpu's the first one tries to handle the second interrupt. | ||
197 | The effect is that the int remains disabled on the second cpu. | ||
198 | Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ | ||
199 | irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU; | ||
200 | set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); | ||
201 | #endif | ||
202 | } | ||