diff options
Diffstat (limited to 'arch/mips/mips-boards/generic')
-rw-r--r-- | arch/mips/mips-boards/generic/Makefile | 26 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/cmdline.c | 59 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/display.c | 39 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/gdb_hook.c | 133 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/init.c | 343 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/memory.c | 173 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/mipsIRQ.S | 153 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/pci.c | 163 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/printf.c | 79 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/reset.c | 73 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/time.c | 167 |
11 files changed, 1408 insertions, 0 deletions
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile new file mode 100644 index 000000000000..b21bc6887fa8 --- /dev/null +++ b/arch/mips/mips-boards/generic/Makefile | |||
@@ -0,0 +1,26 @@ | |||
1 | # | ||
2 | # Carsten Langgaard, carstenl@mips.com | ||
3 | # Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | # | ||
5 | # This program is free software; you can distribute it and/or modify it | ||
6 | # under the terms of the GNU General Public License (Version 2) as | ||
7 | # published by the Free Software Foundation. | ||
8 | # | ||
9 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | # for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License along | ||
15 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | # | ||
18 | # Makefile for the MIPS boards generic routines under Linux. | ||
19 | # | ||
20 | |||
21 | obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ | ||
22 | printf.o cmdline.o time.o | ||
23 | obj-$(CONFIG_PCI) += pci.o | ||
24 | obj-$(CONFIG_KGDB) += gdb_hook.o | ||
25 | |||
26 | EXTRA_AFLAGS := $(CFLAGS) | ||
diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c new file mode 100644 index 000000000000..1871c30ed2eb --- /dev/null +++ b/arch/mips/mips-boards/generic/cmdline.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Kernel command line creation using the prom monitor (YAMON) argc/argv. | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/bootinfo.h> | ||
24 | |||
25 | extern int prom_argc; | ||
26 | extern int *_prom_argv; | ||
27 | |||
28 | /* | ||
29 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
30 | * This macro take care of sign extension. | ||
31 | */ | ||
32 | #define prom_argv(index) ((char *)(long)_prom_argv[(index)]) | ||
33 | |||
34 | char * __init prom_getcmdline(void) | ||
35 | { | ||
36 | return &(arcs_cmdline[0]); | ||
37 | } | ||
38 | |||
39 | |||
40 | void __init prom_init_cmdline(void) | ||
41 | { | ||
42 | char *cp; | ||
43 | int actr; | ||
44 | |||
45 | actr = 1; /* Always ignore argv[0] */ | ||
46 | |||
47 | cp = &(arcs_cmdline[0]); | ||
48 | while(actr < prom_argc) { | ||
49 | strcpy(cp, prom_argv(actr)); | ||
50 | cp += strlen(prom_argv(actr)); | ||
51 | *cp++ = ' '; | ||
52 | actr++; | ||
53 | } | ||
54 | if (cp != &(arcs_cmdline[0])) { | ||
55 | /* get rid of trailing space */ | ||
56 | --cp; | ||
57 | *cp = '\0'; | ||
58 | } | ||
59 | } | ||
diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c new file mode 100644 index 000000000000..f653946afc23 --- /dev/null +++ b/arch/mips/mips-boards/generic/display.c | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Display routines for display messages in MIPS boards ascii display. | ||
19 | */ | ||
20 | |||
21 | #include <linux/compiler.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/mips-boards/generic.h> | ||
24 | |||
25 | void mips_display_message(const char *str) | ||
26 | { | ||
27 | static volatile unsigned int *display = NULL; | ||
28 | int i; | ||
29 | |||
30 | if (unlikely(display == NULL)) | ||
31 | display = (volatile unsigned int *)ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); | ||
32 | |||
33 | for (i = 0; i <= 14; i=i+2) { | ||
34 | if (*str) | ||
35 | display[i] = *str++; | ||
36 | else | ||
37 | display[i] = ' '; | ||
38 | } | ||
39 | } | ||
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c new file mode 100644 index 000000000000..91a2ccbe3730 --- /dev/null +++ b/arch/mips/mips-boards/generic/gdb_hook.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * This is the interface to the remote debugger stub. | ||
19 | */ | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/serial.h> | ||
22 | #include <linux/serialP.h> | ||
23 | #include <linux/serial_reg.h> | ||
24 | |||
25 | #include <asm/serial.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | static struct serial_state rs_table[RS_TABLE_SIZE] = { | ||
29 | SERIAL_PORT_DFNS /* Defined in serial.h */ | ||
30 | }; | ||
31 | |||
32 | static struct async_struct kdb_port_info = {0}; | ||
33 | |||
34 | int (*generic_putDebugChar)(char); | ||
35 | char (*generic_getDebugChar)(void); | ||
36 | |||
37 | static __inline__ unsigned int serial_in(struct async_struct *info, int offset) | ||
38 | { | ||
39 | return inb(info->port + offset); | ||
40 | } | ||
41 | |||
42 | static __inline__ void serial_out(struct async_struct *info, int offset, | ||
43 | int value) | ||
44 | { | ||
45 | outb(value, info->port+offset); | ||
46 | } | ||
47 | |||
48 | int rs_kgdb_hook(int tty_no, int speed) { | ||
49 | int t; | ||
50 | struct serial_state *ser = &rs_table[tty_no]; | ||
51 | |||
52 | kdb_port_info.state = ser; | ||
53 | kdb_port_info.magic = SERIAL_MAGIC; | ||
54 | kdb_port_info.port = ser->port; | ||
55 | kdb_port_info.flags = ser->flags; | ||
56 | |||
57 | /* | ||
58 | * Clear all interrupts | ||
59 | */ | ||
60 | serial_in(&kdb_port_info, UART_LSR); | ||
61 | serial_in(&kdb_port_info, UART_RX); | ||
62 | serial_in(&kdb_port_info, UART_IIR); | ||
63 | serial_in(&kdb_port_info, UART_MSR); | ||
64 | |||
65 | /* | ||
66 | * Now, initialize the UART | ||
67 | */ | ||
68 | serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ | ||
69 | if (kdb_port_info.flags & ASYNC_FOURPORT) { | ||
70 | kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS; | ||
71 | t = UART_MCR_DTR | UART_MCR_OUT1; | ||
72 | } else { | ||
73 | kdb_port_info.MCR | ||
74 | = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; | ||
75 | t = UART_MCR_DTR | UART_MCR_RTS; | ||
76 | } | ||
77 | |||
78 | kdb_port_info.MCR = t; /* no interrupts, please */ | ||
79 | serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR); | ||
80 | |||
81 | /* | ||
82 | * and set the speed of the serial port | ||
83 | */ | ||
84 | if (speed == 0) | ||
85 | speed = 9600; | ||
86 | |||
87 | t = kdb_port_info.state->baud_base / speed; | ||
88 | /* set DLAB */ | ||
89 | serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB); | ||
90 | serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */ | ||
91 | serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */ | ||
92 | /* reset DLAB */ | ||
93 | serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); | ||
94 | |||
95 | return speed; | ||
96 | } | ||
97 | |||
98 | int putDebugChar(char c) | ||
99 | { | ||
100 | return generic_putDebugChar(c); | ||
101 | } | ||
102 | |||
103 | char getDebugChar(void) | ||
104 | { | ||
105 | return generic_getDebugChar(); | ||
106 | } | ||
107 | |||
108 | int rs_putDebugChar(char c) | ||
109 | { | ||
110 | |||
111 | if (!kdb_port_info.state) { /* need to init device first */ | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0) | ||
116 | ; | ||
117 | |||
118 | serial_out(&kdb_port_info, UART_TX, c); | ||
119 | |||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | char rs_getDebugChar(void) | ||
124 | { | ||
125 | if (!kdb_port_info.state) { /* need to init device first */ | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | while (!(serial_in(&kdb_port_info, UART_LSR) & 1)) | ||
130 | ; | ||
131 | |||
132 | return serial_in(&kdb_port_info, UART_RX); | ||
133 | } | ||
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c new file mode 100644 index 000000000000..31caf0603a3f --- /dev/null +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -0,0 +1,343 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * PROM library initialisation code. | ||
19 | */ | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/kernel.h> | ||
24 | |||
25 | #include <asm/io.h> | ||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/mips-boards/prom.h> | ||
28 | #include <asm/mips-boards/generic.h> | ||
29 | #ifdef CONFIG_MIPS_GT64120 | ||
30 | #include <asm/gt64120.h> | ||
31 | #endif | ||
32 | #include <asm/mips-boards/msc01_pci.h> | ||
33 | #include <asm/mips-boards/bonito64.h> | ||
34 | #ifdef CONFIG_MIPS_MALTA | ||
35 | #include <asm/mips-boards/malta.h> | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONFIG_KGDB | ||
39 | extern int rs_kgdb_hook(int, int); | ||
40 | extern int rs_putDebugChar(char); | ||
41 | extern char rs_getDebugChar(void); | ||
42 | extern int saa9730_kgdb_hook(int); | ||
43 | extern int saa9730_putDebugChar(char); | ||
44 | extern char saa9730_getDebugChar(void); | ||
45 | #endif | ||
46 | |||
47 | int prom_argc; | ||
48 | int *_prom_argv, *_prom_envp; | ||
49 | |||
50 | /* | ||
51 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
52 | * This macro take care of sign extension, if running in 64-bit mode. | ||
53 | */ | ||
54 | #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) | ||
55 | |||
56 | int init_debug = 0; | ||
57 | |||
58 | unsigned int mips_revision_corid; | ||
59 | |||
60 | /* Bonito64 system controller register base. */ | ||
61 | unsigned long _pcictrl_bonito; | ||
62 | unsigned long _pcictrl_bonito_pcicfg; | ||
63 | |||
64 | /* GT64120 system controller register base */ | ||
65 | unsigned long _pcictrl_gt64120; | ||
66 | |||
67 | /* MIPS System controller register base */ | ||
68 | unsigned long _pcictrl_msc; | ||
69 | |||
70 | char *prom_getenv(char *envname) | ||
71 | { | ||
72 | /* | ||
73 | * Return a pointer to the given environment variable. | ||
74 | * In 64-bit mode: we're using 64-bit pointers, but all pointers | ||
75 | * in the PROM structures are only 32-bit, so we need some | ||
76 | * workarounds, if we are running in 64-bit mode. | ||
77 | */ | ||
78 | int i, index=0; | ||
79 | |||
80 | i = strlen(envname); | ||
81 | |||
82 | while (prom_envp(index)) { | ||
83 | if(strncmp(envname, prom_envp(index), i) == 0) { | ||
84 | return(prom_envp(index+1)); | ||
85 | } | ||
86 | index += 2; | ||
87 | } | ||
88 | |||
89 | return NULL; | ||
90 | } | ||
91 | |||
92 | static inline unsigned char str2hexnum(unsigned char c) | ||
93 | { | ||
94 | if (c >= '0' && c <= '9') | ||
95 | return c - '0'; | ||
96 | if (c >= 'a' && c <= 'f') | ||
97 | return c - 'a' + 10; | ||
98 | return 0; /* foo */ | ||
99 | } | ||
100 | |||
101 | static inline void str2eaddr(unsigned char *ea, unsigned char *str) | ||
102 | { | ||
103 | int i; | ||
104 | |||
105 | for (i = 0; i < 6; i++) { | ||
106 | unsigned char num; | ||
107 | |||
108 | if((*str == '.') || (*str == ':')) | ||
109 | str++; | ||
110 | num = str2hexnum(*str++) << 4; | ||
111 | num |= (str2hexnum(*str++)); | ||
112 | ea[i] = num; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | int get_ethernet_addr(char *ethernet_addr) | ||
117 | { | ||
118 | char *ethaddr_str; | ||
119 | |||
120 | ethaddr_str = prom_getenv("ethaddr"); | ||
121 | if (!ethaddr_str) { | ||
122 | printk("ethaddr not set in boot prom\n"); | ||
123 | return -1; | ||
124 | } | ||
125 | str2eaddr(ethernet_addr, ethaddr_str); | ||
126 | |||
127 | if (init_debug > 1) { | ||
128 | int i; | ||
129 | printk("get_ethernet_addr: "); | ||
130 | for (i=0; i<5; i++) | ||
131 | printk("%02x:", (unsigned char)*(ethernet_addr+i)); | ||
132 | printk("%02x\n", *(ethernet_addr+i)); | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
139 | static void __init console_config(void) | ||
140 | { | ||
141 | char console_string[40]; | ||
142 | int baud = 0; | ||
143 | char parity = '\0', bits = '\0', flow = '\0'; | ||
144 | char *s; | ||
145 | |||
146 | if ((strstr(prom_getcmdline(), "console=ttyS")) == NULL) { | ||
147 | s = prom_getenv("modetty0"); | ||
148 | if (s) { | ||
149 | while (*s >= '0' && *s <= '9') | ||
150 | baud = baud*10 + *s++ - '0'; | ||
151 | if (*s == ',') s++; | ||
152 | if (*s) parity = *s++; | ||
153 | if (*s == ',') s++; | ||
154 | if (*s) bits = *s++; | ||
155 | if (*s == ',') s++; | ||
156 | if (*s == 'h') flow = 'r'; | ||
157 | } | ||
158 | if (baud == 0) | ||
159 | baud = 38400; | ||
160 | if (parity != 'n' && parity != 'o' && parity != 'e') | ||
161 | parity = 'n'; | ||
162 | if (bits != '7' && bits != '8') | ||
163 | bits = '8'; | ||
164 | if (flow == '\0') | ||
165 | flow = 'r'; | ||
166 | sprintf (console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); | ||
167 | strcat (prom_getcmdline(), console_string); | ||
168 | prom_printf("Config serial console:%s\n", console_string); | ||
169 | } | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | #ifdef CONFIG_KGDB | ||
174 | void __init kgdb_config (void) | ||
175 | { | ||
176 | extern int (*generic_putDebugChar)(char); | ||
177 | extern char (*generic_getDebugChar)(void); | ||
178 | char *argptr; | ||
179 | int line, speed; | ||
180 | |||
181 | argptr = prom_getcmdline(); | ||
182 | if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { | ||
183 | argptr += strlen("kgdb=ttyS"); | ||
184 | if (*argptr != '0' && *argptr != '1') | ||
185 | printk("KGDB: Unknown serial line /dev/ttyS%c, " | ||
186 | "falling back to /dev/ttyS1\n", *argptr); | ||
187 | line = *argptr == '0' ? 0 : 1; | ||
188 | printk("KGDB: Using serial line /dev/ttyS%d for session\n", line); | ||
189 | |||
190 | speed = 0; | ||
191 | if (*++argptr == ',') | ||
192 | { | ||
193 | int c; | ||
194 | while ((c = *++argptr) && ('0' <= c && c <= '9')) | ||
195 | speed = speed * 10 + c - '0'; | ||
196 | } | ||
197 | #ifdef CONFIG_MIPS_ATLAS | ||
198 | if (line == 1) { | ||
199 | speed = saa9730_kgdb_hook(speed); | ||
200 | generic_putDebugChar = saa9730_putDebugChar; | ||
201 | generic_getDebugChar = saa9730_getDebugChar; | ||
202 | } | ||
203 | else | ||
204 | #endif | ||
205 | { | ||
206 | speed = rs_kgdb_hook(line, speed); | ||
207 | generic_putDebugChar = rs_putDebugChar; | ||
208 | generic_getDebugChar = rs_getDebugChar; | ||
209 | } | ||
210 | |||
211 | prom_printf("KGDB: Using serial line /dev/ttyS%d at %d for session, " | ||
212 | "please connect your debugger\n", line ? 1 : 0, speed); | ||
213 | |||
214 | { | ||
215 | char *s; | ||
216 | for (s = "Please connect GDB to this port\r\n"; *s; ) | ||
217 | generic_putDebugChar (*s++); | ||
218 | } | ||
219 | |||
220 | kgdb_enabled = 1; | ||
221 | /* Breakpoint is invoked after interrupts are initialised */ | ||
222 | } | ||
223 | } | ||
224 | #endif | ||
225 | |||
226 | void __init prom_init(void) | ||
227 | { | ||
228 | prom_argc = fw_arg0; | ||
229 | _prom_argv = (int *) fw_arg1; | ||
230 | _prom_envp = (int *) fw_arg2; | ||
231 | |||
232 | mips_display_message("LINUX"); | ||
233 | |||
234 | #ifdef CONFIG_MIPS_SEAD | ||
235 | set_io_port_base(KSEG1); | ||
236 | #else | ||
237 | /* | ||
238 | * early setup of _pcictrl_bonito so that we can determine | ||
239 | * the system controller on a CORE_EMUL board | ||
240 | */ | ||
241 | _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE); | ||
242 | |||
243 | mips_revision_corid = MIPS_REVISION_CORID; | ||
244 | |||
245 | if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) { | ||
246 | if (BONITO_PCIDID == 0x0001df53 || | ||
247 | BONITO_PCIDID == 0x0003df53) | ||
248 | mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON; | ||
249 | else | ||
250 | mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; | ||
251 | } | ||
252 | switch(mips_revision_corid) { | ||
253 | case MIPS_REVISION_CORID_QED_RM5261: | ||
254 | case MIPS_REVISION_CORID_CORE_LV: | ||
255 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
256 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
257 | /* | ||
258 | * Setup the North bridge to do Master byte-lane swapping | ||
259 | * when running in bigendian. | ||
260 | */ | ||
261 | _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000); | ||
262 | |||
263 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
264 | GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | | ||
265 | GT_PCI0_CMD_SBYTESWAP_BIT); | ||
266 | #else | ||
267 | GT_WRITE(GT_PCI0_CMD_OFS, 0); | ||
268 | #endif | ||
269 | |||
270 | #ifdef CONFIG_MIPS_MALTA | ||
271 | set_io_port_base(MALTA_GT_PORT_BASE); | ||
272 | #else | ||
273 | set_io_port_base((unsigned long)ioremap(0, 0x20000000)); | ||
274 | #endif | ||
275 | break; | ||
276 | |||
277 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
278 | case MIPS_REVISION_CORID_BONITO64: | ||
279 | case MIPS_REVISION_CORID_CORE_20K: | ||
280 | _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); | ||
281 | |||
282 | /* | ||
283 | * Disable Bonito IOBC. | ||
284 | */ | ||
285 | BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & | ||
286 | ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | ||
287 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | ||
288 | |||
289 | /* | ||
290 | * Setup the North bridge to do Master byte-lane swapping | ||
291 | * when running in bigendian. | ||
292 | */ | ||
293 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
294 | BONITO_BONGENCFG = BONITO_BONGENCFG & | ||
295 | ~(BONITO_BONGENCFG_MSTRBYTESWAP | | ||
296 | BONITO_BONGENCFG_BYTESWAP); | ||
297 | #else | ||
298 | BONITO_BONGENCFG = BONITO_BONGENCFG | | ||
299 | BONITO_BONGENCFG_MSTRBYTESWAP | | ||
300 | BONITO_BONGENCFG_BYTESWAP; | ||
301 | #endif | ||
302 | |||
303 | #ifdef CONFIG_MIPS_MALTA | ||
304 | set_io_port_base(MALTA_BONITO_PORT_BASE); | ||
305 | #else | ||
306 | set_io_port_base((unsigned long)ioremap(0, 0x20000000)); | ||
307 | #endif | ||
308 | break; | ||
309 | |||
310 | case MIPS_REVISION_CORID_CORE_MSC: | ||
311 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
312 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
313 | _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); | ||
314 | |||
315 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
316 | MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); | ||
317 | #else | ||
318 | MSC_WRITE(MSC01_PCI_SWAP, | ||
319 | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF | | ||
320 | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | | ||
321 | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); | ||
322 | #endif | ||
323 | |||
324 | #ifdef CONFIG_MIPS_MALTA | ||
325 | set_io_port_base(MALTA_MSC_PORT_BASE); | ||
326 | #else | ||
327 | set_io_port_base((unsigned long)ioremap(0, 0x20000000)); | ||
328 | #endif | ||
329 | break; | ||
330 | |||
331 | default: | ||
332 | /* Unknown Core card */ | ||
333 | mips_display_message("CC Error"); | ||
334 | while(1); /* We die here... */ | ||
335 | } | ||
336 | #endif | ||
337 | prom_printf("\nLINUX started...\n"); | ||
338 | prom_init_cmdline(); | ||
339 | prom_meminit(); | ||
340 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
341 | console_config(); | ||
342 | #endif | ||
343 | } | ||
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c new file mode 100644 index 000000000000..5ae2b43e4c2e --- /dev/null +++ b/arch/mips/mips-boards/generic/memory.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * PROM library functions for acquiring/using memory descriptors given to | ||
19 | * us from the YAMON. | ||
20 | */ | ||
21 | #include <linux/config.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/bootmem.h> | ||
25 | |||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/page.h> | ||
28 | |||
29 | #include <asm/mips-boards/prom.h> | ||
30 | |||
31 | /*#define DEBUG*/ | ||
32 | |||
33 | enum yamon_memtypes { | ||
34 | yamon_dontuse, | ||
35 | yamon_prom, | ||
36 | yamon_free, | ||
37 | }; | ||
38 | struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; | ||
39 | |||
40 | #ifdef DEBUG | ||
41 | static char *mtypes[3] = { | ||
42 | "Dont use memory", | ||
43 | "YAMON PROM memory", | ||
44 | "Free memmory", | ||
45 | }; | ||
46 | #endif | ||
47 | |||
48 | /* References to section boundaries */ | ||
49 | extern char _end; | ||
50 | |||
51 | #define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) | ||
52 | |||
53 | |||
54 | struct prom_pmemblock * __init prom_getmdesc(void) | ||
55 | { | ||
56 | char *memsize_str; | ||
57 | unsigned int memsize; | ||
58 | |||
59 | memsize_str = prom_getenv("memsize"); | ||
60 | if (!memsize_str) { | ||
61 | prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); | ||
62 | memsize = 0x02000000; | ||
63 | } else { | ||
64 | #ifdef DEBUG | ||
65 | prom_printf("prom_memsize = %s\n", memsize_str); | ||
66 | #endif | ||
67 | memsize = simple_strtol(memsize_str, NULL, 0); | ||
68 | } | ||
69 | |||
70 | memset(mdesc, 0, sizeof(mdesc)); | ||
71 | |||
72 | mdesc[0].type = yamon_dontuse; | ||
73 | mdesc[0].base = 0x00000000; | ||
74 | mdesc[0].size = 0x00001000; | ||
75 | |||
76 | mdesc[1].type = yamon_prom; | ||
77 | mdesc[1].base = 0x00001000; | ||
78 | mdesc[1].size = 0x000ef000; | ||
79 | |||
80 | #ifdef CONFIG_MIPS_MALTA | ||
81 | /* | ||
82 | * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the | ||
83 | * south bridge and PCI access always forwarded to the ISA Bus and | ||
84 | * BIOSCS# is always generated. | ||
85 | * This mean that this area can't be used as DMA memory for PCI | ||
86 | * devices. | ||
87 | */ | ||
88 | mdesc[2].type = yamon_dontuse; | ||
89 | mdesc[2].base = 0x000f0000; | ||
90 | mdesc[2].size = 0x00010000; | ||
91 | #else | ||
92 | mdesc[2].type = yamon_prom; | ||
93 | mdesc[2].base = 0x000f0000; | ||
94 | mdesc[2].size = 0x00010000; | ||
95 | #endif | ||
96 | |||
97 | mdesc[3].type = yamon_dontuse; | ||
98 | mdesc[3].base = 0x00100000; | ||
99 | mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base; | ||
100 | |||
101 | mdesc[4].type = yamon_free; | ||
102 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); | ||
103 | mdesc[4].size = memsize - mdesc[4].base; | ||
104 | |||
105 | return &mdesc[0]; | ||
106 | } | ||
107 | |||
108 | static int __init prom_memtype_classify (unsigned int type) | ||
109 | { | ||
110 | switch (type) { | ||
111 | case yamon_free: | ||
112 | return BOOT_MEM_RAM; | ||
113 | case yamon_prom: | ||
114 | return BOOT_MEM_ROM_DATA; | ||
115 | default: | ||
116 | return BOOT_MEM_RESERVED; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | void __init prom_meminit(void) | ||
121 | { | ||
122 | struct prom_pmemblock *p; | ||
123 | |||
124 | #ifdef DEBUG | ||
125 | prom_printf("YAMON MEMORY DESCRIPTOR dump:\n"); | ||
126 | p = prom_getmdesc(); | ||
127 | while (p->size) { | ||
128 | int i = 0; | ||
129 | prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", | ||
130 | i, p, p->base, p->size, mtypes[p->type]); | ||
131 | p++; | ||
132 | i++; | ||
133 | } | ||
134 | #endif | ||
135 | p = prom_getmdesc(); | ||
136 | |||
137 | while (p->size) { | ||
138 | long type; | ||
139 | unsigned long base, size; | ||
140 | |||
141 | type = prom_memtype_classify (p->type); | ||
142 | base = p->base; | ||
143 | size = p->size; | ||
144 | |||
145 | add_memory_region(base, size, type); | ||
146 | p++; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | unsigned long __init prom_free_prom_memory(void) | ||
151 | { | ||
152 | unsigned long freed = 0; | ||
153 | unsigned long addr; | ||
154 | int i; | ||
155 | |||
156 | for (i = 0; i < boot_mem_map.nr_map; i++) { | ||
157 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | ||
158 | continue; | ||
159 | |||
160 | addr = boot_mem_map.map[i].addr; | ||
161 | while (addr < boot_mem_map.map[i].addr | ||
162 | + boot_mem_map.map[i].size) { | ||
163 | ClearPageReserved(virt_to_page(__va(addr))); | ||
164 | set_page_count(virt_to_page(__va(addr)), 1); | ||
165 | free_page((unsigned long)__va(addr)); | ||
166 | addr += PAGE_SIZE; | ||
167 | freed += PAGE_SIZE; | ||
168 | } | ||
169 | } | ||
170 | printk("Freeing prom memory: %ldkb freed\n", freed >> 10); | ||
171 | |||
172 | return freed; | ||
173 | } | ||
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S new file mode 100644 index 000000000000..131f49bccb20 --- /dev/null +++ b/arch/mips/mips-boards/generic/mipsIRQ.S | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Interrupt exception dispatch code. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | |||
27 | #include <asm/asm.h> | ||
28 | #include <asm/mipsregs.h> | ||
29 | #include <asm/regdef.h> | ||
30 | #include <asm/stackframe.h> | ||
31 | |||
32 | /* A lot of complication here is taken away because: | ||
33 | * | ||
34 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
35 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
36 | * common case is one pending IRQ so optimize in that direction. | ||
37 | * | ||
38 | * 2) We need not check against bits in the status register IRQ mask, that | ||
39 | * would make this routine slow as hell. | ||
40 | * | ||
41 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
42 | * between like BSD spl() brain-damage. | ||
43 | * | ||
44 | * Furthermore, the IRQs on the MIPS board look basically (barring software | ||
45 | * IRQs which we don't use at all and all external interrupt sources are | ||
46 | * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
47 | * | ||
48 | * MIPS IRQ Source | ||
49 | * -------- ------ | ||
50 | * 0 Software (ignored) | ||
51 | * 1 Software (ignored) | ||
52 | * 2 Combined hardware interrupt (hw0) | ||
53 | * 3 Hardware (ignored) | ||
54 | * 4 Hardware (ignored) | ||
55 | * 5 Hardware (ignored) | ||
56 | * 6 Hardware (ignored) | ||
57 | * 7 R4k timer (what we use) | ||
58 | * | ||
59 | * Note: On the SEAD board thing are a little bit different. | ||
60 | * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired | ||
61 | * wired to UART1. | ||
62 | * | ||
63 | * We handle the IRQ according to _our_ priority which is: | ||
64 | * | ||
65 | * Highest ---- R4k Timer | ||
66 | * Lowest ---- Combined hardware interrupt | ||
67 | * | ||
68 | * then we just return, if multiple IRQs are pending then we will just take | ||
69 | * another exception, big deal. | ||
70 | */ | ||
71 | |||
72 | .text | ||
73 | .set noreorder | ||
74 | .set noat | ||
75 | .align 5 | ||
76 | NESTED(mipsIRQ, PT_SIZE, sp) | ||
77 | SAVE_ALL | ||
78 | CLI | ||
79 | .set at | ||
80 | |||
81 | mfc0 s0, CP0_CAUSE # get irq bits | ||
82 | mfc0 s1, CP0_STATUS # get irq mask | ||
83 | and s0, s1 | ||
84 | |||
85 | /* First we check for r4k counter/timer IRQ. */ | ||
86 | andi a0, s0, CAUSEF_IP7 | ||
87 | beq a0, zero, 1f | ||
88 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | ||
89 | |||
90 | /* Wheee, a timer interrupt. */ | ||
91 | move a0, sp | ||
92 | jal mips_timer_interrupt | ||
93 | nop | ||
94 | |||
95 | j ret_from_irq | ||
96 | nop | ||
97 | |||
98 | 1: | ||
99 | #if defined(CONFIG_MIPS_SEAD) | ||
100 | beq a0, zero, 1f | ||
101 | andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt | ||
102 | #else | ||
103 | beq a0, zero, 1f # delay slot, check hw3 interrupt | ||
104 | andi a0, s0, CAUSEF_IP5 | ||
105 | #endif | ||
106 | |||
107 | /* Wheee, combined hardware level zero interrupt. */ | ||
108 | #if defined(CONFIG_MIPS_ATLAS) | ||
109 | jal atlas_hw0_irqdispatch | ||
110 | #elif defined(CONFIG_MIPS_MALTA) | ||
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 | |||
119 | j ret_from_irq | ||
120 | nop # delay slot | ||
121 | |||
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 | nop | ||
139 | 1: | ||
140 | #endif | ||
141 | /* | ||
142 | * Here by mistake? This is possible, what can happen is that by the | ||
143 | * time we take the exception the IRQ pin goes low, so just leave if | ||
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 | |||
151 | j ret_from_irq | ||
152 | nop | ||
153 | END(mipsIRQ) | ||
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c new file mode 100644 index 000000000000..92c34bda02ae --- /dev/null +++ b/arch/mips/mips-boards/generic/pci.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * MIPS boards specific PCI support. | ||
21 | */ | ||
22 | #include <linux/config.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/init.h> | ||
27 | |||
28 | #include <asm/mips-boards/generic.h> | ||
29 | #include <asm/gt64120.h> | ||
30 | #include <asm/mips-boards/bonito64.h> | ||
31 | #include <asm/mips-boards/msc01_pci.h> | ||
32 | #ifdef CONFIG_MIPS_MALTA | ||
33 | #include <asm/mips-boards/malta.h> | ||
34 | #endif | ||
35 | |||
36 | static struct resource bonito64_mem_resource = { | ||
37 | .name = "Bonito PCI MEM", | ||
38 | .start = 0x10000000UL, | ||
39 | .end = 0x1bffffffUL, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }; | ||
42 | |||
43 | static struct resource bonito64_io_resource = { | ||
44 | .name = "Bonito IO MEM", | ||
45 | .start = 0x00002000UL, /* avoid conflicts with YAMON allocated I/O addresses */ | ||
46 | .end = 0x000fffffUL, | ||
47 | .flags = IORESOURCE_IO, | ||
48 | }; | ||
49 | |||
50 | static struct resource gt64120_mem_resource = { | ||
51 | .name = "GT64120 PCI MEM", | ||
52 | .start = 0x10000000UL, | ||
53 | .end = 0x1bdfffffUL, | ||
54 | .flags = IORESOURCE_MEM, | ||
55 | }; | ||
56 | |||
57 | static struct resource gt64120_io_resource = { | ||
58 | .name = "GT64120 IO MEM", | ||
59 | #ifdef CONFIG_MIPS_ATLAS | ||
60 | .start = 0x18000000UL, | ||
61 | .end = 0x181fffffUL, | ||
62 | #endif | ||
63 | #ifdef CONFIG_MIPS_MALTA | ||
64 | .start = 0x00002000UL, | ||
65 | .end = 0x001fffffUL, | ||
66 | #endif | ||
67 | .flags = IORESOURCE_IO, | ||
68 | }; | ||
69 | |||
70 | static struct resource msc_mem_resource = { | ||
71 | .name = "MSC PCI MEM", | ||
72 | .start = 0x10000000UL, | ||
73 | .end = 0x1fffffffUL, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }; | ||
76 | |||
77 | static struct resource msc_io_resource = { | ||
78 | .name = "MSC IO MEM", | ||
79 | .start = 0x00002000UL, | ||
80 | .end = 0x007fffffUL, | ||
81 | .flags = IORESOURCE_IO, | ||
82 | }; | ||
83 | |||
84 | extern struct pci_ops bonito64_pci_ops; | ||
85 | extern struct pci_ops gt64120_pci_ops; | ||
86 | extern struct pci_ops msc_pci_ops; | ||
87 | |||
88 | static struct pci_controller bonito64_controller = { | ||
89 | .pci_ops = &bonito64_pci_ops, | ||
90 | .io_resource = &bonito64_io_resource, | ||
91 | .mem_resource = &bonito64_mem_resource, | ||
92 | .mem_offset = 0x10000000UL, | ||
93 | .io_offset = 0x00000000UL, | ||
94 | }; | ||
95 | |||
96 | static struct pci_controller gt64120_controller = { | ||
97 | .pci_ops = >64120_pci_ops, | ||
98 | .io_resource = >64120_io_resource, | ||
99 | .mem_resource = >64120_mem_resource, | ||
100 | .mem_offset = 0x00000000UL, | ||
101 | .io_offset = 0x00000000UL, | ||
102 | }; | ||
103 | |||
104 | static struct pci_controller msc_controller = { | ||
105 | .pci_ops = &msc_pci_ops, | ||
106 | .io_resource = &msc_io_resource, | ||
107 | .mem_resource = &msc_mem_resource, | ||
108 | .mem_offset = 0x10000000UL, | ||
109 | .io_offset = 0x00000000UL, | ||
110 | }; | ||
111 | |||
112 | static int __init pcibios_init(void) | ||
113 | { | ||
114 | struct pci_controller *controller; | ||
115 | |||
116 | switch (mips_revision_corid) { | ||
117 | case MIPS_REVISION_CORID_QED_RM5261: | ||
118 | case MIPS_REVISION_CORID_CORE_LV: | ||
119 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
120 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
121 | /* | ||
122 | * Due to a bug in the Galileo system controller, we need | ||
123 | * to setup the PCI BAR for the Galileo internal registers. | ||
124 | * This should be done in the bios/bootprom and will be | ||
125 | * fixed in a later revision of YAMON (the MIPS boards | ||
126 | * boot prom). | ||
127 | */ | ||
128 | GT_WRITE(GT_PCI0_CFGADDR_OFS, | ||
129 | (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ | ||
130 | (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ | ||
131 | (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ | ||
132 | ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ | ||
133 | GT_PCI0_CFGADDR_CONFIGEN_BIT ); | ||
134 | |||
135 | /* Perform the write */ | ||
136 | GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); | ||
137 | |||
138 | controller = >64120_controller; | ||
139 | break; | ||
140 | |||
141 | case MIPS_REVISION_CORID_BONITO64: | ||
142 | case MIPS_REVISION_CORID_CORE_20K: | ||
143 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
144 | controller = &bonito64_controller; | ||
145 | break; | ||
146 | |||
147 | case MIPS_REVISION_CORID_CORE_MSC: | ||
148 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
149 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
150 | controller = &msc_controller; | ||
151 | break; | ||
152 | default: | ||
153 | return 1; | ||
154 | } | ||
155 | |||
156 | ioport_resource.end = controller->io_resource->end; | ||
157 | |||
158 | register_pci_controller (controller); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | early_initcall(pcibios_init); | ||
diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c new file mode 100644 index 000000000000..2c1ab1f19fdc --- /dev/null +++ b/arch/mips/mips-boards/generic/printf.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Putting things on the screen/serial line using YAMONs facilities. | ||
19 | */ | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/serial_reg.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #ifdef CONFIG_MIPS_ATLAS | ||
28 | #include <asm/mips-boards/atlas.h> | ||
29 | |||
30 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
31 | #define PORT(offset) (ATLAS_UART_REGS_BASE + ((offset)<<3)) | ||
32 | #else | ||
33 | #define PORT(offset) (ATLAS_UART_REGS_BASE + 3 + ((offset)<<3)) | ||
34 | #endif | ||
35 | |||
36 | #elif defined(CONFIG_MIPS_SEAD) | ||
37 | |||
38 | #include <asm/mips-boards/sead.h> | ||
39 | |||
40 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
41 | #define PORT(offset) (SEAD_UART0_REGS_BASE + ((offset)<<3)) | ||
42 | #else | ||
43 | #define PORT(offset) (SEAD_UART0_REGS_BASE + 3 + ((offset)<<3)) | ||
44 | #endif | ||
45 | |||
46 | #else | ||
47 | |||
48 | #define PORT(offset) (0x3f8 + (offset)) | ||
49 | |||
50 | #endif | ||
51 | |||
52 | static inline unsigned int serial_in(int offset) | ||
53 | { | ||
54 | return inb(PORT(offset)); | ||
55 | } | ||
56 | |||
57 | static inline void serial_out(int offset, int value) | ||
58 | { | ||
59 | outb(value, PORT(offset)); | ||
60 | } | ||
61 | |||
62 | int prom_putchar(char c) | ||
63 | { | ||
64 | while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) | ||
65 | ; | ||
66 | |||
67 | serial_out(UART_TX, c); | ||
68 | |||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | char prom_getchar(void) | ||
73 | { | ||
74 | while (!(serial_in(UART_LSR) & UART_LSR_DR)) | ||
75 | ; | ||
76 | |||
77 | return serial_in(UART_RX); | ||
78 | } | ||
79 | |||
diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c new file mode 100644 index 000000000000..9fdec743bd95 --- /dev/null +++ b/arch/mips/mips-boards/generic/reset.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Reset the MIPS boards. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | #include <asm/reboot.h> | ||
29 | #include <asm/mips-boards/generic.h> | ||
30 | #if defined(CONFIG_MIPS_ATLAS) | ||
31 | #include <asm/mips-boards/atlas.h> | ||
32 | #endif | ||
33 | |||
34 | static void mips_machine_restart(char *command); | ||
35 | static void mips_machine_halt(void); | ||
36 | #if defined(CONFIG_MIPS_ATLAS) | ||
37 | static void atlas_machine_power_off(void); | ||
38 | #endif | ||
39 | |||
40 | static void mips_machine_restart(char *command) | ||
41 | { | ||
42 | volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int)); | ||
43 | |||
44 | *softres_reg = GORESET; | ||
45 | } | ||
46 | |||
47 | static void mips_machine_halt(void) | ||
48 | { | ||
49 | volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int)); | ||
50 | |||
51 | *softres_reg = GORESET; | ||
52 | } | ||
53 | |||
54 | #if defined(CONFIG_MIPS_ATLAS) | ||
55 | static void atlas_machine_power_off(void) | ||
56 | { | ||
57 | volatile unsigned int *psustby_reg = (unsigned int *)ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int)); | ||
58 | |||
59 | *psustby_reg = ATLAS_GOSTBY; | ||
60 | } | ||
61 | #endif | ||
62 | |||
63 | void mips_reboot_setup(void) | ||
64 | { | ||
65 | _machine_restart = mips_machine_restart; | ||
66 | _machine_halt = mips_machine_halt; | ||
67 | #if defined(CONFIG_MIPS_ATLAS) | ||
68 | _machine_power_off = atlas_machine_power_off; | ||
69 | #endif | ||
70 | #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD) | ||
71 | _machine_power_off = mips_machine_halt; | ||
72 | #endif | ||
73 | } | ||
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c new file mode 100644 index 000000000000..fe7fc17305a6 --- /dev/null +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Setting up the clock on the MIPS boards. | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/config.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/kernel_stat.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/time.h> | ||
29 | #include <linux/timex.h> | ||
30 | #include <linux/mc146818rtc.h> | ||
31 | |||
32 | #include <asm/mipsregs.h> | ||
33 | #include <asm/ptrace.h> | ||
34 | #include <asm/div64.h> | ||
35 | #include <asm/cpu.h> | ||
36 | #include <asm/time.h> | ||
37 | #include <asm/mc146818-time.h> | ||
38 | |||
39 | #include <asm/mips-boards/generic.h> | ||
40 | #include <asm/mips-boards/prom.h> | ||
41 | |||
42 | unsigned long cpu_khz; | ||
43 | |||
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) | ||
51 | static char display_string[] = " LINUX ON ATLAS "; | ||
52 | #endif | ||
53 | #if defined(CONFIG_MIPS_MALTA) | ||
54 | static char display_string[] = " LINUX ON MALTA "; | ||
55 | #endif | ||
56 | #if defined(CONFIG_MIPS_SEAD) | ||
57 | static char display_string[] = " LINUX ON SEAD "; | ||
58 | #endif | ||
59 | static unsigned int display_count = 0; | ||
60 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | ||
61 | |||
62 | #define MIPS_CPU_TIMER_IRQ (NR_IRQS-1) | ||
63 | |||
64 | static unsigned int timer_tick_count=0; | ||
65 | |||
66 | void mips_timer_interrupt(struct pt_regs *regs) | ||
67 | { | ||
68 | if ((timer_tick_count++ % HZ) == 0) { | ||
69 | mips_display_message(&display_string[display_count++]); | ||
70 | if (display_count == MAX_DISPLAY_COUNT) | ||
71 | display_count = 0; | ||
72 | |||
73 | } | ||
74 | |||
75 | ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect | ||
80 | */ | ||
81 | static unsigned int __init estimate_cpu_frequency(void) | ||
82 | { | ||
83 | unsigned int prid = read_c0_prid() & 0xffff00; | ||
84 | unsigned int count; | ||
85 | |||
86 | #ifdef CONFIG_MIPS_SEAD | ||
87 | /* | ||
88 | * The SEAD board doesn't have a real time clock, so we can't | ||
89 | * really calculate the timer frequency | ||
90 | * For now we hardwire the SEAD board frequency to 12MHz. | ||
91 | */ | ||
92 | |||
93 | if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) || | ||
94 | (prid == (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
95 | count = 12000000; | ||
96 | else | ||
97 | count = 6000000; | ||
98 | #endif | ||
99 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | ||
100 | unsigned int flags; | ||
101 | |||
102 | local_irq_save(flags); | ||
103 | |||
104 | /* Start counter exactly on falling edge of update flag */ | ||
105 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
106 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
107 | |||
108 | /* Start r4k counter. */ | ||
109 | write_c0_count(0); | ||
110 | |||
111 | /* Read counter exactly on falling edge of update flag */ | ||
112 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
113 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
114 | |||
115 | count = read_c0_count(); | ||
116 | |||
117 | /* restore interrupts */ | ||
118 | local_irq_restore(flags); | ||
119 | #endif | ||
120 | |||
121 | mips_hpt_frequency = count; | ||
122 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | ||
123 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
124 | count *= 2; | ||
125 | |||
126 | count += 5000; /* round */ | ||
127 | count -= count%10000; | ||
128 | |||
129 | return count; | ||
130 | } | ||
131 | |||
132 | unsigned long __init mips_rtc_get_time(void) | ||
133 | { | ||
134 | return mc146818_get_cmos_time(); | ||
135 | } | ||
136 | |||
137 | void __init mips_time_init(void) | ||
138 | { | ||
139 | unsigned int est_freq, flags; | ||
140 | |||
141 | local_irq_save(flags); | ||
142 | |||
143 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | ||
144 | /* Set Data mode - binary. */ | ||
145 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
146 | #endif | ||
147 | |||
148 | est_freq = estimate_cpu_frequency (); | ||
149 | |||
150 | printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, | ||
151 | (est_freq%1000000)*100/1000000); | ||
152 | |||
153 | cpu_khz = est_freq / 1000; | ||
154 | |||
155 | local_irq_restore(flags); | ||
156 | } | ||
157 | |||
158 | void __init mips_timer_setup(struct irqaction *irq) | ||
159 | { | ||
160 | /* we are using the cpu counter for timer interrupts */ | ||
161 | irq->handler = no_action; /* we use our own handler */ | ||
162 | setup_irq(MIPS_CPU_TIMER_IRQ, irq); | ||
163 | |||
164 | /* to generate the first timer interrupt */ | ||
165 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); | ||
166 | set_c0_status(ALLINTS); | ||
167 | } | ||