diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-07-14 11:57:16 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:31:53 -0400 |
commit | e01402b115cccb6357f956649487aca2c6f7fbba (patch) | |
tree | 256e14f8d2762de98b992219b1a47e8f56b4b0da /arch/mips/mips-boards/generic | |
parent | 86071b637db7baf599df26fdf820dce2fc55ca9f (diff) |
More AP / SP bits for the 34K, the Malta bits and things. Still wants
a little polishing.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mips-boards/generic')
-rw-r--r-- | arch/mips/mips-boards/generic/init.c | 29 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/memory.c | 29 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/mipsIRQ.S | 110 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/time.c | 49 |
4 files changed, 138 insertions, 79 deletions
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index d821b13d24a0..58256ea33102 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <asm/gt64120.h> | 28 | #include <asm/gt64120.h> |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/cacheflush.h> | ||
32 | #include <asm/traps.h> | ||
31 | 33 | ||
32 | #include <asm/mips-boards/prom.h> | 34 | #include <asm/mips-boards/prom.h> |
33 | #include <asm/mips-boards/generic.h> | 35 | #include <asm/mips-boards/generic.h> |
@@ -224,6 +226,30 @@ void __init kgdb_config (void) | |||
224 | } | 226 | } |
225 | #endif | 227 | #endif |
226 | 228 | ||
229 | void __init mips_nmi_setup (void) | ||
230 | { | ||
231 | void *base; | ||
232 | extern char except_vec_nmi; | ||
233 | |||
234 | base = cpu_has_veic ? | ||
235 | (void *)(CAC_BASE + 0xa80) : | ||
236 | (void *)(CAC_BASE + 0x380); | ||
237 | memcpy(base, &except_vec_nmi, 0x80); | ||
238 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | ||
239 | } | ||
240 | |||
241 | void __init mips_ejtag_setup (void) | ||
242 | { | ||
243 | void *base; | ||
244 | extern char except_vec_ejtag_debug; | ||
245 | |||
246 | base = cpu_has_veic ? | ||
247 | (void *)(CAC_BASE + 0xa00) : | ||
248 | (void *)(CAC_BASE + 0x300); | ||
249 | memcpy(base, &except_vec_ejtag_debug, 0x80); | ||
250 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | ||
251 | } | ||
252 | |||
227 | void __init prom_init(void) | 253 | void __init prom_init(void) |
228 | { | 254 | { |
229 | u32 start, map, mask, data; | 255 | u32 start, map, mask, data; |
@@ -353,6 +379,9 @@ void __init prom_init(void) | |||
353 | while(1); /* We die here... */ | 379 | while(1); /* We die here... */ |
354 | } | 380 | } |
355 | #endif | 381 | #endif |
382 | board_nmi_handler_setup = mips_nmi_setup; | ||
383 | board_ejtag_handler_setup = mips_ejtag_setup; | ||
384 | |||
356 | prom_printf("\nLINUX started...\n"); | 385 | prom_printf("\nLINUX started...\n"); |
357 | prom_init_cmdline(); | 386 | prom_init_cmdline(); |
358 | prom_meminit(); | 387 | prom_meminit(); |
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index 5ae2b43e4c2e..2c8afd77a20b 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
25 | #include <linux/string.h> | ||
25 | 26 | ||
26 | #include <asm/bootinfo.h> | 27 | #include <asm/bootinfo.h> |
27 | #include <asm/page.h> | 28 | #include <asm/page.h> |
@@ -55,18 +56,30 @@ struct prom_pmemblock * __init prom_getmdesc(void) | |||
55 | { | 56 | { |
56 | char *memsize_str; | 57 | char *memsize_str; |
57 | unsigned int memsize; | 58 | unsigned int memsize; |
59 | char cmdline[CL_SIZE], *ptr; | ||
58 | 60 | ||
59 | memsize_str = prom_getenv("memsize"); | 61 | /* Check the command line first for a memsize directive */ |
60 | if (!memsize_str) { | 62 | strcpy(cmdline, arcs_cmdline); |
61 | prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); | 63 | ptr = strstr(cmdline, "memsize="); |
62 | memsize = 0x02000000; | 64 | if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) |
63 | } else { | 65 | ptr = strstr(ptr, " memsize="); |
66 | |||
67 | if (ptr) { | ||
68 | memsize = memparse(ptr + 8, &ptr); | ||
69 | } | ||
70 | else { | ||
71 | /* otherwise look in the environment */ | ||
72 | memsize_str = prom_getenv("memsize"); | ||
73 | if (!memsize_str) { | ||
74 | prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); | ||
75 | memsize = 0x02000000; | ||
76 | } else { | ||
64 | #ifdef DEBUG | 77 | #ifdef DEBUG |
65 | prom_printf("prom_memsize = %s\n", memsize_str); | 78 | prom_printf("prom_memsize = %s\n", memsize_str); |
66 | #endif | 79 | #endif |
67 | memsize = simple_strtol(memsize_str, NULL, 0); | 80 | memsize = simple_strtol(memsize_str, NULL, 0); |
81 | } | ||
68 | } | 82 | } |
69 | |||
70 | memset(mdesc, 0, sizeof(mdesc)); | 83 | memset(mdesc, 0, sizeof(mdesc)); |
71 | 84 | ||
72 | mdesc[0].type = yamon_dontuse; | 85 | mdesc[0].type = yamon_dontuse; |
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S index 131f49bccb20..a397ecb872d6 100644 --- a/arch/mips/mips-boards/generic/mipsIRQ.S +++ b/arch/mips/mips-boards/generic/mipsIRQ.S | |||
@@ -29,6 +29,20 @@ | |||
29 | #include <asm/regdef.h> | 29 | #include <asm/regdef.h> |
30 | #include <asm/stackframe.h> | 30 | #include <asm/stackframe.h> |
31 | 31 | ||
32 | #ifdef CONFIG_MIPS_ATLAS | ||
33 | #include <asm/mips-boards/atlasint.h> | ||
34 | #define CASCADE_IRQ MIPSCPU_INT_ATLAS | ||
35 | #define CASCADE_DISPATCH atlas_hw0_irqdispatch | ||
36 | #endif | ||
37 | #ifdef CONFIG_MIPS_MALTA | ||
38 | #include <asm/mips-boards/maltaint.h> | ||
39 | #define CASCADE_IRQ MIPSCPU_INT_I8259A | ||
40 | #define CASCADE_DISPATCH malta_hw0_irqdispatch | ||
41 | #endif | ||
42 | #ifdef CONFIG_MIPS_SEAD | ||
43 | #include <asm/mips-boards/seadint.h> | ||
44 | #endif | ||
45 | |||
32 | /* A lot of complication here is taken away because: | 46 | /* A lot of complication here is taken away because: |
33 | * | 47 | * |
34 | * 1) We handle one interrupt and return, sitting in a loop and moving across | 48 | * 1) We handle one interrupt and return, sitting in a loop and moving across |
@@ -80,74 +94,62 @@ | |||
80 | 94 | ||
81 | mfc0 s0, CP0_CAUSE # get irq bits | 95 | mfc0 s0, CP0_CAUSE # get irq bits |
82 | mfc0 s1, CP0_STATUS # get irq mask | 96 | mfc0 s1, CP0_STATUS # get irq mask |
97 | andi s0, ST0_IM # CAUSE.CE may be non-zero! | ||
83 | and s0, s1 | 98 | and s0, s1 |
84 | 99 | ||
85 | /* First we check for r4k counter/timer IRQ. */ | 100 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) |
86 | andi a0, s0, CAUSEF_IP7 | 101 | .set mips32 |
87 | beq a0, zero, 1f | 102 | clz a0, s0 |
88 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | 103 | .set mips0 |
104 | negu a0 | ||
105 | addu a0, 31-CAUSEB_IP | ||
106 | bltz a0, spurious | ||
107 | #else | ||
108 | beqz s0, spurious | ||
109 | li a0, 7 | ||
89 | 110 | ||
90 | /* Wheee, a timer interrupt. */ | 111 | and t0, s0, 0xf000 |
91 | move a0, sp | 112 | sltiu t0, t0, 1 |
92 | jal mips_timer_interrupt | 113 | sll t0, 2 |
93 | nop | 114 | subu a0, t0 |
115 | sll s0, t0 | ||
94 | 116 | ||
95 | j ret_from_irq | 117 | and t0, s0, 0xc000 |
96 | nop | 118 | sltiu t0, t0, 1 |
119 | sll t0, 1 | ||
120 | subu a0, t0 | ||
121 | sll s0, t0 | ||
97 | 122 | ||
98 | 1: | 123 | and t0, s0, 0x8000 |
99 | #if defined(CONFIG_MIPS_SEAD) | 124 | sltiu t0, t0, 1 |
100 | beq a0, zero, 1f | 125 | # sll t0, 0 |
101 | andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt | 126 | subu a0, t0 |
102 | #else | 127 | # sll s0, t0 |
103 | beq a0, zero, 1f # delay slot, check hw3 interrupt | ||
104 | andi a0, s0, CAUSEF_IP5 | ||
105 | #endif | 128 | #endif |
106 | 129 | ||
107 | /* Wheee, combined hardware level zero interrupt. */ | 130 | #ifdef CASCADE_IRQ |
108 | #if defined(CONFIG_MIPS_ATLAS) | 131 | li a1, CASCADE_IRQ |
109 | jal atlas_hw0_irqdispatch | 132 | bne a0, a1, 1f |
110 | #elif defined(CONFIG_MIPS_MALTA) | 133 | addu a0, MIPSCPU_INT_BASE |
111 | jal malta_hw0_irqdispatch | ||
112 | #elif defined(CONFIG_MIPS_SEAD) | ||
113 | jal sead_hw0_irqdispatch | ||
114 | #else | ||
115 | #error "MIPS board not supported\n" | ||
116 | #endif | ||
117 | move a0, sp # delay slot | ||
118 | 134 | ||
119 | j ret_from_irq | 135 | jal CASCADE_DISPATCH |
120 | nop # delay slot | 136 | move a0, sp |
121 | 137 | ||
122 | 1: | ||
123 | #if defined(CONFIG_MIPS_SEAD) | ||
124 | beq a0, zero, 1f | ||
125 | andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt | ||
126 | jal sead_hw1_irqdispatch | ||
127 | move a0, sp # delay slot | ||
128 | j ret_from_irq | ||
129 | nop # delay slot | ||
130 | 1: | ||
131 | #endif | ||
132 | #if defined(CONFIG_MIPS_MALTA) | ||
133 | beq a0, zero, 1f # check hw3 (coreHI) interrupt | ||
134 | nop | ||
135 | jal corehi_irqdispatch | ||
136 | move a0, sp | ||
137 | j ret_from_irq | 138 | j ret_from_irq |
138 | nop | 139 | nop |
139 | 1: | 140 | 1: |
141 | #else | ||
142 | addu a0, MIPSCPU_INT_BASE | ||
140 | #endif | 143 | #endif |
141 | /* | 144 | |
142 | * Here by mistake? This is possible, what can happen is that by the | 145 | jal do_IRQ |
143 | * time we take the exception the IRQ pin goes low, so just leave if | 146 | move a1, sp |
144 | * this is the case. | ||
145 | */ | ||
146 | move a1,s0 | ||
147 | PRINT("Got interrupt: c0_cause = %08x\n") | ||
148 | mfc0 a1, CP0_EPC | ||
149 | PRINT("c0_epc = %08x\n") | ||
150 | 147 | ||
151 | j ret_from_irq | 148 | j ret_from_irq |
152 | nop | 149 | nop |
150 | |||
151 | |||
152 | spurious: | ||
153 | j spurious_interrupt | ||
154 | nop | ||
153 | END(mipsIRQ) | 155 | END(mipsIRQ) |
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 16315444dd5a..3a6f1428b2cb 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -31,22 +31,21 @@ | |||
31 | 31 | ||
32 | #include <asm/mipsregs.h> | 32 | #include <asm/mipsregs.h> |
33 | #include <asm/ptrace.h> | 33 | #include <asm/ptrace.h> |
34 | #include <asm/hardirq.h> | ||
35 | #include <asm/irq.h> | ||
34 | #include <asm/div64.h> | 36 | #include <asm/div64.h> |
35 | #include <asm/cpu.h> | 37 | #include <asm/cpu.h> |
36 | #include <asm/time.h> | 38 | #include <asm/time.h> |
37 | #include <asm/mc146818-time.h> | 39 | #include <asm/mc146818-time.h> |
40 | #include <asm/msc01_ic.h> | ||
38 | 41 | ||
39 | #include <asm/mips-boards/generic.h> | 42 | #include <asm/mips-boards/generic.h> |
40 | #include <asm/mips-boards/prom.h> | 43 | #include <asm/mips-boards/prom.h> |
44 | #include <asm/mips-boards/maltaint.h> | ||
45 | #include <asm/mc146818-time.h> | ||
41 | 46 | ||
42 | unsigned long cpu_khz; | 47 | unsigned long cpu_khz; |
43 | 48 | ||
44 | #if defined(CONFIG_MIPS_SEAD) | ||
45 | #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5) | ||
46 | #else | ||
47 | #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) | ||
48 | #endif | ||
49 | |||
50 | #if defined(CONFIG_MIPS_ATLAS) | 49 | #if defined(CONFIG_MIPS_ATLAS) |
51 | static char display_string[] = " LINUX ON ATLAS "; | 50 | static char display_string[] = " LINUX ON ATLAS "; |
52 | #endif | 51 | #endif |
@@ -59,20 +58,27 @@ static char display_string[] = " LINUX ON SEAD "; | |||
59 | static unsigned int display_count = 0; | 58 | static unsigned int display_count = 0; |
60 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | 59 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) |
61 | 60 | ||
62 | #define MIPS_CPU_TIMER_IRQ (NR_IRQS-1) | ||
63 | |||
64 | static unsigned int timer_tick_count=0; | 61 | static unsigned int timer_tick_count=0; |
62 | static int mips_cpu_timer_irq; | ||
65 | 63 | ||
66 | void mips_timer_interrupt(struct pt_regs *regs) | 64 | static void mips_timer_dispatch (struct pt_regs *regs) |
67 | { | 65 | { |
66 | do_IRQ (mips_cpu_timer_irq, regs); | ||
67 | } | ||
68 | |||
69 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
70 | { | ||
71 | irqreturn_t r; | ||
72 | |||
73 | r = timer_interrupt(irq, dev_id, regs); | ||
74 | |||
68 | if ((timer_tick_count++ % HZ) == 0) { | 75 | if ((timer_tick_count++ % HZ) == 0) { |
69 | mips_display_message(&display_string[display_count++]); | 76 | mips_display_message(&display_string[display_count++]); |
70 | if (display_count == MAX_DISPLAY_COUNT) | 77 | if (display_count == MAX_DISPLAY_COUNT) |
71 | display_count = 0; | 78 | display_count = 0; |
72 | |||
73 | } | 79 | } |
74 | 80 | ||
75 | ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); | 81 | return r; |
76 | } | 82 | } |
77 | 83 | ||
78 | /* | 84 | /* |
@@ -140,10 +146,8 @@ void __init mips_time_init(void) | |||
140 | 146 | ||
141 | local_irq_save(flags); | 147 | local_irq_save(flags); |
142 | 148 | ||
143 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | ||
144 | /* Set Data mode - binary. */ | 149 | /* Set Data mode - binary. */ |
145 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | 150 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); |
146 | #endif | ||
147 | 151 | ||
148 | est_freq = estimate_cpu_frequency (); | 152 | est_freq = estimate_cpu_frequency (); |
149 | 153 | ||
@@ -157,11 +161,22 @@ void __init mips_time_init(void) | |||
157 | 161 | ||
158 | void __init mips_timer_setup(struct irqaction *irq) | 162 | void __init mips_timer_setup(struct irqaction *irq) |
159 | { | 163 | { |
164 | if (cpu_has_veic) { | ||
165 | set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch); | ||
166 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | ||
167 | } | ||
168 | else { | ||
169 | if (cpu_has_vint) | ||
170 | set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch); | ||
171 | mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR; | ||
172 | } | ||
173 | |||
174 | |||
160 | /* we are using the cpu counter for timer interrupts */ | 175 | /* we are using the cpu counter for timer interrupts */ |
161 | irq->handler = no_action; /* we use our own handler */ | 176 | irq->handler = mips_timer_interrupt; /* we use our own handler */ |
162 | setup_irq(MIPS_CPU_TIMER_IRQ, irq); | 177 | setup_irq(mips_cpu_timer_irq, irq); |
178 | |||
163 | 179 | ||
164 | /* to generate the first timer interrupt */ | 180 | /* to generate the first timer interrupt */ |
165 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); | 181 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); |
166 | set_c0_status(ALLINTS); | ||
167 | } | 182 | } |