It turned out that using some Open Firmware routines causes the system freeze after calling OF_quiesce(). This is why setting color palette crash the system for some Power Mac G5 models, like PowerMac11,2. Therefore, stop using color-palette and backlight callbacks for genfb(4) in this case. Also, postpone OF_quiesce() after rascons_init_rasops(), and initialize color palette there if OF is going to be quiesced and color depth is 8. Now, color palette for wscons is initialized correctly for PowerMac11,2.diff -r1.19 -r1.20 src/sys/arch/macppc/include/autoconf.h
(rin)
--- src/sys/arch/macppc/include/autoconf.h 2019/01/08 07:46:10 1.19
+++ src/sys/arch/macppc/include/autoconf.h 2020/07/07 02:33:54 1.20
@@ -1,87 +1,88 @@ | @@ -1,87 +1,88 @@ | |||
1 | /* $NetBSD: autoconf.h,v 1.19 2019/01/08 07:46:10 mrg Exp $ */ | 1 | /* $NetBSD: autoconf.h,v 1.20 2020/07/07 02:33:54 rin Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (C) 1998 Internet Research Institute, Inc. | 4 | * Copyright (C) 1998 Internet Research Institute, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * 3. All advertising materials mentioning features or use of this software | 15 | * 3. All advertising materials mentioning features or use of this software | |
16 | * must display the following acknowledgement: | 16 | * must display the following acknowledgement: | |
17 | * This product includes software developed by | 17 | * This product includes software developed by | |
18 | * Internet Research Institute, Inc. | 18 | * Internet Research Institute, Inc. | |
19 | * 4. The name of the author may not be used to endorse or promote products | 19 | * 4. The name of the author may not be used to endorse or promote products | |
20 | * derived from this software without specific prior written permission. | 20 | * derived from this software without specific prior written permission. | |
21 | * | 21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #ifndef _MACHINE_AUTOCONF_H_ | 34 | #ifndef _MACHINE_AUTOCONF_H_ | |
35 | #define _MACHINE_AUTOCONF_H_ | 35 | #define _MACHINE_AUTOCONF_H_ | |
36 | 36 | |||
37 | #include <sys/bus.h> | 37 | #include <sys/bus.h> | |
38 | 38 | |||
39 | #include <prop/proplib.h> | 39 | #include <prop/proplib.h> | |
40 | 40 | |||
41 | struct confargs { | 41 | struct confargs { | |
42 | const char *ca_name; | 42 | const char *ca_name; | |
43 | u_int ca_node; | 43 | u_int ca_node; | |
44 | int ca_nreg; | 44 | int ca_nreg; | |
45 | u_int *ca_reg; | 45 | u_int *ca_reg; | |
46 | int ca_nintr; | 46 | int ca_nintr; | |
47 | int *ca_intr; | 47 | int *ca_intr; | |
48 | 48 | |||
49 | bus_addr_t ca_baseaddr; | 49 | bus_addr_t ca_baseaddr; | |
50 | bus_space_tag_t ca_tag; | 50 | bus_space_tag_t ca_tag; | |
51 | }; | 51 | }; | |
52 | 52 | |||
53 | /* there are in locore.S */ | 53 | /* there are in locore.S */ | |
54 | void ofbcopy(const void *, void *, size_t); | 54 | void ofbcopy(const void *, void *, size_t); | |
55 | int badaddr(volatile void *, int); | 55 | int badaddr(volatile void *, int); | |
56 | 56 | |||
57 | /* these are in clock.c */ | 57 | /* these are in clock.c */ | |
58 | void calc_delayconst(void); | 58 | void calc_delayconst(void); | |
59 | void decr_intr(struct clockframe *); | 59 | void decr_intr(struct clockframe *); | |
60 | 60 | |||
61 | /* these are in cpu.c */ | 61 | /* these are in cpu.c */ | |
62 | void identifycpu(char *); | 62 | void identifycpu(char *); | |
63 | 63 | |||
64 | /* these are in machdep.c */ | 64 | /* these are in machdep.c */ | |
65 | void initppc(u_int, u_int, char *); | 65 | void initppc(u_int, u_int, char *); | |
66 | void model_init(void); | 66 | void model_init(void); | |
67 | paddr_t kvtop(void *); | 67 | paddr_t kvtop(void *); | |
68 | void dumpsys(void); | 68 | void dumpsys(void); | |
69 | void copy_disp_props(device_t, int, prop_dictionary_t); | 69 | void copy_disp_props(device_t, int, prop_dictionary_t); | |
70 | 70 | |||
71 | /* these are in extintr.c */ | 71 | /* these are in extintr.c */ | |
72 | void init_interrupt(void); | 72 | void init_interrupt(void); | |
73 | 73 | |||
74 | /* these are in dev/akbd.c */ | 74 | /* these are in dev/akbd.c */ | |
75 | int kbd_intr(void *); | 75 | int kbd_intr(void *); | |
76 | int akbd_cnattach(void); | 76 | int akbd_cnattach(void); | |
77 | int adbkbd_cnattach(void); | 77 | int adbkbd_cnattach(void); | |
78 | 78 | |||
79 | /* these are in dev/ofb.c */ | 79 | /* these are in dev/ofb.c */ | |
80 | int ofb_is_console(void); | 80 | int ofb_is_console(void); | |
81 | int rascons_cnattach(void); | 81 | int rascons_cnattach(void); | |
82 | 82 | |||
83 | extern int console_node; | 83 | extern int console_node; | |
84 | extern int console_instance; | 84 | extern int console_instance; | |
85 | extern int ofw_quiesce; | |||
85 | extern char model_name[64]; | 86 | extern char model_name[64]; | |
86 | 87 | |||
87 | #endif /* _MACHINE_AUTOCONF_H_ */ | 88 | #endif /* _MACHINE_AUTOCONF_H_ */ |
--- src/sys/arch/macppc/macppc/machdep.c 2019/01/28 02:25:01 1.169
+++ src/sys/arch/macppc/macppc/machdep.c 2020/07/07 02:33:54 1.170
@@ -1,503 +1,513 @@ | @@ -1,503 +1,513 @@ | |||
1 | /* $NetBSD: machdep.c,v 1.169 2019/01/28 02:25:01 sevan Exp $ */ | 1 | /* $NetBSD: machdep.c,v 1.170 2020/07/07 02:33:54 rin Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (C) 1995, 1996 Wolfgang Solfrank. | 4 | * Copyright (C) 1995, 1996 Wolfgang Solfrank. | |
5 | * Copyright (C) 1995, 1996 TooLs GmbH. | 5 | * Copyright (C) 1995, 1996 TooLs GmbH. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | 15 | * documentation and/or other materials provided with the distribution. | |
16 | * 3. All advertising materials mentioning features or use of this software | 16 | * 3. All advertising materials mentioning features or use of this software | |
17 | * must display the following acknowledgement: | 17 | * must display the following acknowledgement: | |
18 | * This product includes software developed by TooLs GmbH. | 18 | * This product includes software developed by TooLs GmbH. | |
19 | * 4. The name of TooLs GmbH may not be used to endorse or promote products | 19 | * 4. The name of TooLs GmbH may not be used to endorse or promote products | |
20 | * derived from this software without specific prior written permission. | 20 | * derived from this software without specific prior written permission. | |
21 | * | 21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR | 22 | * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR | |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
25 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 25 | * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 27 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
28 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 28 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 29 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
30 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | 30 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
31 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.169 2019/01/28 02:25:01 sevan Exp $"); | 35 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.170 2020/07/07 02:33:54 rin Exp $"); | |
36 | 36 | |||
37 | #include "opt_compat_netbsd.h" | 37 | #include "opt_compat_netbsd.h" | |
38 | #include "opt_ddb.h" | 38 | #include "opt_ddb.h" | |
39 | #include "opt_kgdb.h" | 39 | #include "opt_kgdb.h" | |
40 | #include "opt_altivec.h" | 40 | #include "opt_altivec.h" | |
41 | #include "opt_multiprocessor.h" | 41 | #include "opt_multiprocessor.h" | |
42 | #include "adb.h" | 42 | #include "adb.h" | |
43 | #include "zsc.h" | 43 | #include "zsc.h" | |
44 | 44 | |||
45 | #include <sys/param.h> | 45 | #include <sys/param.h> | |
46 | #include <sys/buf.h> | 46 | #include <sys/buf.h> | |
47 | #include <sys/boot_flag.h> | 47 | #include <sys/boot_flag.h> | |
48 | #include <sys/bus.h> | 48 | #include <sys/bus.h> | |
49 | #include <sys/conf.h> | 49 | #include <sys/conf.h> | |
50 | #include <sys/device.h> | 50 | #include <sys/device.h> | |
51 | #include <sys/exec.h> | 51 | #include <sys/exec.h> | |
52 | #include <sys/kernel.h> | 52 | #include <sys/kernel.h> | |
53 | #include <sys/ksyms.h> | 53 | #include <sys/ksyms.h> | |
54 | #include <sys/mbuf.h> | 54 | #include <sys/mbuf.h> | |
55 | #include <sys/mount.h> | 55 | #include <sys/mount.h> | |
56 | #include <sys/msgbuf.h> | 56 | #include <sys/msgbuf.h> | |
57 | #include <sys/proc.h> | 57 | #include <sys/proc.h> | |
58 | #include <sys/reboot.h> | 58 | #include <sys/reboot.h> | |
59 | #include <sys/syscallargs.h> | 59 | #include <sys/syscallargs.h> | |
60 | #include <sys/syslog.h> | 60 | #include <sys/syslog.h> | |
61 | #include <sys/systm.h> | 61 | #include <sys/systm.h> | |
62 | 62 | |||
63 | #ifdef DDB | 63 | #ifdef DDB | |
64 | #include <powerpc/db_machdep.h> | 64 | #include <powerpc/db_machdep.h> | |
65 | #include <ddb/db_extern.h> | 65 | #include <ddb/db_extern.h> | |
66 | #endif | 66 | #endif | |
67 | 67 | |||
68 | #ifdef KGDB | 68 | #ifdef KGDB | |
69 | #include <sys/kgdb.h> | 69 | #include <sys/kgdb.h> | |
70 | #endif | 70 | #endif | |
71 | 71 | |||
72 | #include <dev/ofw/openfirm.h> | 72 | #include <dev/ofw/openfirm.h> | |
73 | #include <dev/wsfb/genfbvar.h> | 73 | #include <dev/wsfb/genfbvar.h> | |
74 | 74 | |||
75 | #include <machine/autoconf.h> | 75 | #include <machine/autoconf.h> | |
76 | #include <machine/powerpc.h> | 76 | #include <machine/powerpc.h> | |
77 | 77 | |||
78 | #include <powerpc/trap.h> | 78 | #include <powerpc/trap.h> | |
79 | #include <powerpc/fpu.h> | 79 | #include <powerpc/fpu.h> | |
80 | #include <powerpc/oea/bat.h> | 80 | #include <powerpc/oea/bat.h> | |
81 | #include <powerpc/spr.h> | 81 | #include <powerpc/spr.h> | |
82 | #ifdef ALTIVEC | 82 | #ifdef ALTIVEC | |
83 | #include <powerpc/altivec.h> | 83 | #include <powerpc/altivec.h> | |
84 | #endif | 84 | #endif | |
85 | #include <powerpc/ofw_cons.h> | 85 | #include <powerpc/ofw_cons.h> | |
86 | 86 | |||
87 | #include <powerpc/pic/picvar.h> | 87 | #include <powerpc/pic/picvar.h> | |
88 | #ifdef MULTIPROCESSOR | 88 | #ifdef MULTIPROCESSOR | |
89 | #include <powerpc/pic/ipivar.h> | 89 | #include <powerpc/pic/ipivar.h> | |
90 | #endif | 90 | #endif | |
91 | 91 | |||
92 | #include <macppc/dev/adbvar.h> | 92 | #include <macppc/dev/adbvar.h> | |
93 | #include <macppc/dev/pmuvar.h> | 93 | #include <macppc/dev/pmuvar.h> | |
94 | #include <macppc/dev/cudavar.h> | 94 | #include <macppc/dev/cudavar.h> | |
95 | #include <macppc/dev/smuvar.h> | 95 | #include <macppc/dev/smuvar.h> | |
96 | 96 | |||
97 | #include <macppc/macppc/static_edid.h> | 97 | #include <macppc/macppc/static_edid.h> | |
98 | 98 | |||
99 | #include "ksyms.h" | 99 | #include "ksyms.h" | |
100 | #include "pmu.h" | 100 | #include "pmu.h" | |
101 | #include "cuda.h" | 101 | #include "cuda.h" | |
102 | #include "smu.h" | 102 | #include "smu.h" | |
103 | 103 | |||
104 | struct genfb_colormap_callback gfb_cb; | 104 | struct genfb_colormap_callback gfb_cb; | |
105 | struct genfb_parameter_callback gpc_backlight, gpc_brightness; | 105 | struct genfb_parameter_callback gpc_backlight, gpc_brightness; | |
106 | 106 | |||
107 | /* | 107 | /* | |
108 | * OpenFirmware gives us no way to check the brightness level or the backlight | 108 | * OpenFirmware gives us no way to check the brightness level or the backlight | |
109 | * state so we assume the backlight is on and about 4/5 up which seems | 109 | * state so we assume the backlight is on and about 4/5 up which seems | |
110 | * reasonable for most laptops | 110 | * reasonable for most laptops | |
111 | */ | 111 | */ | |
112 | 112 | |||
113 | int backlight_state = 1; | 113 | int backlight_state = 1; | |
114 | int brightness_level = 200; | 114 | int brightness_level = 200; | |
115 | 115 | |||
116 | static void of_set_palette(void *, int, int, int, int); | 116 | static void of_set_palette(void *, int, int, int, int); | |
117 | static void add_model_specifics(prop_dictionary_t); | 117 | static void add_model_specifics(prop_dictionary_t); | |
118 | static int of_get_backlight(void *, int *); | 118 | static int of_get_backlight(void *, int *); | |
119 | static int of_set_backlight(void *, int); | 119 | static int of_set_backlight(void *, int); | |
120 | static int of_get_brightness(void *, int *); | 120 | static int of_get_brightness(void *, int *); | |
121 | static int of_set_brightness(void *, int); | 121 | static int of_set_brightness(void *, int); | |
122 | static int of_upd_brightness(void *, int); | 122 | static int of_upd_brightness(void *, int); | |
123 | 123 | |||
124 | void | 124 | void | |
125 | initppc(u_int startkernel, u_int endkernel, char *args) | 125 | initppc(u_int startkernel, u_int endkernel, char *args) | |
126 | { | 126 | { | |
127 | ofwoea_initppc(startkernel, endkernel, args); | 127 | ofwoea_initppc(startkernel, endkernel, args); | |
128 | } | 128 | } | |
129 | 129 | |||
130 | /* perform model-specific actions at initppc() */ | 130 | /* perform model-specific actions at initppc() */ | |
131 | void | 131 | void | |
132 | model_init(void) | 132 | model_init(void) | |
133 | { | 133 | { | |
134 | } | 134 | } | |
135 | 135 | |||
136 | void | 136 | void | |
137 | consinit(void) | 137 | consinit(void) | |
138 | { | 138 | { | |
139 | ofwoea_consinit(); | 139 | ofwoea_consinit(); | |
140 | } | 140 | } | |
141 | 141 | |||
142 | /* | 142 | /* | |
143 | * Machine dependent startup code. | 143 | * Machine dependent startup code. | |
144 | */ | 144 | */ | |
145 | void | 145 | void | |
146 | cpu_startup(void) | 146 | cpu_startup(void) | |
147 | { | 147 | { | |
148 | oea_startup(NULL); | 148 | oea_startup(NULL); | |
149 | } | 149 | } | |
150 | 150 | |||
151 | /* | 151 | /* | |
152 | * Crash dump handling. | 152 | * Crash dump handling. | |
153 | */ | 153 | */ | |
154 | 154 | |||
155 | void | 155 | void | |
156 | dumpsys(void) | 156 | dumpsys(void) | |
157 | { | 157 | { | |
158 | printf("dumpsys: TBD\n"); | 158 | printf("dumpsys: TBD\n"); | |
159 | } | 159 | } | |
160 | 160 | |||
161 | /* | 161 | /* | |
162 | * Halt or reboot the machine after syncing/dumping according to howto. | 162 | * Halt or reboot the machine after syncing/dumping according to howto. | |
163 | */ | 163 | */ | |
164 | void | 164 | void | |
165 | cpu_reboot(int howto, char *what) | 165 | cpu_reboot(int howto, char *what) | |
166 | { | 166 | { | |
167 | static int syncing; | 167 | static int syncing; | |
168 | static char str[256]; | 168 | static char str[256]; | |
169 | char *ap = str, *ap1 = ap; | 169 | char *ap = str, *ap1 = ap; | |
170 | 170 | |||
171 | /* | 171 | /* | |
172 | * Enable external interrupts in case someone is rebooting | 172 | * Enable external interrupts in case someone is rebooting | |
173 | * from a strange context via ddb. | 173 | * from a strange context via ddb. | |
174 | */ | 174 | */ | |
175 | mtmsr(mfmsr() | PSL_EE); | 175 | mtmsr(mfmsr() | PSL_EE); | |
176 | 176 | |||
177 | boothowto = howto; | 177 | boothowto = howto; | |
178 | if (!cold && !(howto & RB_NOSYNC) && !syncing) { | 178 | if (!cold && !(howto & RB_NOSYNC) && !syncing) { | |
179 | syncing = 1; | 179 | syncing = 1; | |
180 | vfs_shutdown(); /* sync */ | 180 | vfs_shutdown(); /* sync */ | |
181 | resettodr(); /* set wall clock */ | 181 | resettodr(); /* set wall clock */ | |
182 | } | 182 | } | |
183 | 183 | |||
184 | #ifdef MULTIPROCESSOR | 184 | #ifdef MULTIPROCESSOR | |
185 | /* Halt other CPU */ | 185 | /* Halt other CPU */ | |
186 | cpu_send_ipi(IPI_DST_NOTME, IPI_HALT); | 186 | cpu_send_ipi(IPI_DST_NOTME, IPI_HALT); | |
187 | delay(100000); /* XXX */ | 187 | delay(100000); /* XXX */ | |
188 | #endif | 188 | #endif | |
189 | 189 | |||
190 | splhigh(); | 190 | splhigh(); | |
191 | 191 | |||
192 | if (!cold && (howto & RB_DUMP)) | 192 | if (!cold && (howto & RB_DUMP)) | |
193 | dumpsys(); | 193 | dumpsys(); | |
194 | 194 | |||
195 | doshutdownhooks(); | 195 | doshutdownhooks(); | |
196 | 196 | |||
197 | pmf_system_shutdown(boothowto); | 197 | pmf_system_shutdown(boothowto); | |
198 | 198 | |||
199 | if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { | 199 | if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { | |
200 | delay(1000000); | 200 | delay(1000000); | |
201 | #if NCUDA > 0 | 201 | #if NCUDA > 0 | |
202 | cuda_poweroff(); | 202 | cuda_poweroff(); | |
203 | #endif | 203 | #endif | |
204 | #if NPMU > 0 | 204 | #if NPMU > 0 | |
205 | pmu_poweroff(); | 205 | pmu_poweroff(); | |
206 | #endif | 206 | #endif | |
207 | #if NADB > 0 | 207 | #if NADB > 0 | |
208 | adb_poweroff(); | 208 | adb_poweroff(); | |
209 | printf("WARNING: powerdown failed!\n"); | 209 | printf("WARNING: powerdown failed!\n"); | |
210 | #endif | 210 | #endif | |
211 | #if NSMU > 0 | 211 | #if NSMU > 0 | |
212 | smu_poweroff(); | 212 | smu_poweroff(); | |
213 | #endif | 213 | #endif | |
214 | } | 214 | } | |
215 | 215 | |||
216 | if (howto & RB_HALT) { | 216 | if (howto & RB_HALT) { | |
217 | printf("halted\n\n"); | 217 | printf("halted\n\n"); | |
218 | 218 | |||
219 | /* flush cache for msgbuf */ | 219 | /* flush cache for msgbuf */ | |
220 | __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); | 220 | __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); | |
221 | 221 | |||
222 | ppc_exit(); | 222 | ppc_exit(); | |
223 | } | 223 | } | |
224 | 224 | |||
225 | printf("rebooting\n\n"); | 225 | printf("rebooting\n\n"); | |
226 | if (what && *what) { | 226 | if (what && *what) { | |
227 | if (strlen(what) > sizeof str - 5) | 227 | if (strlen(what) > sizeof str - 5) | |
228 | printf("boot string too large, ignored\n"); | 228 | printf("boot string too large, ignored\n"); | |
229 | else { | 229 | else { | |
230 | strcpy(str, what); | 230 | strcpy(str, what); | |
231 | ap1 = ap = str + strlen(str); | 231 | ap1 = ap = str + strlen(str); | |
232 | *ap++ = ' '; | 232 | *ap++ = ' '; | |
233 | } | 233 | } | |
234 | } | 234 | } | |
235 | *ap++ = '-'; | 235 | *ap++ = '-'; | |
236 | if (howto & RB_SINGLE) | 236 | if (howto & RB_SINGLE) | |
237 | *ap++ = 's'; | 237 | *ap++ = 's'; | |
238 | if (howto & RB_KDB) | 238 | if (howto & RB_KDB) | |
239 | *ap++ = 'd'; | 239 | *ap++ = 'd'; | |
240 | *ap++ = 0; | 240 | *ap++ = 0; | |
241 | if (ap[-2] == '-') | 241 | if (ap[-2] == '-') | |
242 | *ap1 = 0; | 242 | *ap1 = 0; | |
243 | 243 | |||
244 | /* flush cache for msgbuf */ | 244 | /* flush cache for msgbuf */ | |
245 | __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); | 245 | __syncicache((void *)msgbuf_paddr, round_page(MSGBUFSIZE)); | |
246 | 246 | |||
247 | #if NCUDA > 0 | 247 | #if NCUDA > 0 | |
248 | cuda_restart(); | 248 | cuda_restart(); | |
249 | #endif | 249 | #endif | |
250 | #if NPMU > 0 | 250 | #if NPMU > 0 | |
251 | pmu_restart(); | 251 | pmu_restart(); | |
252 | #endif | 252 | #endif | |
253 | #if NADB > 0 | 253 | #if NADB > 0 | |
254 | adb_restart(); /* not return */ | 254 | adb_restart(); /* not return */ | |
255 | #endif | 255 | #endif | |
256 | #if NSMU > 0 | 256 | #if NSMU > 0 | |
257 | smu_restart(); | 257 | smu_restart(); | |
258 | #endif | 258 | #endif | |
259 | ppc_exit(); | 259 | ppc_exit(); | |
260 | } | 260 | } | |
261 | 261 | |||
262 | #if 0 | 262 | #if 0 | |
263 | /* | 263 | /* | |
264 | * OpenFirmware callback routine | 264 | * OpenFirmware callback routine | |
265 | */ | 265 | */ | |
266 | void | 266 | void | |
267 | callback(void *p) | 267 | callback(void *p) | |
268 | { | 268 | { | |
269 | panic("callback"); /* for now XXX */ | 269 | panic("callback"); /* for now XXX */ | |
270 | } | 270 | } | |
271 | #endif | 271 | #endif | |
272 | 272 | |||
273 | void | 273 | void | |
274 | copy_disp_props(device_t dev, int node, prop_dictionary_t dict) | 274 | copy_disp_props(device_t dev, int node, prop_dictionary_t dict) | |
275 | { | 275 | { | |
276 | char name[32]; | 276 | char name[32]; | |
277 | uint32_t temp; | 277 | uint32_t temp; | |
278 | uint64_t cmap_cb, backlight_cb, brightness_cb; | 278 | uint64_t cmap_cb, backlight_cb, brightness_cb; | |
279 | int have_backlight = 0; | 279 | int have_backlight = 0; | |
280 | #ifdef PMAC_G5 | |||
281 | int have_palette = 0; | |||
282 | #else | |||
283 | int have_palette = 1; | 280 | int have_palette = 1; | |
284 | #endif | 281 | ||
285 | if (node != console_node) { | 282 | if (node != console_node) { | |
286 | /* | 283 | /* | |
287 | * see if any child matches since OF attaches nodes for | 284 | * see if any child matches since OF attaches nodes for | |
288 | * each head and /chosen/stdout points to the head | 285 | * each head and /chosen/stdout points to the head | |
289 | * rather than the device itself in this case | 286 | * rather than the device itself in this case | |
290 | */ | 287 | */ | |
291 | int sub; | 288 | int sub; | |
292 | 289 | |||
293 | sub = OF_child(node); | 290 | sub = OF_child(node); | |
294 | while ((sub != 0) && (sub != console_node)) { | 291 | while ((sub != 0) && (sub != console_node)) { | |
295 | sub = OF_peer(sub); | 292 | sub = OF_peer(sub); | |
296 | } | 293 | } | |
297 | if (sub != console_node) | 294 | if (sub != console_node) | |
298 | return; | 295 | return; | |
299 | node = sub; | 296 | node = sub; | |
300 | } | 297 | } | |
301 | 298 | |||
302 | prop_dictionary_set_bool(dict, "is_console", 1); | 299 | prop_dictionary_set_bool(dict, "is_console", 1); | |
303 | if (!of_to_uint32_prop(dict, node, "width", "width")) { | 300 | if (!of_to_uint32_prop(dict, node, "width", "width")) { | |
304 | 301 | |||
305 | OF_interpret("screen-width", 0, 1, &temp); | 302 | OF_interpret("screen-width", 0, 1, &temp); | |
306 | prop_dictionary_set_uint32(dict, "width", temp); | 303 | prop_dictionary_set_uint32(dict, "width", temp); | |
307 | } | 304 | } | |
308 | if (!of_to_uint32_prop(dict, node, "height", "height")) { | 305 | if (!of_to_uint32_prop(dict, node, "height", "height")) { | |
309 | 306 | |||
310 | OF_interpret("screen-height", 0, 1, &temp); | 307 | OF_interpret("screen-height", 0, 1, &temp); | |
311 | prop_dictionary_set_uint32(dict, "height", temp); | 308 | prop_dictionary_set_uint32(dict, "height", temp); | |
312 | } | 309 | } | |
313 | of_to_uint32_prop(dict, node, "linebytes", "linebytes"); | 310 | of_to_uint32_prop(dict, node, "linebytes", "linebytes"); | |
314 | if (!of_to_uint32_prop(dict, node, "depth", "depth")) { | 311 | if (!of_to_uint32_prop(dict, node, "depth", "depth")) { | |
315 | /* | 312 | /* | |
316 | * XXX we should check linebytes vs. width but those | 313 | * XXX we should check linebytes vs. width but those | |
317 | * FBs that don't have a depth property ( /chaos/control... ) | 314 | * FBs that don't have a depth property ( /chaos/control... ) | |
318 | * won't have linebytes either | 315 | * won't have linebytes either | |
319 | */ | 316 | */ | |
320 | prop_dictionary_set_uint32(dict, "depth", 8); | 317 | prop_dictionary_set_uint32(dict, "depth", 8); | |
321 | } | 318 | } | |
322 | if (!of_to_uint32_prop(dict, node, "address", "address")) { | 319 | if (!of_to_uint32_prop(dict, node, "address", "address")) { | |
323 | uint32_t fbaddr = 0; | 320 | uint32_t fbaddr = 0; | |
324 | OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); | 321 | OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); | |
325 | if (fbaddr != 0) | 322 | if (fbaddr != 0) | |
326 | prop_dictionary_set_uint32(dict, "address", fbaddr); | 323 | prop_dictionary_set_uint32(dict, "address", fbaddr); | |
327 | } | 324 | } | |
328 | if (of_to_dataprop(dict, node, "EDID", "EDID")) { | 325 | if (of_to_dataprop(dict, node, "EDID", "EDID")) { | |
329 | aprint_debug("found EDID property...\n"); | 326 | aprint_debug("found EDID property...\n"); | |
330 | } else if (of_to_dataprop(dict, node, "EDID,A", "EDID")) { | 327 | } else if (of_to_dataprop(dict, node, "EDID,A", "EDID")) { | |
331 | aprint_debug("found EDID,A\n"); | 328 | aprint_debug("found EDID,A\n"); | |
332 | } else if (of_to_dataprop(dict, node, "EDID,B", "EDID")) { | 329 | } else if (of_to_dataprop(dict, node, "EDID,B", "EDID")) { | |
333 | memset(name, 0, sizeof(name)); | 330 | memset(name, 0, sizeof(name)); | |
334 | OF_getprop(node, "name", name, sizeof(name)); | 331 | OF_getprop(node, "name", name, sizeof(name)); | |
335 | if (strcmp(name, "NVDA,NVMac") == 0) { | 332 | if (strcmp(name, "NVDA,NVMac") == 0) { | |
336 | aprint_debug("found EDID,B on nvidia - assuming digital output\n"); | 333 | aprint_debug("found EDID,B on nvidia - assuming digital output\n"); | |
337 | prop_dictionary_set_bool(dict, "no_palette_control", 1); | 334 | prop_dictionary_set_bool(dict, "no_palette_control", 1); | |
338 | have_palette = 0; | 335 | have_palette = 0; | |
339 | } | 336 | } | |
340 | } | 337 | } | |
341 | add_model_specifics(dict); | 338 | add_model_specifics(dict); | |
342 | 339 | |||
343 | temp = 0; | 340 | temp = 0; | |
344 | if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { | 341 | if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { | |
345 | 342 | |||
346 | OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, | 343 | OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, | |
347 | sizeof(temp)); | 344 | sizeof(temp)); | |
348 | } | 345 | } | |
349 | if (temp != 0) | 346 | if (temp != 0) | |
350 | prop_dictionary_set_uint32(dict, "refclk", temp / 10); | 347 | prop_dictionary_set_uint32(dict, "refclk", temp / 10); | |
351 | 348 | |||
349 | if (have_palette && ofw_quiesce) { | |||
350 | aprint_debug( | |||
351 | "OFW has been quiesced - disabling palette callback\n"); | |||
352 | have_palette = 0; | |||
353 | } | |||
354 | ||||
352 | if (have_palette) { | 355 | if (have_palette) { | |
353 | gfb_cb.gcc_cookie = (void *)console_instance; | 356 | gfb_cb.gcc_cookie = (void *)console_instance; | |
354 | gfb_cb.gcc_set_mapreg = of_set_palette; | 357 | gfb_cb.gcc_set_mapreg = of_set_palette; | |
355 | cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; | 358 | cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; | |
356 | prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); | 359 | prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); | |
357 | } | 360 | } | |
358 | 361 | |||
359 | /* now let's look for backlight control */ | 362 | /* now let's look for backlight control */ | |
360 | have_backlight = 0; | 363 | have_backlight = 0; | |
361 | if (OF_getprop(node, "backlight-control", &temp, sizeof(temp)) == 4) { | 364 | if (OF_getprop(node, "backlight-control", &temp, sizeof(temp)) == 4) { | |
362 | have_backlight = 1; | 365 | have_backlight = 1; | |
363 | } else if (OF_getprop(OF_parent(node), "backlight-control", &temp, | 366 | } else if (OF_getprop(OF_parent(node), "backlight-control", &temp, | |
364 | sizeof(temp)) == 4) { | 367 | sizeof(temp)) == 4) { | |
365 | have_backlight = 1; | 368 | have_backlight = 1; | |
366 | } | 369 | } | |
370 | ||||
371 | if (have_backlight && ofw_quiesce) { | |||
372 | aprint_debug( | |||
373 | "OFW has been quiesced - disabling backlight callbacks\n"); | |||
374 | have_palette = 0; | |||
375 | } | |||
376 | ||||
367 | if (have_backlight) { | 377 | if (have_backlight) { | |
368 | 378 | |||
369 | gpc_backlight.gpc_cookie = (void *)console_instance; | 379 | gpc_backlight.gpc_cookie = (void *)console_instance; | |
370 | gpc_backlight.gpc_set_parameter = of_set_backlight; | 380 | gpc_backlight.gpc_set_parameter = of_set_backlight; | |
371 | gpc_backlight.gpc_get_parameter = of_get_backlight; | 381 | gpc_backlight.gpc_get_parameter = of_get_backlight; | |
372 | gpc_backlight.gpc_upd_parameter = NULL; | 382 | gpc_backlight.gpc_upd_parameter = NULL; | |
373 | backlight_cb = (uint64_t)(uintptr_t)&gpc_backlight; | 383 | backlight_cb = (uint64_t)(uintptr_t)&gpc_backlight; | |
374 | prop_dictionary_set_uint64(dict, "backlight_callback", | 384 | prop_dictionary_set_uint64(dict, "backlight_callback", | |
375 | backlight_cb); | 385 | backlight_cb); | |
376 | 386 | |||
377 | gpc_brightness.gpc_cookie = (void *)console_instance; | 387 | gpc_brightness.gpc_cookie = (void *)console_instance; | |
378 | gpc_brightness.gpc_set_parameter = of_set_brightness; | 388 | gpc_brightness.gpc_set_parameter = of_set_brightness; | |
379 | gpc_brightness.gpc_get_parameter = of_get_brightness; | 389 | gpc_brightness.gpc_get_parameter = of_get_brightness; | |
380 | gpc_brightness.gpc_upd_parameter = of_upd_brightness; | 390 | gpc_brightness.gpc_upd_parameter = of_upd_brightness; | |
381 | brightness_cb = (uint64_t)(uintptr_t)&gpc_brightness; | 391 | brightness_cb = (uint64_t)(uintptr_t)&gpc_brightness; | |
382 | prop_dictionary_set_uint64(dict, "brightness_callback", | 392 | prop_dictionary_set_uint64(dict, "brightness_callback", | |
383 | brightness_cb); | 393 | brightness_cb); | |
384 | } | 394 | } | |
385 | } | 395 | } | |
386 | 396 | |||
387 | static void | 397 | static void | |
388 | add_model_specifics(prop_dictionary_t dict) | 398 | add_model_specifics(prop_dictionary_t dict) | |
389 | { | 399 | { | |
390 | const char *bl_rev_models[] = { | 400 | const char *bl_rev_models[] = { | |
391 | "PowerBook4,3", "PowerBook6,3", "PowerBook6,5", NULL}; | 401 | "PowerBook4,3", "PowerBook6,3", "PowerBook6,5", NULL}; | |
392 | const char *clamshell[] = { | 402 | const char *clamshell[] = { | |
393 | "PowerBook2,1", "PowerBook2,2", NULL}; | 403 | "PowerBook2,1", "PowerBook2,2", NULL}; | |
394 | const char *pismo[] = { | 404 | const char *pismo[] = { | |
395 | "PowerBook3,1", NULL}; | 405 | "PowerBook3,1", NULL}; | |
396 | const char *mini1[] = { | 406 | const char *mini1[] = { | |
397 | "PowerMac10,1", NULL}; | 407 | "PowerMac10,1", NULL}; | |
398 | const char *mini2[] = { | 408 | const char *mini2[] = { | |
399 | "PowerMac10,2", NULL}; | 409 | "PowerMac10,2", NULL}; | |
400 | int node; | 410 | int node; | |
401 | 411 | |||
402 | node = OF_finddevice("/"); | 412 | node = OF_finddevice("/"); | |
403 | 413 | |||
404 | if (of_compatible(node, bl_rev_models) != -1) { | 414 | if (of_compatible(node, bl_rev_models) != -1) { | |
405 | prop_dictionary_set_bool(dict, "backlight_level_reverted", 1); | 415 | prop_dictionary_set_bool(dict, "backlight_level_reverted", 1); | |
406 | } | 416 | } | |
407 | if (of_compatible(node, clamshell) != -1) { | 417 | if (of_compatible(node, clamshell) != -1) { | |
408 | prop_data_t edid; | 418 | prop_data_t edid; | |
409 | 419 | |||
410 | edid = prop_data_create_data(edid_clamshell, sizeof(edid_clamshell)); | 420 | edid = prop_data_create_data(edid_clamshell, sizeof(edid_clamshell)); | |
411 | prop_dictionary_set(dict, "EDID", edid); | 421 | prop_dictionary_set(dict, "EDID", edid); | |
412 | prop_object_release(edid); | 422 | prop_object_release(edid); | |
413 | } | 423 | } | |
414 | if (of_compatible(node, pismo) != -1) { | 424 | if (of_compatible(node, pismo) != -1) { | |
415 | prop_data_t edid; | 425 | prop_data_t edid; | |
416 | 426 | |||
417 | edid = prop_data_create_data(edid_pismo, sizeof(edid_pismo)); | 427 | edid = prop_data_create_data(edid_pismo, sizeof(edid_pismo)); | |
418 | prop_dictionary_set(dict, "EDID", edid); | 428 | prop_dictionary_set(dict, "EDID", edid); | |
419 | prop_object_release(edid); | 429 | prop_object_release(edid); | |
420 | } | 430 | } | |
421 | if (of_compatible(node, mini1) != -1) { | 431 | if (of_compatible(node, mini1) != -1) { | |
422 | prop_dictionary_set_bool(dict, "dvi-internal", 1); | 432 | prop_dictionary_set_bool(dict, "dvi-internal", 1); | |
423 | } | 433 | } | |
424 | if (of_compatible(node, mini2) != -1) { | 434 | if (of_compatible(node, mini2) != -1) { | |
425 | prop_dictionary_set_bool(dict, "dvi-external", 1); | 435 | prop_dictionary_set_bool(dict, "dvi-external", 1); | |
426 | } | 436 | } | |
427 | } | 437 | } | |
428 | 438 | |||
429 | static void | 439 | static void | |
430 | of_set_palette(void *cookie, int index, int r, int g, int b) | 440 | of_set_palette(void *cookie, int index, int r, int g, int b) | |
431 | { | 441 | { | |
432 | int ih = (int)cookie; | 442 | int ih = (int)cookie; | |
433 | 443 | |||
434 | OF_call_method_1("color!", ih, 4, r, g, b, index); | 444 | OF_call_method_1("color!", ih, 4, r, g, b, index); | |
435 | } | 445 | } | |
436 | 446 | |||
437 | static int | 447 | static int | |
438 | of_get_backlight(void *cookie, int *state) | 448 | of_get_backlight(void *cookie, int *state) | |
439 | { | 449 | { | |
440 | if (backlight_state < 0) | 450 | if (backlight_state < 0) | |
441 | return ENODEV; | 451 | return ENODEV; | |
442 | *state = backlight_state; | 452 | *state = backlight_state; | |
443 | return 0; | 453 | return 0; | |
444 | } | 454 | } | |
445 | 455 | |||
446 | static int | 456 | static int | |
447 | of_set_backlight(void *cookie, int state) | 457 | of_set_backlight(void *cookie, int state) | |
448 | { | 458 | { | |
449 | int ih = (int)cookie; | 459 | int ih = (int)cookie; | |
450 | 460 | |||
451 | KASSERT(state >= 0 && state <= 1); | 461 | KASSERT(state >= 0 && state <= 1); | |
452 | 462 | |||
453 | backlight_state = state; | 463 | backlight_state = state; | |
454 | if (state) | 464 | if (state) | |
455 | OF_call_method_1("backlight-on", ih, 0); | 465 | OF_call_method_1("backlight-on", ih, 0); | |
456 | else | 466 | else | |
457 | OF_call_method_1("backlight-off", ih, 0); | 467 | OF_call_method_1("backlight-off", ih, 0); | |
458 | 468 | |||
459 | return 0; /* XXX or use return value of OF_call_method_1? */ | 469 | return 0; /* XXX or use return value of OF_call_method_1? */ | |
460 | } | 470 | } | |
461 | 471 | |||
462 | static int | 472 | static int | |
463 | of_get_brightness(void *cookie, int *level) | 473 | of_get_brightness(void *cookie, int *level) | |
464 | { | 474 | { | |
465 | /* | 475 | /* | |
466 | * We don't know how to read the brightness level from OF alone - we | 476 | * We don't know how to read the brightness level from OF alone - we | |
467 | * should read the value from the PMU. Here, we just return whatever | 477 | * should read the value from the PMU. Here, we just return whatever | |
468 | * we set last (if any). | 478 | * we set last (if any). | |
469 | */ | 479 | */ | |
470 | if (brightness_level < 0) | 480 | if (brightness_level < 0) | |
471 | return ENODEV; | 481 | return ENODEV; | |
472 | *level = brightness_level; | 482 | *level = brightness_level; | |
473 | return 0; | 483 | return 0; | |
474 | } | 484 | } | |
475 | 485 | |||
476 | static int | 486 | static int | |
477 | of_set_brightness(void *cookie, int level) | 487 | of_set_brightness(void *cookie, int level) | |
478 | { | 488 | { | |
479 | int ih = (int)cookie; | 489 | int ih = (int)cookie; | |
480 | 490 | |||
481 | KASSERT(level >= 0 && level <= 255); | 491 | KASSERT(level >= 0 && level <= 255); | |
482 | 492 | |||
483 | brightness_level = level; | 493 | brightness_level = level; | |
484 | OF_call_method_1("set-contrast", ih, 1, brightness_level); | 494 | OF_call_method_1("set-contrast", ih, 1, brightness_level); | |
485 | 495 | |||
486 | return 0; /* XXX or use return value of OF_call_method_1? */ | 496 | return 0; /* XXX or use return value of OF_call_method_1? */ | |
487 | } | 497 | } | |
488 | 498 | |||
489 | static int | 499 | static int | |
490 | of_upd_brightness(void *cookie, int delta) | 500 | of_upd_brightness(void *cookie, int delta) | |
491 | { | 501 | { | |
492 | int ih = (int)cookie; | 502 | int ih = (int)cookie; | |
493 | 503 | |||
494 | if (brightness_level < 0) | 504 | if (brightness_level < 0) | |
495 | return ENODEV; | 505 | return ENODEV; | |
496 | 506 | |||
497 | brightness_level += delta; | 507 | brightness_level += delta; | |
498 | if (brightness_level < 0) brightness_level = 0; | 508 | if (brightness_level < 0) brightness_level = 0; | |
499 | if (brightness_level > 255) brightness_level = 255; | 509 | if (brightness_level > 255) brightness_level = 255; | |
500 | OF_call_method_1("set-contrast", ih, 1, brightness_level); | 510 | OF_call_method_1("set-contrast", ih, 1, brightness_level); | |
501 | 511 | |||
502 | return 0; /* XXX or use return value of OF_call_method_1? */ | 512 | return 0; /* XXX or use return value of OF_call_method_1? */ | |
503 | } | 513 | } |
--- src/sys/arch/ofppc/include/autoconf.h 2019/01/08 07:46:10 1.16
+++ src/sys/arch/ofppc/include/autoconf.h 2020/07/07 02:33:54 1.17
@@ -1,58 +1,59 @@ | @@ -1,58 +1,59 @@ | |||
1 | /* $NetBSD: autoconf.h,v 1.16 2019/01/08 07:46:10 mrg Exp $ */ | 1 | /* $NetBSD: autoconf.h,v 1.17 2020/07/07 02:33:54 rin Exp $ */ | |
2 | 2 | |||
3 | #ifndef _OFPPC_AUTOCONF_H_ | 3 | #ifndef _OFPPC_AUTOCONF_H_ | |
4 | #define _OFPPC_AUTOCONF_H_ | 4 | #define _OFPPC_AUTOCONF_H_ | |
5 | 5 | |||
6 | #include <sys/bus.h> | 6 | #include <sys/bus.h> | |
7 | 7 | |||
8 | #include <prop/proplib.h> | 8 | #include <prop/proplib.h> | |
9 | 9 | |||
10 | struct confargs { | 10 | struct confargs { | |
11 | const char *ca_name; | 11 | const char *ca_name; | |
12 | u_int ca_node; | 12 | u_int ca_node; | |
13 | int ca_nreg; | 13 | int ca_nreg; | |
14 | u_int *ca_reg; | 14 | u_int *ca_reg; | |
15 | int ca_nintr; | 15 | int ca_nintr; | |
16 | int *ca_intr; | 16 | int *ca_intr; | |
17 | 17 | |||
18 | bus_addr_t ca_baseaddr; | 18 | bus_addr_t ca_baseaddr; | |
19 | bus_space_tag_t ca_tag; | 19 | bus_space_tag_t ca_tag; | |
20 | }; | 20 | }; | |
21 | 21 | |||
22 | struct pciio_info { | 22 | struct pciio_info { | |
23 | uint32_t start; | 23 | uint32_t start; | |
24 | uint32_t limit; | 24 | uint32_t limit; | |
25 | }; | 25 | }; | |
26 | 26 | |||
27 | /* to support machines with more than 4 busses, change the below */ | 27 | /* to support machines with more than 4 busses, change the below */ | |
28 | #define MAX_PCI_BUSSES 4 | 28 | #define MAX_PCI_BUSSES 4 | |
29 | struct model_data { | 29 | struct model_data { | |
30 | int ranges_offset; | 30 | int ranges_offset; | |
31 | struct pciio_info pciiodata[MAX_PCI_BUSSES]; | 31 | struct pciio_info pciiodata[MAX_PCI_BUSSES]; | |
32 | }; | 32 | }; | |
33 | 33 | |||
34 | extern int console_node; | 34 | extern int console_node; | |
35 | extern int ofw_quiesce; /* XXX not used at the moment */ | |||
35 | extern char model_name[64]; | 36 | extern char model_name[64]; | |
36 | 37 | |||
37 | #ifdef _KERNEL | 38 | #ifdef _KERNEL | |
38 | void initppc(u_int, u_int, char *); | 39 | void initppc(u_int, u_int, char *); | |
39 | void model_init(void); | 40 | void model_init(void); | |
40 | void strayintr(int); | 41 | void strayintr(int); | |
41 | void dumpsys(void); | 42 | void dumpsys(void); | |
42 | 43 | |||
43 | void inittodr(time_t); | 44 | void inittodr(time_t); | |
44 | void resettodr(void); | 45 | void resettodr(void); | |
45 | void cpu_initclocks(void); | 46 | void cpu_initclocks(void); | |
46 | void decr_intr(struct clockframe *); | 47 | void decr_intr(struct clockframe *); | |
47 | void setstatclockrate(int); | 48 | void setstatclockrate(int); | |
48 | void init_interrupt(void); | 49 | void init_interrupt(void); | |
49 | void init_ofppc_interrupt(void); | 50 | void init_ofppc_interrupt(void); | |
50 | void ofppc_init_comcons(int); | 51 | void ofppc_init_comcons(int); | |
51 | void copy_disp_props(device_t, int, prop_dictionary_t); | 52 | void copy_disp_props(device_t, int, prop_dictionary_t); | |
52 | 53 | |||
53 | void OF_start_cpu(int, u_int, int); | 54 | void OF_start_cpu(int, u_int, int); | |
54 | 55 | |||
55 | int rascons_cnattach(void); | 56 | int rascons_cnattach(void); | |
56 | #endif /* _KERNEL */ | 57 | #endif /* _KERNEL */ | |
57 | 58 | |||
58 | #endif /* _OFPPC_AUTOCONF_H_ */ | 59 | #endif /* _OFPPC_AUTOCONF_H_ */ |
--- src/sys/arch/powerpc/oea/ofw_rascons.c 2020/07/07 02:10:20 1.15
+++ src/sys/arch/powerpc/oea/ofw_rascons.c 2020/07/07 02:33:54 1.16
@@ -1,297 +1,309 @@ | @@ -1,297 +1,309 @@ | |||
1 | /* $NetBSD: ofw_rascons.c,v 1.15 2020/07/07 02:10:20 rin Exp $ */ | 1 | /* $NetBSD: ofw_rascons.c,v 1.16 2020/07/07 02:33:54 rin Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1995, 1996 Carnegie-Mellon University. | 4 | * Copyright (c) 1995, 1996 Carnegie-Mellon University. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Author: Chris G. Demetriou | 7 | * Author: Chris G. Demetriou | |
8 | * | 8 | * | |
9 | * Permission to use, copy, modify and distribute this software and | 9 | * Permission to use, copy, modify and distribute this software and | |
10 | * its documentation is hereby granted, provided that both the copyright | 10 | * its documentation is hereby granted, provided that both the copyright | |
11 | * notice and this permission notice appear in all copies of the | 11 | * notice and this permission notice appear in all copies of the | |
12 | * software, derivative works or modified versions, and any portions | 12 | * software, derivative works or modified versions, and any portions | |
13 | * thereof, and that both notices appear in supporting documentation. | 13 | * thereof, and that both notices appear in supporting documentation. | |
14 | * | 14 | * | |
15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | 15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | |
16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND | 16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND | |
17 | * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | 17 | * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |
18 | * | 18 | * | |
19 | * Carnegie Mellon requests users of this software to return to | 19 | * Carnegie Mellon requests users of this software to return to | |
20 | * | 20 | * | |
21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | 21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | |
22 | * School of Computer Science | 22 | * School of Computer Science | |
23 | * Carnegie Mellon University | 23 | * Carnegie Mellon University | |
24 | * Pittsburgh PA 15213-3890 | 24 | * Pittsburgh PA 15213-3890 | |
25 | * | 25 | * | |
26 | * any improvements or extensions that they make and grant Carnegie the | 26 | * any improvements or extensions that they make and grant Carnegie the | |
27 | * rights to redistribute these changes. | 27 | * rights to redistribute these changes. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __KERNEL_RCSID(0, "$NetBSD: ofw_rascons.c,v 1.15 2020/07/07 02:10:20 rin Exp $"); | 31 | __KERNEL_RCSID(0, "$NetBSD: ofw_rascons.c,v 1.16 2020/07/07 02:33:54 rin Exp $"); | |
32 | 32 | |||
33 | #include "wsdisplay.h" | 33 | #include "wsdisplay.h" | |
34 | 34 | |||
35 | #include <sys/param.h> | 35 | #include <sys/param.h> | |
36 | #include <sys/buf.h> | 36 | #include <sys/buf.h> | |
37 | #include <sys/bus.h> | 37 | #include <sys/bus.h> | |
38 | #include <sys/conf.h> | 38 | #include <sys/conf.h> | |
39 | #include <sys/device.h> | 39 | #include <sys/device.h> | |
40 | #include <sys/ioctl.h> | 40 | #include <sys/ioctl.h> | |
41 | #include <sys/kernel.h> | 41 | #include <sys/kernel.h> | |
42 | #include <sys/systm.h> | 42 | #include <sys/systm.h> | |
43 | 43 | |||
44 | #include <dev/ofw/openfirm.h> | 44 | #include <dev/ofw/openfirm.h> | |
45 | #include <uvm/uvm_extern.h> | 45 | #include <uvm/uvm_extern.h> | |
46 | 46 | |||
47 | #include <machine/autoconf.h> | 47 | #include <machine/autoconf.h> | |
48 | 48 | |||
49 | #include <dev/wscons/wsconsio.h> | 49 | #include <dev/wscons/wsconsio.h> | |
50 | #include <dev/wscons/wsdisplayvar.h> | 50 | #include <dev/wscons/wsdisplayvar.h> | |
51 | #include <dev/rasops/rasops.h> | 51 | #include <dev/rasops/rasops.h> | |
52 | #include <dev/wscons/wsdisplay_vconsvar.h> | 52 | #include <dev/wscons/wsdisplay_vconsvar.h> | |
53 | #include <dev/wsfont/wsfont.h> | 53 | #include <dev/wsfont/wsfont.h> | |
54 | 54 | |||
55 | #include <powerpc/oea/bat.h> | 55 | #include <powerpc/oea/bat.h> | |
56 | #include <powerpc/oea/cpufeat.h> | 56 | #include <powerpc/oea/cpufeat.h> | |
57 | #include <powerpc/oea/ofw_rasconsvar.h> | 57 | #include <powerpc/oea/ofw_rasconsvar.h> | |
58 | 58 | |||
59 | /* we need a wsdisplay to do anything halfway useful */ | 59 | /* we need a wsdisplay to do anything halfway useful */ | |
60 | #if NWSDISPLAY > 0 | 60 | #if NWSDISPLAY > 0 | |
61 | 61 | |||
62 | static int copy_rom_font(void); | 62 | static int copy_rom_font(void); | |
63 | static struct wsdisplay_font openfirm6x11; | 63 | static struct wsdisplay_font openfirm6x11; | |
64 | static vaddr_t fbaddr; | 64 | static vaddr_t fbaddr; | |
65 | static int romfont_loaded = 0; | 65 | static int romfont_loaded = 0; | |
66 | static int needs_finalize = 0; | 66 | static int needs_finalize = 0; | |
67 | 67 | |||
68 | #define FONTBUFSIZE (2048) /* enough for 96 6x11 bitmap characters */ | 68 | #define FONTBUFSIZE (2048) /* enough for 96 6x11 bitmap characters */ | |
69 | static uint8_t fontbuf[FONTBUFSIZE]; | 69 | static uint8_t fontbuf[FONTBUFSIZE]; | |
70 | 70 | |||
71 | struct vcons_screen rascons_console_screen; | 71 | struct vcons_screen rascons_console_screen; | |
72 | 72 | |||
73 | struct wsscreen_descr rascons_stdscreen = { | 73 | struct wsscreen_descr rascons_stdscreen = { | |
74 | "std", | 74 | "std", | |
75 | 0, 0, /* will be filled in -- XXX shouldn't, it's global */ | 75 | 0, 0, /* will be filled in -- XXX shouldn't, it's global */ | |
76 | 0, | 76 | 0, | |
77 | 0, 0, | 77 | 0, 0, | |
78 | WSSCREEN_REVERSE | 78 | WSSCREEN_REVERSE | |
79 | }; | 79 | }; | |
80 | 80 | |||
81 | int | 81 | int | |
82 | rascons_cnattach(void) | 82 | rascons_cnattach(void) | |
83 | { | 83 | { | |
84 | struct rasops_info *ri = &rascons_console_screen.scr_ri; | 84 | struct rasops_info *ri = &rascons_console_screen.scr_ri; | |
85 | long defattr; | 85 | long defattr; | |
86 | int crow = 0; | 86 | int crow = 0; | |
87 | 87 | |||
88 | /* get current cursor position */ | 88 | /* get current cursor position */ | |
89 | OF_interpret("line#", 0, 1, &crow); | 89 | OF_interpret("line#", 0, 1, &crow); | |
90 | if (crow < 0) | 90 | if (crow < 0) | |
91 | crow = 0; | 91 | crow = 0; | |
92 | 92 | |||
93 | /* move (rom monitor) cursor to the lowest line - 1 */ | 93 | /* move (rom monitor) cursor to the lowest line - 1 */ | |
94 | /* XXXX - Why? */ | 94 | /* XXXX - Why? */ | |
95 | #if 0 | 95 | #if 0 | |
96 | OF_interpret("#lines 2 - to line#", 0, 0); | 96 | OF_interpret("#lines 2 - to line#", 0, 0); | |
97 | #endif | 97 | #endif | |
98 | wsfont_init(); | 98 | wsfont_init(); | |
99 | if (copy_rom_font() == 0) { | 99 | if (copy_rom_font() == 0) { | |
100 | #if !defined(OFWOEA_WSCONS_NO_ROM_FONT) | 100 | #if !defined(OFWOEA_WSCONS_NO_ROM_FONT) | |
101 | romfont_loaded = 1; | 101 | romfont_loaded = 1; | |
102 | #endif /* !OFWOEA_WSCONS_NO_ROM_FONT */ | 102 | #endif /* !OFWOEA_WSCONS_NO_ROM_FONT */ | |
103 | } | 103 | } | |
104 | 104 | |||
105 | /* set up rasops */ | 105 | /* set up rasops */ | |
106 | rascons_init_rasops(console_node, ri); | 106 | rascons_init_rasops(console_node, ri); | |
107 | 107 | |||
108 | /* | 108 | /* | |
109 | * no need to clear the screen here when we're mimicing firmware | 109 | * no need to clear the screen here when we're mimicing firmware | |
110 | * output anyway | 110 | * output anyway | |
111 | */ | 111 | */ | |
112 | #if 0 | 112 | #if 0 | |
113 | if (ri->ri_width >= 1024 && ri->ri_height >= 768) { | 113 | if (ri->ri_width >= 1024 && ri->ri_height >= 768) { | |
114 | int i, screenbytes = ri->ri_stride * ri->ri_height; | 114 | int i, screenbytes = ri->ri_stride * ri->ri_height; | |
115 | 115 | |||
116 | for (i = 0; i < screenbytes; i += sizeof(u_int32_t)) | 116 | for (i = 0; i < screenbytes; i += sizeof(u_int32_t)) | |
117 | *(u_int32_t *)(fbaddr + i) = 0xffffffff; | 117 | *(u_int32_t *)(fbaddr + i) = 0xffffffff; | |
118 | crow = 0; | 118 | crow = 0; | |
119 | } | 119 | } | |
120 | #endif | 120 | #endif | |
121 | 121 | |||
122 | rascons_stdscreen.nrows = ri->ri_rows; | 122 | rascons_stdscreen.nrows = ri->ri_rows; | |
123 | rascons_stdscreen.ncols = ri->ri_cols; | 123 | rascons_stdscreen.ncols = ri->ri_cols; | |
124 | rascons_stdscreen.textops = &ri->ri_ops; | 124 | rascons_stdscreen.textops = &ri->ri_ops; | |
125 | rascons_stdscreen.capabilities = ri->ri_caps; | 125 | rascons_stdscreen.capabilities = ri->ri_caps; | |
126 | 126 | |||
127 | /* | 127 | /* | |
128 | * XXX | 128 | * XXX | |
129 | * On some G5 models ( so far, 970FX but not 970MP ) we can't seem to | 129 | * On some G5 models ( so far, 970FX but not 970MP ) we can't seem to | |
130 | * access video memory in real mode, but a lot of code relies on rasops | 130 | * access video memory in real mode, but a lot of code relies on rasops | |
131 | * data structures being set up early so we can't just push the whole | 131 | * data structures being set up early so we can't just push the whole | |
132 | * thing further down. Instead set things up but don't actually attach | 132 | * thing further down. Instead set things up but don't actually attach | |
133 | * the console until later. | 133 | * the console until later. | |
134 | * This needs a better trigger but for now I can't reliably tell which | 134 | * This needs a better trigger but for now I can't reliably tell which | |
135 | * exact models / CPUs / other hardware actually need it. | 135 | * exact models / CPUs / other hardware actually need it. | |
136 | */ | 136 | */ | |
137 | if ((oeacpufeat & OEACPU_64_BRIDGE) != 0) { | 137 | if ((oeacpufeat & OEACPU_64_BRIDGE) != 0) { | |
138 | needs_finalize = 1; | 138 | needs_finalize = 1; | |
139 | } else { | 139 | } else { | |
140 | ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr); | 140 | ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr); | |
141 | wsdisplay_preattach(&rascons_stdscreen, ri, 0, uimax(0, | 141 | wsdisplay_preattach(&rascons_stdscreen, ri, 0, uimax(0, | |
142 | uimin(crow, ri->ri_rows - 1)), defattr); | 142 | uimin(crow, ri->ri_rows - 1)), defattr); | |
143 | } | 143 | } | |
144 | #if notyet | 144 | #if notyet | |
145 | rascons_init_cmap(NULL); | 145 | rascons_init_cmap(NULL); | |
146 | #endif | 146 | #endif | |
147 | 147 | |||
148 | return 0; | 148 | return 0; | |
149 | } | 149 | } | |
150 | 150 | |||
151 | void | 151 | void | |
152 | rascons_add_rom_font(void) | 152 | rascons_add_rom_font(void) | |
153 | { | 153 | { | |
154 | wsfont_init(); | 154 | wsfont_init(); | |
155 | if (romfont_loaded) { | 155 | if (romfont_loaded) { | |
156 | wsfont_add(&openfirm6x11, 0); | 156 | wsfont_add(&openfirm6x11, 0); | |
157 | } | 157 | } | |
158 | } | 158 | } | |
159 | 159 | |||
160 | void | 160 | void | |
161 | rascons_finalize(void) | 161 | rascons_finalize(void) | |
162 | { | 162 | { | |
163 | struct rasops_info *ri = &rascons_console_screen.scr_ri; | 163 | struct rasops_info *ri = &rascons_console_screen.scr_ri; | |
164 | long defattr; | 164 | long defattr; | |
165 | int crow = 0; | 165 | int crow = 0; | |
166 | 166 | |||
167 | if (needs_finalize == 0) return; | 167 | if (needs_finalize == 0) return; | |
168 | 168 | |||
169 | /* get current cursor position */ | 169 | /* get current cursor position */ | |
170 | if (romfont_loaded) { | 170 | if (romfont_loaded) { | |
171 | OF_interpret("line#", 0, 1, &crow); | 171 | OF_interpret("line#", 0, 1, &crow); | |
172 | if (crow < 0) | 172 | if (crow < 0) | |
173 | crow = 0; | 173 | crow = 0; | |
174 | } | 174 | } | |
175 | 175 | |||
176 | ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr); | 176 | ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr); | |
177 | wsdisplay_preattach(&rascons_stdscreen, ri, 0, uimax(0, | 177 | wsdisplay_preattach(&rascons_stdscreen, ri, 0, uimax(0, | |
178 | uimin(crow, ri->ri_rows - 1)), defattr); | 178 | uimin(crow, ri->ri_rows - 1)), defattr); | |
179 | } | 179 | } | |
180 | 180 | |||
181 | static int | 181 | static int | |
182 | copy_rom_font(void) | 182 | copy_rom_font(void) | |
183 | { | 183 | { | |
184 | u_char *romfont; | 184 | u_char *romfont; | |
185 | int char_width, char_height, stride; | 185 | int char_width, char_height, stride; | |
186 | int chosen, mmu, m, e, size; | 186 | int chosen, mmu, m, e, size; | |
187 | 187 | |||
188 | /* | 188 | /* | |
189 | * Get ROM FONT address. | 189 | * Get ROM FONT address. | |
190 | * | 190 | * | |
191 | * For some machines like ``PowerMac11,2'', Open Firmware does not | 191 | * For some machines like ``PowerMac11,2'', Open Firmware does not | |
192 | * initialize console-related variables when auto-boot? is true; | 192 | * initialize console-related variables when auto-boot? is true; | |
193 | * -1 is returned instead of correct value. Fall back to wsfont | 193 | * -1 is returned instead of correct value. Fall back to wsfont | |
194 | * embedded in kernel in this case. | 194 | * embedded in kernel in this case. | |
195 | */ | 195 | */ | |
196 | OF_interpret("font-adr", 0, 1, &romfont); | 196 | OF_interpret("font-adr", 0, 1, &romfont); | |
197 | if (romfont == NULL || romfont == (u_char *)-1) | 197 | if (romfont == NULL || romfont == (u_char *)-1) | |
198 | return -1; | 198 | return -1; | |
199 | 199 | |||
200 | chosen = OF_finddevice("/chosen"); | 200 | chosen = OF_finddevice("/chosen"); | |
201 | OF_getprop(chosen, "mmu", &mmu, 4); | 201 | OF_getprop(chosen, "mmu", &mmu, 4); | |
202 | 202 | |||
203 | /* | 203 | /* | |
204 | * Convert to physcal address. We cannot access to Open Firmware's | 204 | * Convert to physcal address. We cannot access to Open Firmware's | |
205 | * virtual address space. | 205 | * virtual address space. | |
206 | */ | 206 | */ | |
207 | OF_call_method("translate", mmu, 1, 3, romfont, &romfont, &m, &e); | 207 | OF_call_method("translate", mmu, 1, 3, romfont, &romfont, &m, &e); | |
208 | 208 | |||
209 | /* Get character size */ | 209 | /* Get character size */ | |
210 | OF_interpret("char-width", 0, 1, &char_width); | 210 | OF_interpret("char-width", 0, 1, &char_width); | |
211 | OF_interpret("char-height", 0, 1, &char_height); | 211 | OF_interpret("char-height", 0, 1, &char_height); | |
212 | 212 | |||
213 | stride = (char_width + 7) >> 3; | 213 | stride = (char_width + 7) >> 3; | |
214 | size = stride * char_height * 96; | 214 | size = stride * char_height * 96; | |
215 | if (size > FONTBUFSIZE) return -1; | 215 | if (size > FONTBUFSIZE) return -1; | |
216 | 216 | |||
217 | memcpy(fontbuf, romfont, size); | 217 | memcpy(fontbuf, romfont, size); | |
218 | 218 | |||
219 | openfirm6x11.name = "Open Firmware"; | 219 | openfirm6x11.name = "Open Firmware"; | |
220 | openfirm6x11.firstchar = 32; | 220 | openfirm6x11.firstchar = 32; | |
221 | openfirm6x11.numchars = 96; | 221 | openfirm6x11.numchars = 96; | |
222 | openfirm6x11.encoding = WSDISPLAY_FONTENC_ISO; | 222 | openfirm6x11.encoding = WSDISPLAY_FONTENC_ISO; | |
223 | openfirm6x11.fontwidth = char_width; | 223 | openfirm6x11.fontwidth = char_width; | |
224 | openfirm6x11.fontheight = char_height; | 224 | openfirm6x11.fontheight = char_height; | |
225 | openfirm6x11.stride = stride; | 225 | openfirm6x11.stride = stride; | |
226 | openfirm6x11.bitorder = WSDISPLAY_FONTORDER_L2R; | 226 | openfirm6x11.bitorder = WSDISPLAY_FONTORDER_L2R; | |
227 | openfirm6x11.byteorder = WSDISPLAY_FONTORDER_L2R; | 227 | openfirm6x11.byteorder = WSDISPLAY_FONTORDER_L2R; | |
228 | openfirm6x11.data = fontbuf; | 228 | openfirm6x11.data = fontbuf; | |
229 | 229 | |||
230 | return 0; | 230 | return 0; | |
231 | } | 231 | } | |
232 | 232 | |||
233 | int | 233 | int | |
234 | rascons_init_rasops(int node, struct rasops_info *ri) | 234 | rascons_init_rasops(int node, struct rasops_info *ri) | |
235 | { | 235 | { | |
236 | int32_t width, height, linebytes, depth; | 236 | int32_t width, height, linebytes, depth; | |
237 | 237 | |||
238 | /* XXX /chaos/control doesn't have "width", "height", ... */ | 238 | /* XXX /chaos/control doesn't have "width", "height", ... */ | |
239 | width = height = -1; | 239 | width = height = -1; | |
240 | if (OF_getprop(node, "width", &width, 4) != 4) | 240 | if (OF_getprop(node, "width", &width, 4) != 4) | |
241 | OF_interpret("screen-width", 0, 1, &width); | 241 | OF_interpret("screen-width", 0, 1, &width); | |
242 | if (OF_getprop(node, "height", &height, 4) != 4) | 242 | if (OF_getprop(node, "height", &height, 4) != 4) | |
243 | OF_interpret("screen-height", 0, 1, &height); | 243 | OF_interpret("screen-height", 0, 1, &height); | |
244 | if (OF_getprop(node, "linebytes", &linebytes, 4) != 4) | 244 | if (OF_getprop(node, "linebytes", &linebytes, 4) != 4) | |
245 | linebytes = width; /* XXX */ | 245 | linebytes = width; /* XXX */ | |
246 | if (OF_getprop(node, "depth", &depth, 4) != 4) | 246 | if (OF_getprop(node, "depth", &depth, 4) != 4) | |
247 | depth = 8; /* XXX */ | 247 | depth = 8; /* XXX */ | |
248 | if (OF_getprop(node, "address", &fbaddr, 4) != 4) | 248 | if (OF_getprop(node, "address", &fbaddr, 4) != 4) | |
249 | OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); | 249 | OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); | |
250 | 250 | |||
251 | if (width == -1 || height == -1 || fbaddr == 0 || fbaddr == -1) | 251 | if (width == -1 || height == -1 || fbaddr == 0 || fbaddr == -1) | |
252 | return false; | 252 | return false; | |
253 | 253 | |||
254 | /* initialize rasops */ | 254 | /* initialize rasops */ | |
255 | ri->ri_width = width; | 255 | ri->ri_width = width; | |
256 | ri->ri_height = height; | 256 | ri->ri_height = height; | |
257 | ri->ri_depth = depth; | 257 | ri->ri_depth = depth; | |
258 | ri->ri_stride = linebytes; | 258 | ri->ri_stride = linebytes; | |
259 | ri->ri_bits = (char *)fbaddr; | 259 | ri->ri_bits = (char *)fbaddr; | |
260 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_NO_AUTO; | 260 | ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_NO_AUTO; | |
261 | 261 | |||
262 | /* mimic firmware output if we can find the ROM font */ | 262 | /* mimic firmware output if we can find the ROM font */ | |
263 | if (romfont_loaded) { | 263 | if (romfont_loaded) { | |
264 | int cols = 0, rows = 0; | 264 | int cols = 0, rows = 0; | |
265 | 265 | |||
266 | /* | 266 | /* | |
267 | * XXX this assumes we're the console which may or may not | 267 | * XXX this assumes we're the console which may or may not | |
268 | * be the case | 268 | * be the case | |
269 | */ | 269 | */ | |
270 | OF_interpret("#lines", 0, 1, &rows); | 270 | OF_interpret("#lines", 0, 1, &rows); | |
271 | OF_interpret("#columns", 0, 1, &cols); | 271 | OF_interpret("#columns", 0, 1, &cols); | |
272 | ri->ri_font = &openfirm6x11; | 272 | ri->ri_font = &openfirm6x11; | |
273 | ri->ri_wsfcookie = -1; /* not using wsfont */ | 273 | ri->ri_wsfcookie = -1; /* not using wsfont */ | |
274 | rasops_init(ri, rows, cols); | 274 | rasops_init(ri, rows, cols); | |
275 | #ifdef RASCONS_DEBUG | 275 | #ifdef RASCONS_DEBUG | |
276 | char buffer[128]; | 276 | char buffer[128]; | |
277 | snprintf(buffer, 128, "bits %08x c %d w %d -> %d %d\n", | 277 | snprintf(buffer, 128, "bits %08x c %d w %d -> %d %d\n", | |
278 | (uint32_t)ri->ri_bits, cols, width, ri->ri_xorigin, ri->ri_yorigin); | 278 | (uint32_t)ri->ri_bits, cols, width, ri->ri_xorigin, ri->ri_yorigin); | |
279 | OF_write(console_instance, buffer, strlen(buffer)); | 279 | OF_write(console_instance, buffer, strlen(buffer)); | |
280 | #endif | 280 | #endif | |
281 | } else { | 281 | } else { | |
282 | /* use as much of the screen as the font permits */ | 282 | /* use as much of the screen as the font permits */ | |
283 | rasops_init(ri, height/8, width/8); | 283 | rasops_init(ri, height/8, width/8); | |
284 | ri->ri_caps = WSSCREEN_WSCOLORS; | 284 | ri->ri_caps = WSSCREEN_WSCOLORS; | |
285 | rasops_reconfig(ri, height / ri->ri_font->fontheight, | 285 | rasops_reconfig(ri, height / ri->ri_font->fontheight, | |
286 | width / ri->ri_font->fontwidth); | 286 | width / ri->ri_font->fontwidth); | |
287 | } | 287 | } | |
288 | 288 | |||
289 | if (depth == 8 && ofw_quiesce) { | |||
290 | /* | |||
291 | * Open Firmware will be quiesced. This is last chance to | |||
292 | * set color palette via ``color!'' method. | |||
293 | */ | |||
294 | for (int i = 0; i < 256; i++) { | |||
295 | OF_call_method_1("color!", console_instance, 4, | |||
296 | rasops_cmap[3 * i], rasops_cmap[3 * i + 1], | |||
297 | rasops_cmap[3 * i + 2], i); | |||
298 | } | |||
299 | } | |||
300 | ||||
289 | return true; | 301 | return true; | |
290 | } | 302 | } | |
291 | #else /* NWSDISPLAY > 0 */ | 303 | #else /* NWSDISPLAY > 0 */ | |
292 | int | 304 | int | |
293 | rascons_cnattach(void) | 305 | rascons_cnattach(void) | |
294 | { | 306 | { | |
295 | return -1; | 307 | return -1; | |
296 | } | 308 | } | |
297 | #endif | 309 | #endif |
--- src/sys/arch/powerpc/oea/ofwoea_machdep.c 2020/07/06 10:59:37 1.49
+++ src/sys/arch/powerpc/oea/ofwoea_machdep.c 2020/07/07 02:33:54 1.50
@@ -1,860 +1,865 @@ | @@ -1,860 +1,865 @@ | |||
1 | /* $NetBSD: ofwoea_machdep.c,v 1.49 2020/07/06 10:59:37 rin Exp $ */ | 1 | /* $NetBSD: ofwoea_machdep.c,v 1.50 2020/07/07 02:33:54 rin Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2007 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2007 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Tim Rightnour | 8 | * by Tim Rightnour | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | __KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.49 2020/07/06 10:59:37 rin Exp $"); | 33 | __KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.50 2020/07/07 02:33:54 rin Exp $"); | |
34 | 34 | |||
35 | #include "ksyms.h" | 35 | #include "ksyms.h" | |
36 | #include "wsdisplay.h" | 36 | #include "wsdisplay.h" | |
37 | 37 | |||
38 | #ifdef _KERNEL_OPT | 38 | #ifdef _KERNEL_OPT | |
39 | #include "opt_ddb.h" | 39 | #include "opt_ddb.h" | |
40 | #include "opt_kgdb.h" | 40 | #include "opt_kgdb.h" | |
41 | #include "opt_modular.h" | 41 | #include "opt_modular.h" | |
42 | #include "opt_multiprocessor.h" | 42 | #include "opt_multiprocessor.h" | |
43 | #include "opt_oea.h" | 43 | #include "opt_oea.h" | |
44 | #include "opt_ofwoea.h" | 44 | #include "opt_ofwoea.h" | |
45 | #include "opt_ppcarch.h" | 45 | #include "opt_ppcarch.h" | |
46 | #endif | 46 | #endif | |
47 | 47 | |||
48 | #include <sys/param.h> | 48 | #include <sys/param.h> | |
49 | #include <sys/buf.h> | 49 | #include <sys/buf.h> | |
50 | #include <sys/boot_flag.h> | 50 | #include <sys/boot_flag.h> | |
51 | #include <sys/extent.h> | 51 | #include <sys/extent.h> | |
52 | #include <sys/kernel.h> | 52 | #include <sys/kernel.h> | |
53 | #include <sys/ksyms.h> | 53 | #include <sys/ksyms.h> | |
54 | #include <uvm/uvm_extern.h> | 54 | #include <uvm/uvm_extern.h> | |
55 | 55 | |||
56 | #include <dev/ofw/openfirm.h> | 56 | #include <dev/ofw/openfirm.h> | |
57 | #include <dev/wscons/wsconsio.h> | 57 | #include <dev/wscons/wsconsio.h> | |
58 | #include <dev/wscons/wsdisplayvar.h> | 58 | #include <dev/wscons/wsdisplayvar.h> | |
59 | #include <dev/rasops/rasops.h> | 59 | #include <dev/rasops/rasops.h> | |
60 | #include <dev/wscons/wsdisplay_vconsvar.h> | 60 | #include <dev/wscons/wsdisplay_vconsvar.h> | |
61 | #include <machine/pmap.h> | 61 | #include <machine/pmap.h> | |
62 | #include <machine/powerpc.h> | 62 | #include <machine/powerpc.h> | |
63 | #include <machine/trap.h> | 63 | #include <machine/trap.h> | |
64 | #include <machine/vmparam.h> | 64 | #include <machine/vmparam.h> | |
65 | #include <machine/autoconf.h> | 65 | #include <machine/autoconf.h> | |
66 | #include <sys/bus.h> | 66 | #include <sys/bus.h> | |
67 | #include <powerpc/oea/bat.h> | 67 | #include <powerpc/oea/bat.h> | |
68 | #include <powerpc/oea/ofw_rasconsvar.h> | 68 | #include <powerpc/oea/ofw_rasconsvar.h> | |
69 | #include <powerpc/oea/cpufeat.h> | 69 | #include <powerpc/oea/cpufeat.h> | |
70 | #include <powerpc/include/oea/spr.h> | 70 | #include <powerpc/include/oea/spr.h> | |
71 | #include <powerpc/ofw_cons.h> | 71 | #include <powerpc/ofw_cons.h> | |
72 | #include <powerpc/spr.h> | 72 | #include <powerpc/spr.h> | |
73 | #include <powerpc/pic/picvar.h> | 73 | #include <powerpc/pic/picvar.h> | |
74 | 74 | |||
75 | #ifdef DDB | 75 | #ifdef DDB | |
76 | #include <machine/db_machdep.h> | 76 | #include <machine/db_machdep.h> | |
77 | #include <ddb/db_extern.h> | 77 | #include <ddb/db_extern.h> | |
78 | #endif | 78 | #endif | |
79 | 79 | |||
80 | #ifdef KGDB | 80 | #ifdef KGDB | |
81 | #include <sys/kgdb.h> | 81 | #include <sys/kgdb.h> | |
82 | #endif | 82 | #endif | |
83 | 83 | |||
84 | #ifdef ofppc | 84 | #ifdef ofppc | |
85 | extern struct model_data modeldata; | 85 | extern struct model_data modeldata; | |
86 | #endif | 86 | #endif | |
87 | 87 | |||
88 | #ifdef OFWOEA_DEBUG | 88 | #ifdef OFWOEA_DEBUG | |
89 | #define DPRINTF printf | 89 | #define DPRINTF printf | |
90 | #else | 90 | #else | |
91 | #define DPRINTF while (0) printf | 91 | #define DPRINTF while (0) printf | |
92 | #endif | 92 | #endif | |
93 | 93 | |||
94 | typedef struct _rangemap { | 94 | typedef struct _rangemap { | |
95 | u_int32_t addr; | 95 | u_int32_t addr; | |
96 | u_int32_t size; | 96 | u_int32_t size; | |
97 | int type; | 97 | int type; | |
98 | } rangemap_t; | 98 | } rangemap_t; | |
99 | 99 | |||
100 | struct ofw_translations { | 100 | struct ofw_translations { | |
101 | vaddr_t va; | 101 | vaddr_t va; | |
102 | int len; | 102 | int len; | |
103 | #if defined (PMAC_G5) | 103 | #if defined (PMAC_G5) | |
104 | register64_t pa; | 104 | register64_t pa; | |
105 | #else | 105 | #else | |
106 | register_t pa; | 106 | register_t pa; | |
107 | #endif | 107 | #endif | |
108 | int mode; | 108 | int mode; | |
109 | }__attribute__((packed)); | 109 | }__attribute__((packed)); | |
110 | 110 | |||
111 | struct pmap ofw_pmap; | 111 | struct pmap ofw_pmap; | |
112 | struct ofw_translations ofmap[32]; | 112 | struct ofw_translations ofmap[32]; | |
113 | char bootpath[256]; | 113 | char bootpath[256]; | |
114 | char model_name[64]; | 114 | char model_name[64]; | |
115 | #if NKSYMS || defined(DDB) || defined(MODULAR) | 115 | #if NKSYMS || defined(DDB) || defined(MODULAR) | |
116 | void *startsym, *endsym; | 116 | void *startsym, *endsym; | |
117 | #endif | 117 | #endif | |
118 | 118 | |||
119 | #if PPC_OEA601 | 119 | #if PPC_OEA601 | |
120 | #define TIMEBASE_FREQ (1000000000) /* RTC register */ | 120 | #define TIMEBASE_FREQ (1000000000) /* RTC register */ | |
121 | #endif | 121 | #endif | |
122 | 122 | |||
123 | #ifdef TIMEBASE_FREQ | 123 | #ifdef TIMEBASE_FREQ | |
124 | u_int timebase_freq = TIMEBASE_FREQ; | 124 | u_int timebase_freq = TIMEBASE_FREQ; | |
125 | #else | 125 | #else | |
126 | u_int timebase_freq = 0; | 126 | u_int timebase_freq = 0; | |
127 | #endif | 127 | #endif | |
128 | 128 | |||
129 | int ofw_quiesce; | |||
130 | ||||
129 | extern int ofwmsr; | 131 | extern int ofwmsr; | |
130 | extern int chosen; | 132 | extern int chosen; | |
131 | extern uint32_t ticks_per_sec; | 133 | extern uint32_t ticks_per_sec; | |
132 | extern uint32_t ns_per_tick; | 134 | extern uint32_t ns_per_tick; | |
133 | extern uint32_t ticks_per_intr; | 135 | extern uint32_t ticks_per_intr; | |
134 | 136 | |||
135 | static int save_ofmap(struct ofw_translations *, int); | 137 | static int save_ofmap(struct ofw_translations *, int); | |
136 | static void restore_ofmap(struct ofw_translations *, int); | 138 | static void restore_ofmap(struct ofw_translations *, int); | |
137 | static void set_timebase(void); | 139 | static void set_timebase(void); | |
138 | 140 | |||
139 | extern void cpu_spinstart(u_int); | 141 | extern void cpu_spinstart(u_int); | |
140 | extern volatile u_int cpu_spinstart_ack; | 142 | extern volatile u_int cpu_spinstart_ack; | |
141 | 143 | |||
142 | void | 144 | void | |
143 | ofwoea_initppc(u_int startkernel, u_int endkernel, char *args) | 145 | ofwoea_initppc(u_int startkernel, u_int endkernel, char *args) | |
144 | { | 146 | { | |
145 | int ofmaplen, node, l; | 147 | int ofmaplen, node, l; | |
146 | register_t scratch; | 148 | register_t scratch; | |
147 | 149 | |||
148 | #if defined(MULTIPROCESSOR) && defined(ofppc) | 150 | #if defined(MULTIPROCESSOR) && defined(ofppc) | |
149 | char cpupath[32]; | 151 | char cpupath[32]; | |
150 | int i; | 152 | int i; | |
151 | #endif | 153 | #endif | |
152 | 154 | |||
153 | /* initialze bats */ | 155 | /* initialze bats */ | |
154 | if ((oeacpufeat & OEACPU_NOBAT) == 0) | 156 | if ((oeacpufeat & OEACPU_NOBAT) == 0) | |
155 | ofwoea_batinit(); | 157 | ofwoea_batinit(); | |
156 | 158 | |||
157 | #if NKSYMS || defined(DDB) || defined(MODULAR) | 159 | #if NKSYMS || defined(DDB) || defined(MODULAR) | |
158 | /* get info of kernel symbol table from bootloader */ | 160 | /* get info of kernel symbol table from bootloader */ | |
159 | memcpy(&startsym, args + strlen(args) + 1, sizeof(startsym)); | 161 | memcpy(&startsym, args + strlen(args) + 1, sizeof(startsym)); | |
160 | memcpy(&endsym, args + strlen(args) + 1 + sizeof(startsym), | 162 | memcpy(&endsym, args + strlen(args) + 1 + sizeof(startsym), | |
161 | sizeof(endsym)); | 163 | sizeof(endsym)); | |
162 | if (startsym == NULL || endsym == NULL) | 164 | if (startsym == NULL || endsym == NULL) | |
163 | startsym = endsym = NULL; | 165 | startsym = endsym = NULL; | |
164 | #endif | 166 | #endif | |
165 | 167 | |||
166 | /* get model name and perform model-specific actions */ | 168 | /* get model name and perform model-specific actions */ | |
167 | memset(model_name, 0, sizeof(model_name)); | 169 | memset(model_name, 0, sizeof(model_name)); | |
168 | node = OF_finddevice("/"); | 170 | node = OF_finddevice("/"); | |
169 | if (node != -1) { | 171 | if (node != -1) { | |
170 | l = OF_getprop(node, "model", model_name, sizeof(model_name)); | 172 | l = OF_getprop(node, "model", model_name, sizeof(model_name)); | |
171 | if (l == -1) | 173 | if (l == -1) | |
172 | OF_getprop(node, "name", model_name, | 174 | OF_getprop(node, "name", model_name, | |
173 | sizeof(model_name)); | 175 | sizeof(model_name)); | |
174 | model_init(); | 176 | model_init(); | |
175 | } | 177 | } | |
176 | 178 | |||
177 | if (strncmp(model_name, "PowerMac11,2", 12) == 0 || | 179 | if (strncmp(model_name, "PowerMac11,2", 12) == 0 || | |
178 | strncmp(model_name, "PowerMac12,1", 12) == 0) | 180 | strncmp(model_name, "PowerMac12,1", 12) == 0) | |
179 | OF_quiesce(); | 181 | ofw_quiesce = 1; | |
180 | 182 | |||
181 | /* switch CPUs to full speed */ | 183 | /* switch CPUs to full speed */ | |
182 | if (strncmp(model_name, "PowerMac7,", 10) == 0) { | 184 | if (strncmp(model_name, "PowerMac7,", 10) == 0) { | |
183 | int clock_ih = OF_open("/u3/i2c/i2c-hwclock"); | 185 | int clock_ih = OF_open("/u3/i2c/i2c-hwclock"); | |
184 | if (clock_ih != 0) { | 186 | if (clock_ih != 0) { | |
185 | OF_call_method_1("slew-high", clock_ih, 0); | 187 | OF_call_method_1("slew-high", clock_ih, 0); | |
186 | } | 188 | } | |
187 | } | 189 | } | |
188 | 190 | |||
189 | /* Initialize bus_space */ | 191 | /* Initialize bus_space */ | |
190 | ofwoea_bus_space_init(); | 192 | ofwoea_bus_space_init(); | |
191 | 193 | |||
192 | ofwoea_consinit(); | 194 | ofwoea_consinit(); | |
193 | 195 | |||
196 | if (ofw_quiesce) | |||
197 | OF_quiesce(); | |||
198 | ||||
194 | #if defined(MULTIPROCESSOR) && defined(ofppc) | 199 | #if defined(MULTIPROCESSOR) && defined(ofppc) | |
195 | for (i=1; i < CPU_MAXNUM; i++) { | 200 | for (i=1; i < CPU_MAXNUM; i++) { | |
196 | snprintf(cpupath, sizeof(cpupath), "/cpus/@%x", i); | 201 | snprintf(cpupath, sizeof(cpupath), "/cpus/@%x", i); | |
197 | node = OF_finddevice(cpupath); | 202 | node = OF_finddevice(cpupath); | |
198 | if (node <= 0) | 203 | if (node <= 0) | |
199 | continue; | 204 | continue; | |
200 | aprint_verbose("Starting up CPU %d %s\n", i, cpupath); | 205 | aprint_verbose("Starting up CPU %d %s\n", i, cpupath); | |
201 | OF_start_cpu(node, (u_int)cpu_spinstart, i); | 206 | OF_start_cpu(node, (u_int)cpu_spinstart, i); | |
202 | for (l=0; l < 100000000; l++) { | 207 | for (l=0; l < 100000000; l++) { | |
203 | if (cpu_spinstart_ack == i) { | 208 | if (cpu_spinstart_ack == i) { | |
204 | aprint_verbose("CPU %d spun up.\n", i); | 209 | aprint_verbose("CPU %d spun up.\n", i); | |
205 | break; | 210 | break; | |
206 | } | 211 | } | |
207 | __asm volatile ("sync"); | 212 | __asm volatile ("sync"); | |
208 | } | 213 | } | |
209 | } | 214 | } | |
210 | #endif | 215 | #endif | |
211 | 216 | |||
212 | oea_init(pic_ext_intr); | 217 | oea_init(pic_ext_intr); | |
213 | 218 | |||
214 | ofmaplen = save_ofmap(NULL, 0); | 219 | ofmaplen = save_ofmap(NULL, 0); | |
215 | if (ofmaplen > 0) | 220 | if (ofmaplen > 0) | |
216 | save_ofmap(ofmap, ofmaplen); | 221 | save_ofmap(ofmap, ofmaplen); | |
217 | 222 | |||
218 | /* | 223 | /* | |
219 | * XXX | 224 | * XXX | |
220 | * we need to do this here instead of earlier on in ofwinit() for some reason | 225 | * we need to do this here instead of earlier on in ofwinit() for some reason | |
221 | * At least some versions of Apple OF 2.0.1 hang if we do this earlier | 226 | * At least some versions of Apple OF 2.0.1 hang if we do this earlier | |
222 | */ | 227 | */ | |
223 | ofwmsr &= ~PSL_IP; | 228 | ofwmsr &= ~PSL_IP; | |
224 | 229 | |||
225 | /* Parse the args string */ | 230 | /* Parse the args string */ | |
226 | if (args) { | 231 | if (args) { | |
227 | strcpy(bootpath, args); | 232 | strcpy(bootpath, args); | |
228 | args = bootpath; | 233 | args = bootpath; | |
229 | while (*++args && *args != ' '); | 234 | while (*++args && *args != ' '); | |
230 | if (*args) { | 235 | if (*args) { | |
231 | *args++ = 0; | 236 | *args++ = 0; | |
232 | while (*args) | 237 | while (*args) | |
233 | BOOT_FLAG(*args++, boothowto); | 238 | BOOT_FLAG(*args++, boothowto); | |
234 | } | 239 | } | |
235 | } else { | 240 | } else { | |
236 | int chs = OF_finddevice("/chosen"); | 241 | int chs = OF_finddevice("/chosen"); | |
237 | int len; | 242 | int len; | |
238 | 243 | |||
239 | len = OF_getprop(chs, "bootpath", bootpath, sizeof(bootpath) - 1); | 244 | len = OF_getprop(chs, "bootpath", bootpath, sizeof(bootpath) - 1); | |
240 | if (len > -1) | 245 | if (len > -1) | |
241 | bootpath[len] = 0; | 246 | bootpath[len] = 0; | |
242 | } | 247 | } | |
243 | 248 | |||
244 | uvm_md_init(); | 249 | uvm_md_init(); | |
245 | 250 | |||
246 | pmap_bootstrap(startkernel, endkernel); | 251 | pmap_bootstrap(startkernel, endkernel); | |
247 | 252 | |||
248 | /* as far as I can tell, the pmap_setup_seg0 stuff is horribly broken */ | 253 | /* as far as I can tell, the pmap_setup_seg0 stuff is horribly broken */ | |
249 | #if defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE) | 254 | #if defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE) | |
250 | #if defined (PMAC_G5) | 255 | #if defined (PMAC_G5) | |
251 | /* Mapin 1st 256MB segment 1:1, also map in mem needed to access OFW*/ | 256 | /* Mapin 1st 256MB segment 1:1, also map in mem needed to access OFW*/ | |
252 | if (oeacpufeat & OEACPU_64_BRIDGE) { | 257 | if (oeacpufeat & OEACPU_64_BRIDGE) { | |
253 | vaddr_t va; | 258 | vaddr_t va; | |
254 | paddr_t pa; | 259 | paddr_t pa; | |
255 | int i; | 260 | int i; | |
256 | 261 | |||
257 | pmap_setup_segment0_map(0, msgbuf_paddr, msgbuf_paddr, | 262 | pmap_setup_segment0_map(0, msgbuf_paddr, msgbuf_paddr, | |
258 | round_page(MSGBUFSIZE), 0x0); | 263 | round_page(MSGBUFSIZE), 0x0); | |
259 | 264 | |||
260 | /* Map OFW code+data */ | 265 | /* Map OFW code+data */ | |
261 | 266 | |||
262 | for (i = 0; i < ofmaplen / sizeof(struct ofw_translations); i++) { | 267 | for (i = 0; i < ofmaplen / sizeof(struct ofw_translations); i++) { | |
263 | if (ofmap[i].va < 0xff800000) | 268 | if (ofmap[i].va < 0xff800000) | |
264 | continue; | 269 | continue; | |
265 | 270 | |||
266 | for (va = ofmap[i].va, pa = ofmap[i].pa; | 271 | for (va = ofmap[i].va, pa = ofmap[i].pa; | |
267 | va < ofmap[i].va + ofmap[i].len; | 272 | va < ofmap[i].va + ofmap[i].len; | |
268 | va += PAGE_SIZE, pa += PAGE_SIZE) { | 273 | va += PAGE_SIZE, pa += PAGE_SIZE) { | |
269 | pmap_enter(pmap_kernel(), va, pa, VM_PROT_ALL, | 274 | pmap_enter(pmap_kernel(), va, pa, VM_PROT_ALL, | |
270 | VM_PROT_ALL | PMAP_WIRED); | 275 | VM_PROT_ALL | PMAP_WIRED); | |
271 | } | 276 | } | |
272 | } | 277 | } | |
273 | 278 | |||
274 | #if NWSDISPLAY > 0 | 279 | #if NWSDISPLAY > 0 | |
275 | /* Map video frame buffer */ | 280 | /* Map video frame buffer */ | |
276 | 281 | |||
277 | struct rasops_info *ri = &rascons_console_screen.scr_ri; | 282 | struct rasops_info *ri = &rascons_console_screen.scr_ri; | |
278 | 283 | |||
279 | if (ri->ri_bits != NULL) { | 284 | if (ri->ri_bits != NULL) { | |
280 | for (va = (vaddr_t) ri->ri_bits; | 285 | for (va = (vaddr_t) ri->ri_bits; | |
281 | va < round_page((vaddr_t) ri->ri_bits + | 286 | va < round_page((vaddr_t) ri->ri_bits + | |
282 | ri->ri_height * ri->ri_stride); | 287 | ri->ri_height * ri->ri_stride); | |
283 | va += PAGE_SIZE) { | 288 | va += PAGE_SIZE) { | |
284 | pmap_enter(pmap_kernel(), va, va, | 289 | pmap_enter(pmap_kernel(), va, va, | |
285 | VM_PROT_READ | VM_PROT_WRITE, | 290 | VM_PROT_READ | VM_PROT_WRITE, | |
286 | PMAP_NOCACHE | PMAP_WIRED); | 291 | PMAP_NOCACHE | PMAP_WIRED); | |
287 | } | 292 | } | |
288 | } | 293 | } | |
289 | #endif | 294 | #endif | |
290 | } | 295 | } | |
291 | #elif defined (MAMBO) | 296 | #elif defined (MAMBO) | |
292 | /* Mapin 1st 256MB segment 1:1, also map in mem needed to access OFW*/ | 297 | /* Mapin 1st 256MB segment 1:1, also map in mem needed to access OFW*/ | |
293 | if (oeacpufeat & OEACPU_64_BRIDGE) | 298 | if (oeacpufeat & OEACPU_64_BRIDGE) | |
294 | pmap_setup_segment0_map(0, 0xf4000000, 0xf4000000, 0x1000, 0x0); | 299 | pmap_setup_segment0_map(0, 0xf4000000, 0xf4000000, 0x1000, 0x0); | |
295 | #endif /* PMAC_G5 */ | 300 | #endif /* PMAC_G5 */ | |
296 | #endif /* PPC_OEA64 || PPC_OEA64_BRIDGE */ | 301 | #endif /* PPC_OEA64 || PPC_OEA64_BRIDGE */ | |
297 | 302 | |||
298 | /* Now enable translation (and machine checks/recoverable interrupts) */ | 303 | /* Now enable translation (and machine checks/recoverable interrupts) */ | |
299 | __asm __volatile ("sync; mfmsr %0; ori %0,%0,%1; mtmsr %0; isync" | 304 | __asm __volatile ("sync; mfmsr %0; ori %0,%0,%1; mtmsr %0; isync" | |
300 | : "=r"(scratch) | 305 | : "=r"(scratch) | |
301 | : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI)); | 306 | : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI)); | |
302 | 307 | |||
303 | restore_ofmap(ofmap, ofmaplen); | 308 | restore_ofmap(ofmap, ofmaplen); | |
304 | 309 | |||
305 | rascons_finalize(); | 310 | rascons_finalize(); | |
306 | 311 | |||
307 | #if NKSYMS || defined(DDB) || defined(MODULAR) | 312 | #if NKSYMS || defined(DDB) || defined(MODULAR) | |
308 | ksyms_addsyms_elf((int)((uintptr_t)endsym - (uintptr_t)startsym), startsym, endsym); | 313 | ksyms_addsyms_elf((int)((uintptr_t)endsym - (uintptr_t)startsym), startsym, endsym); | |
309 | #endif | 314 | #endif | |
310 | 315 | |||
311 | /* CPU clock stuff */ | 316 | /* CPU clock stuff */ | |
312 | set_timebase(); | 317 | set_timebase(); | |
313 | 318 | |||
314 | #ifdef DDB | 319 | #ifdef DDB | |
315 | if (boothowto & RB_KDB) | 320 | if (boothowto & RB_KDB) | |
316 | Debugger(); | 321 | Debugger(); | |
317 | #endif | 322 | #endif | |
318 | } | 323 | } | |
319 | 324 | |||
320 | void | 325 | void | |
321 | set_timebase(void) | 326 | set_timebase(void) | |
322 | { | 327 | { | |
323 | int qhandle, phandle, msr, scratch, node; | 328 | int qhandle, phandle, msr, scratch, node; | |
324 | char type[32]; | 329 | char type[32]; | |
325 | 330 | |||
326 | if (timebase_freq != 0) { | 331 | if (timebase_freq != 0) { | |
327 | ticks_per_sec = timebase_freq; | 332 | ticks_per_sec = timebase_freq; | |
328 | goto found; | 333 | goto found; | |
329 | } | 334 | } | |
330 | 335 | |||
331 | node = OF_finddevice("/cpus/@0"); | 336 | node = OF_finddevice("/cpus/@0"); | |
332 | if (node != -1 && | 337 | if (node != -1 && | |
333 | OF_getprop(node, "timebase-frequency", &ticks_per_sec, | 338 | OF_getprop(node, "timebase-frequency", &ticks_per_sec, | |
334 | sizeof ticks_per_sec) > 0) { | 339 | sizeof ticks_per_sec) > 0) { | |
335 | goto found; | 340 | goto found; | |
336 | } | 341 | } | |
337 | 342 | |||
338 | node = OF_finddevice("/"); | 343 | node = OF_finddevice("/"); | |
339 | for (qhandle = node; qhandle; qhandle = phandle) { | 344 | for (qhandle = node; qhandle; qhandle = phandle) { | |
340 | if (OF_getprop(qhandle, "device_type", type, sizeof type) > 0 | 345 | if (OF_getprop(qhandle, "device_type", type, sizeof type) > 0 | |
341 | && strcmp(type, "cpu") == 0 | 346 | && strcmp(type, "cpu") == 0 | |
342 | && OF_getprop(qhandle, "timebase-frequency", | 347 | && OF_getprop(qhandle, "timebase-frequency", | |
343 | &ticks_per_sec, sizeof ticks_per_sec) > 0) { | 348 | &ticks_per_sec, sizeof ticks_per_sec) > 0) { | |
344 | goto found; | 349 | goto found; | |
345 | } | 350 | } | |
346 | if ((phandle = OF_child(qhandle))) | 351 | if ((phandle = OF_child(qhandle))) | |
347 | continue; | 352 | continue; | |
348 | while (qhandle) { | 353 | while (qhandle) { | |
349 | if ((phandle = OF_peer(qhandle))) | 354 | if ((phandle = OF_peer(qhandle))) | |
350 | break; | 355 | break; | |
351 | qhandle = OF_parent(qhandle); | 356 | qhandle = OF_parent(qhandle); | |
352 | } | 357 | } | |
353 | } | 358 | } | |
354 | panic("no cpu node"); | 359 | panic("no cpu node"); | |
355 | 360 | |||
356 | found: | 361 | found: | |
357 | __asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1" | 362 | __asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1" | |
358 | : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE)); | 363 | : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE)); | |
359 | ns_per_tick = 1000000000 / ticks_per_sec; | 364 | ns_per_tick = 1000000000 / ticks_per_sec; | |
360 | ticks_per_intr = ticks_per_sec / hz; | 365 | ticks_per_intr = ticks_per_sec / hz; | |
361 | cpu_timebase = ticks_per_sec; | 366 | cpu_timebase = ticks_per_sec; | |
362 | 367 | |||
363 | #ifdef PPC_OEA601 | 368 | #ifdef PPC_OEA601 | |
364 | if ((mfpvr() >> 16) == MPC601) | 369 | if ((mfpvr() >> 16) == MPC601) | |
365 | curcpu()->ci_lasttb = rtc_nanosecs(); | 370 | curcpu()->ci_lasttb = rtc_nanosecs(); | |
366 | else | 371 | else | |
367 | #endif | 372 | #endif | |
368 | curcpu()->ci_lasttb = mftbl(); | 373 | curcpu()->ci_lasttb = mftbl(); | |
369 | 374 | |||
370 | mtspr(SPR_DEC, ticks_per_intr); | 375 | mtspr(SPR_DEC, ticks_per_intr); | |
371 | mtmsr(msr); | 376 | mtmsr(msr); | |
372 | } | 377 | } | |
373 | 378 | |||
374 | static int | 379 | static int | |
375 | save_ofmap(struct ofw_translations *map, int maxlen) | 380 | save_ofmap(struct ofw_translations *map, int maxlen) | |
376 | { | 381 | { | |
377 | int mmui, mmu, len; | 382 | int mmui, mmu, len; | |
378 | 383 | |||
379 | OF_getprop(chosen, "mmu", &mmui, sizeof mmui); | 384 | OF_getprop(chosen, "mmu", &mmui, sizeof mmui); | |
380 | mmu = OF_instance_to_package(mmui); | 385 | mmu = OF_instance_to_package(mmui); | |
381 | 386 | |||
382 | if (map) { | 387 | if (map) { | |
383 | memset(map, 0, maxlen); /* to be safe */ | 388 | memset(map, 0, maxlen); /* to be safe */ | |
384 | len = OF_getprop(mmu, "translations", map, maxlen); | 389 | len = OF_getprop(mmu, "translations", map, maxlen); | |
385 | } else | 390 | } else | |
386 | len = OF_getproplen(mmu, "translations"); | 391 | len = OF_getproplen(mmu, "translations"); | |
387 | 392 | |||
388 | if (len < 0) | 393 | if (len < 0) | |
389 | len = 0; | 394 | len = 0; | |
390 | return len; | 395 | return len; | |
391 | } | 396 | } | |
392 | 397 | |||
393 | 398 | |||
394 | /* The PMAC_G5 code here needs to be replaced by code that looks for the | 399 | /* The PMAC_G5 code here needs to be replaced by code that looks for the | |
395 | size_cells and does the right thing automatically. | 400 | size_cells and does the right thing automatically. | |
396 | */ | 401 | */ | |
397 | void | 402 | void | |
398 | restore_ofmap(struct ofw_translations *map, int len) | 403 | restore_ofmap(struct ofw_translations *map, int len) | |
399 | { | 404 | { | |
400 | int n = len / sizeof(struct ofw_translations); | 405 | int n = len / sizeof(struct ofw_translations); | |
401 | int i; | 406 | int i; | |
402 | 407 | |||
403 | pmap_pinit(&ofw_pmap); | 408 | pmap_pinit(&ofw_pmap); | |
404 | 409 | |||
405 | #ifndef _LP64 | 410 | #ifndef _LP64 | |
406 | ofw_pmap.pm_sr[0] = KERNELN_SEGMENT(0)|SR_PRKEY; | 411 | ofw_pmap.pm_sr[0] = KERNELN_SEGMENT(0)|SR_PRKEY; | |
407 | ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY; | 412 | ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY; | |
408 | 413 | |||
409 | #ifdef KERNEL2_SR | 414 | #ifdef KERNEL2_SR | |
410 | ofw_pmap.pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT|SR_SUKEY|SR_PRKEY; | 415 | ofw_pmap.pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT|SR_SUKEY|SR_PRKEY; | |
411 | #endif | 416 | #endif | |
412 | #endif | 417 | #endif | |
413 | 418 | |||
414 | for (i = 0; i < n; i++) { | 419 | for (i = 0; i < n; i++) { | |
415 | #if defined (PMAC_G5) | 420 | #if defined (PMAC_G5) | |
416 | register64_t pa = map[i].pa; | 421 | register64_t pa = map[i].pa; | |
417 | #else | 422 | #else | |
418 | register_t pa = map[i].pa; | 423 | register_t pa = map[i].pa; | |
419 | #endif | 424 | #endif | |
420 | vaddr_t va = map[i].va; | 425 | vaddr_t va = map[i].va; | |
421 | size_t length = map[i].len; | 426 | size_t length = map[i].len; | |
422 | 427 | |||
423 | if (va < 0xf0000000) /* XXX */ | 428 | if (va < 0xf0000000) /* XXX */ | |
424 | continue; | 429 | continue; | |
425 | 430 | |||
426 | while (length > 0) { | 431 | while (length > 0) { | |
427 | pmap_enter(&ofw_pmap, va, (paddr_t)pa, VM_PROT_ALL, | 432 | pmap_enter(&ofw_pmap, va, (paddr_t)pa, VM_PROT_ALL, | |
428 | VM_PROT_ALL|PMAP_WIRED); | 433 | VM_PROT_ALL|PMAP_WIRED); | |
429 | pa += PAGE_SIZE; | 434 | pa += PAGE_SIZE; | |
430 | va += PAGE_SIZE; | 435 | va += PAGE_SIZE; | |
431 | length -= PAGE_SIZE; | 436 | length -= PAGE_SIZE; | |
432 | } | 437 | } | |
433 | } | 438 | } | |
434 | pmap_update(&ofw_pmap); | 439 | pmap_update(&ofw_pmap); | |
435 | } | 440 | } | |
436 | 441 | |||
437 | 442 | |||
438 | 443 | |||
439 | /* | 444 | /* | |
440 | * Scan the device tree for ranges, and return them as bitmap 0..15 | 445 | * Scan the device tree for ranges, and return them as bitmap 0..15 | |
441 | */ | 446 | */ | |
442 | #if !defined(macppc) && defined(PPC_OEA) | 447 | #if !defined(macppc) && defined(PPC_OEA) | |
443 | static u_int16_t | 448 | static u_int16_t | |
444 | ranges_bitmap(int node, u_int16_t bitmap) | 449 | ranges_bitmap(int node, u_int16_t bitmap) | |
445 | { | 450 | { | |
446 | int child, mlen, acells, scells, reclen, i, j; | 451 | int child, mlen, acells, scells, reclen, i, j; | |
447 | u_int32_t addr, len, map[160]; | 452 | u_int32_t addr, len, map[160]; | |
448 | 453 | |||
449 | for (child = OF_child(node); child; child = OF_peer(child)) { | 454 | for (child = OF_child(node); child; child = OF_peer(child)) { | |
450 | mlen = OF_getprop(child, "ranges", map, sizeof(map)); | 455 | mlen = OF_getprop(child, "ranges", map, sizeof(map)); | |
451 | if (mlen == -1) | 456 | if (mlen == -1) | |
452 | goto noranges; | 457 | goto noranges; | |
453 | 458 | |||
454 | j = OF_getprop(child, "#address-cells", &acells, | 459 | j = OF_getprop(child, "#address-cells", &acells, | |
455 | sizeof(acells)); | 460 | sizeof(acells)); | |
456 | if (j == -1) | 461 | if (j == -1) | |
457 | goto noranges; | 462 | goto noranges; | |
458 | 463 | |||
459 | j = OF_getprop(child, "#size-cells", &scells, | 464 | j = OF_getprop(child, "#size-cells", &scells, | |
460 | sizeof(scells)); | 465 | sizeof(scells)); | |
461 | if (j == -1) | 466 | if (j == -1) | |
462 | goto noranges; | 467 | goto noranges; | |
463 | 468 | |||
464 | #ifdef ofppc | 469 | #ifdef ofppc | |
465 | reclen = acells + modeldata.ranges_offset + scells; | 470 | reclen = acells + modeldata.ranges_offset + scells; | |
466 | #else | 471 | #else | |
467 | reclen = acells + 1 + scells; | 472 | reclen = acells + 1 + scells; | |
468 | #endif | 473 | #endif | |
469 | 474 | |||
470 | for (i=0; i < (mlen/4)/reclen; i++) { | 475 | for (i=0; i < (mlen/4)/reclen; i++) { | |
471 | addr = map[reclen * i + acells]; | 476 | addr = map[reclen * i + acells]; | |
472 | len = map[reclen * i + reclen - 1]; | 477 | len = map[reclen * i + reclen - 1]; | |
473 | for (j = 0; j < len / 0x10000000; j++) | 478 | for (j = 0; j < len / 0x10000000; j++) | |
474 | bitmap |= 1 << ((addr+j*0x10000000) >>28); | 479 | bitmap |= 1 << ((addr+j*0x10000000) >>28); | |
475 | bitmap |= 1 << (addr >> 28); | 480 | bitmap |= 1 << (addr >> 28); | |
476 | } | 481 | } | |
477 | noranges: | 482 | noranges: | |
478 | bitmap |= ranges_bitmap(child, bitmap); | 483 | bitmap |= ranges_bitmap(child, bitmap); | |
479 | continue; | 484 | continue; | |
480 | } | 485 | } | |
481 | return bitmap; | 486 | return bitmap; | |
482 | } | 487 | } | |
483 | #endif /* !macppc && PPC_OEA */ | 488 | #endif /* !macppc && PPC_OEA */ | |
484 | 489 | |||
485 | void | 490 | void | |
486 | ofwoea_batinit(void) | 491 | ofwoea_batinit(void) | |
487 | { | 492 | { | |
488 | #if defined (PPC_OEA) | 493 | #if defined (PPC_OEA) | |
489 | 494 | |||
490 | #ifdef macppc | 495 | #ifdef macppc | |
491 | /* | 496 | /* | |
492 | * cover PCI and register space but not the firmware ROM | 497 | * cover PCI and register space but not the firmware ROM | |
493 | */ | 498 | */ | |
494 | #ifdef PPC_OEA601 | 499 | #ifdef PPC_OEA601 | |
495 | 500 | |||
496 | /* | 501 | /* | |
497 | * use segment registers for the 601 | 502 | * use segment registers for the 601 | |
498 | */ | 503 | */ | |
499 | if ((mfpvr() >> 16 ) == MPC601) | 504 | if ((mfpvr() >> 16 ) == MPC601) | |
500 | oea_batinit( | 505 | oea_batinit( | |
501 | 0x80000000, BAT_BL_256M, | 506 | 0x80000000, BAT_BL_256M, | |
502 | 0x90000000, BAT_BL_256M, | 507 | 0x90000000, BAT_BL_256M, | |
503 | 0xa0000000, BAT_BL_256M, | 508 | 0xa0000000, BAT_BL_256M, | |
504 | 0xb0000000, BAT_BL_256M, | 509 | 0xb0000000, BAT_BL_256M, | |
505 | 0xf0000000, BAT_BL_256M, | 510 | 0xf0000000, BAT_BL_256M, | |
506 | 0); | 511 | 0); | |
507 | else | 512 | else | |
508 | #endif | 513 | #endif | |
509 | /* | 514 | /* | |
510 | * map to bats | 515 | * map to bats | |
511 | */ | 516 | */ | |
512 | oea_batinit(0x80000000, BAT_BL_1G, | 517 | oea_batinit(0x80000000, BAT_BL_1G, | |
513 | 0xf0000000, BAT_BL_128M, | 518 | 0xf0000000, BAT_BL_128M, | |
514 | 0xf8000000, BAT_BL_64M, | 519 | 0xf8000000, BAT_BL_64M, | |
515 | 0xfe000000, BAT_BL_8M, /* Grackle IO */ | 520 | 0xfe000000, BAT_BL_8M, /* Grackle IO */ | |
516 | 0); | 521 | 0); | |
517 | #else | 522 | #else | |
518 | uint16_t bitmap; | 523 | uint16_t bitmap; | |
519 | int node, i; | 524 | int node, i; | |
520 | 525 | |||
521 | node = OF_finddevice("/"); | 526 | node = OF_finddevice("/"); | |
522 | 527 | |||
523 | bitmap = ranges_bitmap(node, 0); | 528 | bitmap = ranges_bitmap(node, 0); | |
524 | oea_batinit(0); | 529 | oea_batinit(0); | |
525 | 530 | |||
526 | for (i=1; i < 0x10; i++) { | 531 | for (i=1; i < 0x10; i++) { | |
527 | /* skip the three vital SR regions */ | 532 | /* skip the three vital SR regions */ | |
528 | if (i == USER_SR || i == KERNEL_SR || i == KERNEL2_SR) | 533 | if (i == USER_SR || i == KERNEL_SR || i == KERNEL2_SR) | |
529 | continue; | 534 | continue; | |
530 | if (bitmap & (1 << i)) { | 535 | if (bitmap & (1 << i)) { | |
531 | oea_iobat_add(0x10000000 * i, BAT_BL_256M); | 536 | oea_iobat_add(0x10000000 * i, BAT_BL_256M); | |
532 | DPRINTF("Batmapped 256M at 0x%x\n", 0x10000000 * i); | 537 | DPRINTF("Batmapped 256M at 0x%x\n", 0x10000000 * i); | |
533 | } | 538 | } | |
534 | } | 539 | } | |
535 | #endif | 540 | #endif | |
536 | #endif /* OEA */ | 541 | #endif /* OEA */ | |
537 | } | 542 | } | |
538 | 543 | |||
539 | 544 | |||
540 | /* we define these partially, as we will fill the rest in later */ | 545 | /* we define these partially, as we will fill the rest in later */ | |
541 | struct powerpc_bus_space genppc_isa_io_space_tag = { | 546 | struct powerpc_bus_space genppc_isa_io_space_tag = { | |
542 | .pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE, | 547 | .pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE, | |
543 | .pbs_base = 0x00000000, | 548 | .pbs_base = 0x00000000, | |
544 | }; | 549 | }; | |
545 | 550 | |||
546 | struct powerpc_bus_space genppc_isa_mem_space_tag = { | 551 | struct powerpc_bus_space genppc_isa_mem_space_tag = { | |
547 | .pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, | 552 | .pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE, | |
548 | .pbs_base = 0x00000000, | 553 | .pbs_base = 0x00000000, | |
549 | }; | 554 | }; | |
550 | 555 | |||
551 | /* This gives us a maximum of 6 PCI busses, assuming both io/mem on each. | 556 | /* This gives us a maximum of 6 PCI busses, assuming both io/mem on each. | |
552 | * Increase if necc. | 557 | * Increase if necc. | |
553 | */ | 558 | */ | |
554 | static char ex_storage[EXSTORAGE_MAX][EXTENT_FIXED_STORAGE_SIZE(EXTMAP_RANGES)] | 559 | static char ex_storage[EXSTORAGE_MAX][EXTENT_FIXED_STORAGE_SIZE(EXTMAP_RANGES)] | |
555 | __attribute__((aligned(8))); | 560 | __attribute__((aligned(8))); | |
556 | 561 | |||
557 | 562 | |||
558 | static void | 563 | static void | |
559 | find_ranges(int base, rangemap_t *regions, int *cur, int type) | 564 | find_ranges(int base, rangemap_t *regions, int *cur, int type) | |
560 | { | 565 | { | |
561 | int node, i, len, reclen; | 566 | int node, i, len, reclen; | |
562 | u_int32_t parent_acells, acells, scells, map[160]; | 567 | u_int32_t parent_acells, acells, scells, map[160]; | |
563 | char tmp[32]; | 568 | char tmp[32]; | |
564 | 569 | |||
565 | node = base; | 570 | node = base; | |
566 | if (OF_getprop(node, "device_type", tmp, sizeof(tmp)) == -1) | 571 | if (OF_getprop(node, "device_type", tmp, sizeof(tmp)) == -1) | |
567 | goto rec; | 572 | goto rec; | |
568 | if ((type == RANGE_TYPE_PCI || type == RANGE_TYPE_FIRSTPCI) && | 573 | if ((type == RANGE_TYPE_PCI || type == RANGE_TYPE_FIRSTPCI) && | |
569 | strcmp("pci", tmp) != 0) | 574 | strcmp("pci", tmp) != 0) | |
570 | goto rec; | 575 | goto rec; | |
571 | if (type == RANGE_TYPE_ISA && strcmp("isa", tmp) != 0) | 576 | if (type == RANGE_TYPE_ISA && strcmp("isa", tmp) != 0) | |
572 | goto rec; | 577 | goto rec; | |
573 | if (type == RANGE_TYPE_MACIO && strcmp("memory-controller", tmp) == 0) { | 578 | if (type == RANGE_TYPE_MACIO && strcmp("memory-controller", tmp) == 0) { | |
574 | len = OF_getprop(node, "reg", map, sizeof(map)); | 579 | len = OF_getprop(node, "reg", map, sizeof(map)); | |
575 | acells = 1; | 580 | acells = 1; | |
576 | scells = 1; | 581 | scells = 1; | |
577 | } else { | 582 | } else { | |
578 | len = OF_getprop(node, "ranges", map, sizeof(map)); | 583 | len = OF_getprop(node, "ranges", map, sizeof(map)); | |
579 | } | 584 | } | |
580 | if (len == -1) | 585 | if (len == -1) | |
581 | goto rec; | 586 | goto rec; | |
582 | if (OF_getprop(OF_parent(node), "#address-cells", &parent_acells, | 587 | if (OF_getprop(OF_parent(node), "#address-cells", &parent_acells, | |
583 | sizeof(parent_acells)) != sizeof(parent_acells)) | 588 | sizeof(parent_acells)) != sizeof(parent_acells)) | |
584 | parent_acells = 1; | 589 | parent_acells = 1; | |
585 | if (OF_getprop(node, "#address-cells", &acells, | 590 | if (OF_getprop(node, "#address-cells", &acells, | |
586 | sizeof(acells)) != sizeof(acells)) | 591 | sizeof(acells)) != sizeof(acells)) | |
587 | acells = 3; | 592 | acells = 3; | |
588 | if (OF_getprop(node, "#size-cells", &scells, | 593 | if (OF_getprop(node, "#size-cells", &scells, | |
589 | sizeof(scells)) != sizeof(scells)) | 594 | sizeof(scells)) != sizeof(scells)) | |
590 | scells = 2; | 595 | scells = 2; | |
591 | #ifdef ofppc | 596 | #ifdef ofppc | |
592 | if (modeldata.ranges_offset == 0) | 597 | if (modeldata.ranges_offset == 0) | |
593 | scells -= 1; | 598 | scells -= 1; | |
594 | #endif | 599 | #endif | |
595 | if (type == RANGE_TYPE_ISA) | 600 | if (type == RANGE_TYPE_ISA) | |
596 | reclen = 6; | 601 | reclen = 6; | |
597 | else | 602 | else | |
598 | reclen = parent_acells + acells + scells; | 603 | reclen = parent_acells + acells + scells; | |
599 | /* | 604 | /* | |
600 | * There exist ISA buses with empty ranges properties. This is | 605 | * There exist ISA buses with empty ranges properties. This is | |
601 | * known to occur on the Pegasos II machine, and likely others. | 606 | * known to occur on the Pegasos II machine, and likely others. | |
602 | * According to them, that means that the isa bus is a fake bus, and | 607 | * According to them, that means that the isa bus is a fake bus, and | |
603 | * the real maps are the PCI maps of the preceeding bus. To deal | 608 | * the real maps are the PCI maps of the preceeding bus. To deal | |
604 | * with this, we will set cur to -1 and return. | 609 | * with this, we will set cur to -1 and return. | |
605 | */ | 610 | */ | |
606 | if (type == RANGE_TYPE_ISA && strcmp("isa", tmp) == 0 && len == 0) { | 611 | if (type == RANGE_TYPE_ISA && strcmp("isa", tmp) == 0 && len == 0) { | |
607 | *cur = -1; | 612 | *cur = -1; | |
608 | DPRINTF("Found empty range in isa bus\n"); | 613 | DPRINTF("Found empty range in isa bus\n"); | |
609 | return; | 614 | return; | |
610 | } | 615 | } | |
611 | 616 | |||
612 | DPRINTF("found a map reclen=%d cur=%d len=%d\n", reclen, *cur, len); | 617 | DPRINTF("found a map reclen=%d cur=%d len=%d\n", reclen, *cur, len); | |
613 | switch (type) { | 618 | switch (type) { | |
614 | case RANGE_TYPE_PCI: | 619 | case RANGE_TYPE_PCI: | |
615 | case RANGE_TYPE_FIRSTPCI: | 620 | case RANGE_TYPE_FIRSTPCI: | |
616 | for (i=0; i < len/(4*reclen); i++) { | 621 | for (i=0; i < len/(4*reclen); i++) { | |
617 | DPRINTF("FOUND PCI RANGE\n"); | 622 | DPRINTF("FOUND PCI RANGE\n"); | |
618 | regions[*cur].size = | 623 | regions[*cur].size = | |
619 | map[i*reclen + parent_acells + acells + scells - 1]; | 624 | map[i*reclen + parent_acells + acells + scells - 1]; | |
620 | /* skip ranges of size==0 */ | 625 | /* skip ranges of size==0 */ | |
621 | if (regions[*cur].size == 0) | 626 | if (regions[*cur].size == 0) | |
622 | continue; | 627 | continue; | |
623 | regions[*cur].type = (map[i*reclen] >> 24) & 0x3; | 628 | regions[*cur].type = (map[i*reclen] >> 24) & 0x3; | |
624 | regions[*cur].addr = map[i*reclen + parent_acells + acells - 1]; | 629 | regions[*cur].addr = map[i*reclen + parent_acells + acells - 1]; | |
625 | (*cur)++; | 630 | (*cur)++; | |
626 | } | 631 | } | |
627 | break; | 632 | break; | |
628 | case RANGE_TYPE_ISA: | 633 | case RANGE_TYPE_ISA: | |
629 | for (i=0; i < len/(4*reclen); i++) { | 634 | for (i=0; i < len/(4*reclen); i++) { | |
630 | if (map[i*reclen] == 1) | 635 | if (map[i*reclen] == 1) | |
631 | regions[*cur].type = RANGE_IO; | 636 | regions[*cur].type = RANGE_IO; | |
632 | else | 637 | else | |
633 | regions[*cur].type = RANGE_MEM; | 638 | regions[*cur].type = RANGE_MEM; | |
634 | DPRINTF("FOUND ISA RANGE TYPE=%d\n", | 639 | DPRINTF("FOUND ISA RANGE TYPE=%d\n", | |
635 | regions[*cur].type); | 640 | regions[*cur].type); | |
636 | regions[*cur].size = | 641 | regions[*cur].size = | |
637 | map[i*reclen + acells + scells]; | 642 | map[i*reclen + acells + scells]; | |
638 | (*cur)++; | 643 | (*cur)++; | |
639 | } | 644 | } | |
640 | break; | 645 | break; | |
641 | case RANGE_TYPE_MACIO: | 646 | case RANGE_TYPE_MACIO: | |
642 | regions[*cur].type = RANGE_MEM; | 647 | regions[*cur].type = RANGE_MEM; | |
643 | if (len == 8) { | 648 | if (len == 8) { | |
644 | regions[*cur].size = map[1]; | 649 | regions[*cur].size = map[1]; | |
645 | regions[*cur].addr = map[0]; | 650 | regions[*cur].addr = map[0]; | |
646 | } else { | 651 | } else { | |
647 | regions[*cur].size = map[2]; | 652 | regions[*cur].size = map[2]; | |
648 | regions[*cur].addr = map[1]; | 653 | regions[*cur].addr = map[1]; | |
649 | } | 654 | } | |
650 | (*cur)++; | 655 | (*cur)++; | |
651 | break; | 656 | break; | |
652 | } | 657 | } | |
653 | DPRINTF("returning with CUR=%d\n", *cur); | 658 | DPRINTF("returning with CUR=%d\n", *cur); | |
654 | return; | 659 | return; | |
655 | rec: | 660 | rec: | |
656 | for (node = OF_child(base); node; node = OF_peer(node)) { | 661 | for (node = OF_child(base); node; node = OF_peer(node)) { | |
657 | DPRINTF("RECURSE 1 STEP\n"); | 662 | DPRINTF("RECURSE 1 STEP\n"); | |
658 | find_ranges(node, regions, cur, type); | 663 | find_ranges(node, regions, cur, type); | |
659 | if (*cur == -1) | 664 | if (*cur == -1) | |
660 | return; | 665 | return; | |
661 | } | 666 | } | |
662 | } | 667 | } | |
663 | 668 | |||
664 | static int | 669 | static int | |
665 | find_lowest_range(rangemap_t *ranges, int nrof, int type) | 670 | find_lowest_range(rangemap_t *ranges, int nrof, int type) | |
666 | { | 671 | { | |
667 | int i, low = 0; | 672 | int i, low = 0; | |
668 | u_int32_t addr = 0xffffffff; | 673 | u_int32_t addr = 0xffffffff; | |
669 | 674 | |||
670 | for (i=0; i < nrof; i++) { | 675 | for (i=0; i < nrof; i++) { | |
671 | if (ranges[i].type == type && ranges[i].addr != 0 && | 676 | if (ranges[i].type == type && ranges[i].addr != 0 && | |
672 | ranges[i].addr < addr) { | 677 | ranges[i].addr < addr) { | |
673 | low = i; | 678 | low = i; | |
674 | addr = ranges[i].addr; | 679 | addr = ranges[i].addr; | |
675 | } | 680 | } | |
676 | } | 681 | } | |
677 | if (addr == 0xffffffff) | 682 | if (addr == 0xffffffff) | |
678 | return -1; | 683 | return -1; | |
679 | return low; | 684 | return low; | |
680 | } | 685 | } | |
681 | 686 | |||
682 | /* | 687 | /* | |
683 | * Find a region of memory, and create a bus_space_tag for it. | 688 | * Find a region of memory, and create a bus_space_tag for it. | |
684 | * Notes: | 689 | * Notes: | |
685 | * For ISA node is ignored. | 690 | * For ISA node is ignored. | |
686 | * node is the starting node. if -1, we start at / and map everything. | 691 | * node is the starting node. if -1, we start at / and map everything. | |
687 | */ | 692 | */ | |
688 | 693 | |||
689 | int | 694 | int | |
690 | ofwoea_map_space(int rangetype, int iomem, int node, | 695 | ofwoea_map_space(int rangetype, int iomem, int node, | |
691 | struct powerpc_bus_space *tag, const char *name) | 696 | struct powerpc_bus_space *tag, const char *name) | |
692 | { | 697 | { | |
693 | int i, cur, range, nrofholes, error; | 698 | int i, cur, range, nrofholes, error; | |
694 | static int exmap=0; | 699 | static int exmap=0; | |
695 | rangemap_t region, holes[32], list[32]; | 700 | rangemap_t region, holes[32], list[32]; | |
696 | 701 | |||
697 | memset(list, 0, sizeof(list)); | 702 | memset(list, 0, sizeof(list)); | |
698 | memset(®ion, 0, sizeof(region)); | 703 | memset(®ion, 0, sizeof(region)); | |
699 | cur = 0; | 704 | cur = 0; | |
700 | if (rangetype == RANGE_TYPE_ISA || node == -1) | 705 | if (rangetype == RANGE_TYPE_ISA || node == -1) | |
701 | node = OF_finddevice("/"); | 706 | node = OF_finddevice("/"); | |
702 | if (rangetype == RANGE_TYPE_ISA) { | 707 | if (rangetype == RANGE_TYPE_ISA) { | |
703 | u_int32_t size = 0; | 708 | u_int32_t size = 0; | |
704 | rangemap_t regions[32]; | 709 | rangemap_t regions[32]; | |
705 | 710 | |||
706 | DPRINTF("LOOKING FOR FIRSTPCI\n"); | 711 | DPRINTF("LOOKING FOR FIRSTPCI\n"); | |
707 | find_ranges(node, list, &cur, RANGE_TYPE_FIRSTPCI); | 712 | find_ranges(node, list, &cur, RANGE_TYPE_FIRSTPCI); | |
708 | range = 0; | 713 | range = 0; | |
709 | DPRINTF("LOOKING FOR ISA\n"); | 714 | DPRINTF("LOOKING FOR ISA\n"); | |
710 | find_ranges(node, regions, &range, RANGE_TYPE_ISA); | 715 | find_ranges(node, regions, &range, RANGE_TYPE_ISA); | |
711 | if (range == 0 || cur == 0) | 716 | if (range == 0 || cur == 0) | |
712 | return -1; /* no isa stuff found */ | 717 | return -1; /* no isa stuff found */ | |
713 | /* | 718 | /* | |
714 | * This may be confusing to some. The ISA ranges property | 719 | * This may be confusing to some. The ISA ranges property | |
715 | * is supposed to be a set of IO ranges for the ISA bus, but | 720 | * is supposed to be a set of IO ranges for the ISA bus, but | |
716 | * generally, it's just a set of pci devfunc lists that tell | 721 | * generally, it's just a set of pci devfunc lists that tell | |
717 | * you to go look at the parent PCI device for the actual | 722 | * you to go look at the parent PCI device for the actual | |
718 | * ranges. | 723 | * ranges. | |
719 | */ | 724 | */ | |
720 | if (range == -1) { | 725 | if (range == -1) { | |
721 | /* we found a rangeless isa bus */ | 726 | /* we found a rangeless isa bus */ | |
722 | if (iomem == RANGE_IO) | 727 | if (iomem == RANGE_IO) | |
723 | size = 0x10000; | 728 | size = 0x10000; | |
724 | else | 729 | else | |
725 | size = 0x1000000; | 730 | size = 0x1000000; | |
726 | } | 731 | } | |
727 | DPRINTF("found isa stuff\n"); | 732 | DPRINTF("found isa stuff\n"); | |
728 | for (i=0; i < range; i++) | 733 | for (i=0; i < range; i++) | |
729 | if (regions[i].type == iomem) | 734 | if (regions[i].type == iomem) | |
730 | size = regions[i].size; | 735 | size = regions[i].size; | |
731 | if (iomem == RANGE_IO) { | 736 | if (iomem == RANGE_IO) { | |
732 | /* the first io range is the one */ | 737 | /* the first io range is the one */ | |
733 | for (i=0; i < cur; i++) | 738 | for (i=0; i < cur; i++) | |
734 | if (list[i].type == RANGE_IO && size) { | 739 | if (list[i].type == RANGE_IO && size) { | |
735 | DPRINTF("found IO\n"); | 740 | DPRINTF("found IO\n"); | |
736 | tag->pbs_offset = list[i].addr; | 741 | tag->pbs_offset = list[i].addr; | |
737 | tag->pbs_limit = size; | 742 | tag->pbs_limit = size; | |
738 | error = bus_space_init(tag, name, | 743 | error = bus_space_init(tag, name, | |
739 | ex_storage[exmap], | 744 | ex_storage[exmap], | |
740 | sizeof(ex_storage[exmap])); | 745 | sizeof(ex_storage[exmap])); | |
741 | exmap++; | 746 | exmap++; | |
742 | return error; | 747 | return error; | |
743 | } | 748 | } | |
744 | } else { | 749 | } else { | |
745 | for (i=0; i < cur; i++) | 750 | for (i=0; i < cur; i++) | |
746 | if (list[i].type == RANGE_MEM && | 751 | if (list[i].type == RANGE_MEM && | |
747 | list[i].size == size) { | 752 | list[i].size == size) { | |
748 | DPRINTF("found mem\n"); | 753 | DPRINTF("found mem\n"); | |
749 | tag->pbs_offset = list[i].addr; | 754 | tag->pbs_offset = list[i].addr; | |
750 | tag->pbs_limit = size; | 755 | tag->pbs_limit = size; | |
751 | error = bus_space_init(tag, name, | 756 | error = bus_space_init(tag, name, | |
752 | ex_storage[exmap], | 757 | ex_storage[exmap], | |
753 | sizeof(ex_storage[exmap])); | 758 | sizeof(ex_storage[exmap])); | |
754 | exmap++; | 759 | exmap++; | |
755 | return error; | 760 | return error; | |
756 | } | 761 | } | |
757 | } | 762 | } | |
758 | return -1; /* NO ISA FOUND */ | 763 | return -1; /* NO ISA FOUND */ | |
759 | } | 764 | } | |
760 | find_ranges(node, list, &cur, rangetype); | 765 | find_ranges(node, list, &cur, rangetype); | |
761 | 766 | |||
762 | DPRINTF("cur == %d\n", cur); | 767 | DPRINTF("cur == %d\n", cur); | |
763 | /* now list should contain a list of memory regions */ | 768 | /* now list should contain a list of memory regions */ | |
764 | for (i=0; i < cur; i++) | 769 | for (i=0; i < cur; i++) | |
765 | DPRINTF("addr=0x%x size=0x%x type=%d\n", list[i].addr, | 770 | DPRINTF("addr=0x%x size=0x%x type=%d\n", list[i].addr, | |
766 | list[i].size, list[i].type); | 771 | list[i].size, list[i].type); | |
767 | 772 | |||
768 | range = find_lowest_range(list, cur, iomem); | 773 | range = find_lowest_range(list, cur, iomem); | |
769 | i = 0; | 774 | i = 0; | |
770 | nrofholes = 0; | 775 | nrofholes = 0; | |
771 | while (range != -1) { | 776 | while (range != -1) { | |
772 | DPRINTF("range==%d\n", range); | 777 | DPRINTF("range==%d\n", range); | |
773 | DPRINTF("i==%d\n", i); | 778 | DPRINTF("i==%d\n", i); | |
774 | if (i == 0) { | 779 | if (i == 0) { | |
775 | memcpy(®ion, &list[range], sizeof(rangemap_t)); | 780 | memcpy(®ion, &list[range], sizeof(rangemap_t)); | |
776 | list[range].addr = 0; | 781 | list[range].addr = 0; | |
777 | i++; | 782 | i++; | |
778 | range = find_lowest_range(list, cur, iomem); | 783 | range = find_lowest_range(list, cur, iomem); | |
779 | continue; | 784 | continue; | |
780 | } | 785 | } | |
781 | if (region.addr + region.size < list[range].addr) { | 786 | if (region.addr + region.size < list[range].addr) { | |
782 | /* allocate a hole */ | 787 | /* allocate a hole */ | |
783 | holes[nrofholes].type = iomem; | 788 | holes[nrofholes].type = iomem; | |
784 | holes[nrofholes].addr = region.size + region.addr; | 789 | holes[nrofholes].addr = region.size + region.addr; | |
785 | holes[nrofholes].size = list[range].addr - | 790 | holes[nrofholes].size = list[range].addr - | |
786 | holes[nrofholes].addr - 1; | 791 | holes[nrofholes].addr - 1; | |
787 | nrofholes++; | 792 | nrofholes++; | |
788 | } | 793 | } | |
789 | region.size = list[range].size + list[range].addr - | 794 | region.size = list[range].size + list[range].addr - | |
790 | region.addr; | 795 | region.addr; | |
791 | list[range].addr = 0; | 796 | list[range].addr = 0; | |
792 | range = find_lowest_range(list, cur, iomem); | 797 | range = find_lowest_range(list, cur, iomem); | |
793 | } | 798 | } | |
794 | DPRINTF("RANGE iomem=%d FOUND\n", iomem); | 799 | DPRINTF("RANGE iomem=%d FOUND\n", iomem); | |
795 | DPRINTF("addr=0x%x size=0x%x type=%d\n", region.addr, | 800 | DPRINTF("addr=0x%x size=0x%x type=%d\n", region.addr, | |
796 | region.size, region.type); | 801 | region.size, region.type); | |
797 | DPRINTF("HOLES FOUND\n"); | 802 | DPRINTF("HOLES FOUND\n"); | |
798 | for (i=0; i < nrofholes; i++) | 803 | for (i=0; i < nrofholes; i++) | |
799 | DPRINTF("addr=0x%x size=0x%x type=%d\n", holes[i].addr, | 804 | DPRINTF("addr=0x%x size=0x%x type=%d\n", holes[i].addr, | |
800 | holes[i].size, holes[i].type); | 805 | holes[i].size, holes[i].type); | |
801 | /* AT THIS POINT WE MAP IT */ | 806 | /* AT THIS POINT WE MAP IT */ | |
802 | 807 | |||
803 | if ((rangetype == RANGE_TYPE_PCI) || (rangetype == RANGE_TYPE_MACIO)) { | 808 | if ((rangetype == RANGE_TYPE_PCI) || (rangetype == RANGE_TYPE_MACIO)) { | |
804 | if (exmap == EXSTORAGE_MAX) | 809 | if (exmap == EXSTORAGE_MAX) | |
805 | panic("Not enough ex_storage space. " | 810 | panic("Not enough ex_storage space. " | |
806 | "Increase EXSTORAGE_MAX"); | 811 | "Increase EXSTORAGE_MAX"); | |
807 | 812 | |||
808 | /* XXX doing this in here might be wrong */ | 813 | /* XXX doing this in here might be wrong */ | |
809 | if (iomem == 1) { | 814 | if (iomem == 1) { | |
810 | /* we map an IO region */ | 815 | /* we map an IO region */ | |
811 | tag->pbs_offset = region.addr; | 816 | tag->pbs_offset = region.addr; | |
812 | tag->pbs_base = 0; | 817 | tag->pbs_base = 0; | |
813 | tag->pbs_limit = region.size; | 818 | tag->pbs_limit = region.size; | |
814 | } else { | 819 | } else { | |
815 | /* ... or a memory region */ | 820 | /* ... or a memory region */ | |
816 | tag->pbs_offset = 0; | 821 | tag->pbs_offset = 0; | |
817 | tag->pbs_base = region.addr; | 822 | tag->pbs_base = region.addr; | |
818 | tag->pbs_limit = region.size + region.addr; | 823 | tag->pbs_limit = region.size + region.addr; | |
819 | } | 824 | } | |
820 | 825 | |||
821 | error = bus_space_init(tag, name, ex_storage[exmap], | 826 | error = bus_space_init(tag, name, ex_storage[exmap], | |
822 | sizeof(ex_storage[exmap])); | 827 | sizeof(ex_storage[exmap])); | |
823 | exmap++; | 828 | exmap++; | |
824 | if (error) | 829 | if (error) | |
825 | panic("ofwoea_bus_space_init: can't init tag %s", name); | 830 | panic("ofwoea_bus_space_init: can't init tag %s", name); | |
826 | for (i=0; i < nrofholes; i++) { | 831 | for (i=0; i < nrofholes; i++) { | |
827 | if (holes[i].type == RANGE_IO) { | 832 | if (holes[i].type == RANGE_IO) { | |
828 | error = extent_alloc_region(tag->pbs_extent, | 833 | error = extent_alloc_region(tag->pbs_extent, | |
829 | holes[i].addr - tag->pbs_offset, | 834 | holes[i].addr - tag->pbs_offset, | |
830 | holes[i].size, EX_NOWAIT); | 835 | holes[i].size, EX_NOWAIT); | |
831 | } else { | 836 | } else { | |
832 | error = extent_alloc_region(tag->pbs_extent, | 837 | error = extent_alloc_region(tag->pbs_extent, | |
833 | holes[i].addr, holes[i].size, EX_NOWAIT); | 838 | holes[i].addr, holes[i].size, EX_NOWAIT); | |
834 | } | 839 | } | |
835 | if (error) | 840 | if (error) | |
836 | panic("ofwoea_bus_space_init: can't block out" | 841 | panic("ofwoea_bus_space_init: can't block out" | |
837 | " reserved space 0x%x-0x%x: error=%d", | 842 | " reserved space 0x%x-0x%x: error=%d", | |
838 | holes[i].addr, holes[i].addr+holes[i].size, | 843 | holes[i].addr, holes[i].addr+holes[i].size, | |
839 | error); | 844 | error); | |
840 | } | 845 | } | |
841 | return error; | 846 | return error; | |
842 | } | 847 | } | |
843 | return -1; | 848 | return -1; | |
844 | } | 849 | } | |
845 | 850 | |||
846 | void | 851 | void | |
847 | ofwoea_bus_space_init(void) | 852 | ofwoea_bus_space_init(void) | |
848 | { | 853 | { | |
849 | int error; | 854 | int error; | |
850 | 855 | |||
851 | error = ofwoea_map_space(RANGE_TYPE_ISA, RANGE_IO, -1, | 856 | error = ofwoea_map_space(RANGE_TYPE_ISA, RANGE_IO, -1, | |
852 | &genppc_isa_io_space_tag, "isa-ioport"); | 857 | &genppc_isa_io_space_tag, "isa-ioport"); | |
853 | if (error > 0) | 858 | if (error > 0) | |
854 | panic("Could not map ISA IO"); | 859 | panic("Could not map ISA IO"); | |
855 | 860 | |||
856 | error = ofwoea_map_space(RANGE_TYPE_ISA, RANGE_MEM, -1, | 861 | error = ofwoea_map_space(RANGE_TYPE_ISA, RANGE_MEM, -1, | |
857 | &genppc_isa_mem_space_tag, "isa-iomem"); | 862 | &genppc_isa_mem_space_tag, "isa-iomem"); | |
858 | if (error > 0) | 863 | if (error > 0) | |
859 | panic("Could not map ISA MEM"); | 864 | panic("Could not map ISA MEM"); | |
860 | } | 865 | } |