Tue Jul 7 02:33:55 2020 UTC ()
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.


(rin)
diff -r1.19 -r1.20 src/sys/arch/macppc/include/autoconf.h
diff -r1.169 -r1.170 src/sys/arch/macppc/macppc/machdep.c
diff -r1.16 -r1.17 src/sys/arch/ofppc/include/autoconf.h
diff -r1.15 -r1.16 src/sys/arch/powerpc/oea/ofw_rascons.c
diff -r1.49 -r1.50 src/sys/arch/powerpc/oea/ofwoea_machdep.c

cvs diff -r1.19 -r1.20 src/sys/arch/macppc/include/autoconf.h (switch to unified diff)

--- 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
41struct confargs { 41struct 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 */
54void ofbcopy(const void *, void *, size_t); 54void ofbcopy(const void *, void *, size_t);
55int badaddr(volatile void *, int); 55int badaddr(volatile void *, int);
56 56
57/* these are in clock.c */ 57/* these are in clock.c */
58void calc_delayconst(void); 58void calc_delayconst(void);
59void decr_intr(struct clockframe *); 59void decr_intr(struct clockframe *);
60 60
61/* these are in cpu.c */ 61/* these are in cpu.c */
62void identifycpu(char *); 62void identifycpu(char *);
63 63
64/* these are in machdep.c */ 64/* these are in machdep.c */
65void initppc(u_int, u_int, char *); 65void initppc(u_int, u_int, char *);
66void model_init(void); 66void model_init(void);
67paddr_t kvtop(void *); 67paddr_t kvtop(void *);
68void dumpsys(void); 68void dumpsys(void);
69void copy_disp_props(device_t, int, prop_dictionary_t); 69void copy_disp_props(device_t, int, prop_dictionary_t);
70 70
71/* these are in extintr.c */ 71/* these are in extintr.c */
72void init_interrupt(void); 72void init_interrupt(void);
73 73
74/* these are in dev/akbd.c */ 74/* these are in dev/akbd.c */
75int kbd_intr(void *); 75int kbd_intr(void *);
76int akbd_cnattach(void); 76int akbd_cnattach(void);
77int adbkbd_cnattach(void); 77int adbkbd_cnattach(void);
78 78
79/* these are in dev/ofb.c */ 79/* these are in dev/ofb.c */
80int ofb_is_console(void); 80int ofb_is_console(void);
81int rascons_cnattach(void); 81int rascons_cnattach(void);
82 82
83extern int console_node; 83extern int console_node;
84extern int console_instance; 84extern int console_instance;
 85extern int ofw_quiesce;
85extern char model_name[64]; 86extern char model_name[64];
86 87
87#endif /* _MACHINE_AUTOCONF_H_ */ 88#endif /* _MACHINE_AUTOCONF_H_ */

cvs diff -r1.169 -r1.170 src/sys/arch/macppc/macppc/machdep.c (switch to unified diff)

--- 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
104struct genfb_colormap_callback gfb_cb; 104struct genfb_colormap_callback gfb_cb;
105struct genfb_parameter_callback gpc_backlight, gpc_brightness; 105struct 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
113int backlight_state = 1; 113int backlight_state = 1;
114int brightness_level = 200; 114int brightness_level = 200;
115 115
116static void of_set_palette(void *, int, int, int, int); 116static void of_set_palette(void *, int, int, int, int);
117static void add_model_specifics(prop_dictionary_t); 117static void add_model_specifics(prop_dictionary_t);
118static int of_get_backlight(void *, int *); 118static int of_get_backlight(void *, int *);
119static int of_set_backlight(void *, int); 119static int of_set_backlight(void *, int);
120static int of_get_brightness(void *, int *); 120static int of_get_brightness(void *, int *);
121static int of_set_brightness(void *, int); 121static int of_set_brightness(void *, int);
122static int of_upd_brightness(void *, int); 122static int of_upd_brightness(void *, int);
123 123
124void 124void
125initppc(u_int startkernel, u_int endkernel, char *args) 125initppc(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() */
131void 131void
132model_init(void) 132model_init(void)
133{ 133{
134} 134}
135 135
136void 136void
137consinit(void) 137consinit(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 */
145void 145void
146cpu_startup(void) 146cpu_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
155void 155void
156dumpsys(void) 156dumpsys(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 */
164void 164void
165cpu_reboot(int howto, char *what) 165cpu_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 */
266void 266void
267callback(void *p) 267callback(void *p)
268{ 268{
269 panic("callback"); /* for now XXX */ 269 panic("callback"); /* for now XXX */
270} 270}
271#endif 271#endif
272 272
273void 273void
274copy_disp_props(device_t dev, int node, prop_dictionary_t dict) 274copy_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
387static void 397static void
388add_model_specifics(prop_dictionary_t dict) 398add_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
429static void 439static void
430of_set_palette(void *cookie, int index, int r, int g, int b) 440of_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
437static int 447static int
438of_get_backlight(void *cookie, int *state) 448of_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
446static int 456static int
447of_set_backlight(void *cookie, int state) 457of_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
462static int 472static int
463of_get_brightness(void *cookie, int *level) 473of_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
476static int 486static int
477of_set_brightness(void *cookie, int level) 487of_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
489static int 499static int
490of_upd_brightness(void *cookie, int delta) 500of_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}

cvs diff -r1.16 -r1.17 src/sys/arch/ofppc/include/autoconf.h (switch to unified diff)

--- 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
10struct confargs { 10struct 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
22struct pciio_info { 22struct 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
29struct model_data { 29struct 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
34extern int console_node; 34extern int console_node;
 35extern int ofw_quiesce; /* XXX not used at the moment */
35extern char model_name[64]; 36extern char model_name[64];
36 37
37#ifdef _KERNEL 38#ifdef _KERNEL
38void initppc(u_int, u_int, char *); 39void initppc(u_int, u_int, char *);
39void model_init(void); 40void model_init(void);
40void strayintr(int); 41void strayintr(int);
41void dumpsys(void); 42void dumpsys(void);
42 43
43void inittodr(time_t); 44void inittodr(time_t);
44void resettodr(void); 45void resettodr(void);
45void cpu_initclocks(void); 46void cpu_initclocks(void);
46void decr_intr(struct clockframe *); 47void decr_intr(struct clockframe *);
47void setstatclockrate(int); 48void setstatclockrate(int);
48void init_interrupt(void); 49void init_interrupt(void);
49void init_ofppc_interrupt(void); 50void init_ofppc_interrupt(void);
50void ofppc_init_comcons(int); 51void ofppc_init_comcons(int);
51void copy_disp_props(device_t, int, prop_dictionary_t); 52void copy_disp_props(device_t, int, prop_dictionary_t);
52 53
53void OF_start_cpu(int, u_int, int); 54void OF_start_cpu(int, u_int, int);
54 55
55int rascons_cnattach(void); 56int rascons_cnattach(void);
56#endif /* _KERNEL */ 57#endif /* _KERNEL */
57 58
58#endif /* _OFPPC_AUTOCONF_H_ */ 59#endif /* _OFPPC_AUTOCONF_H_ */

cvs diff -r1.15 -r1.16 src/sys/arch/powerpc/oea/ofw_rascons.c (switch to unified diff)

--- 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
62static int copy_rom_font(void); 62static int copy_rom_font(void);
63static struct wsdisplay_font openfirm6x11; 63static struct wsdisplay_font openfirm6x11;
64static vaddr_t fbaddr; 64static vaddr_t fbaddr;
65static int romfont_loaded = 0; 65static int romfont_loaded = 0;
66static int needs_finalize = 0; 66static 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 */
69static uint8_t fontbuf[FONTBUFSIZE]; 69static uint8_t fontbuf[FONTBUFSIZE];
70 70
71struct vcons_screen rascons_console_screen; 71struct vcons_screen rascons_console_screen;
72 72
73struct wsscreen_descr rascons_stdscreen = { 73struct 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
81int 81int
82rascons_cnattach(void) 82rascons_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
151void 151void
152rascons_add_rom_font(void) 152rascons_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
160void 160void
161rascons_finalize(void) 161rascons_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
181static int 181static int
182copy_rom_font(void) 182copy_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
233int 233int
234rascons_init_rasops(int node, struct rasops_info *ri) 234rascons_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 */
292int 304int
293rascons_cnattach(void) 305rascons_cnattach(void)
294{ 306{
295 return -1; 307 return -1;
296} 308}
297#endif 309#endif

cvs diff -r1.49 -r1.50 src/sys/arch/powerpc/oea/ofwoea_machdep.c (switch to unified diff)

--- 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
85extern struct model_data modeldata; 85extern 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
94typedef struct _rangemap { 94typedef 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
100struct ofw_translations { 100struct 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
111struct pmap ofw_pmap; 111struct pmap ofw_pmap;
112struct ofw_translations ofmap[32]; 112struct ofw_translations ofmap[32];
113char bootpath[256]; 113char bootpath[256];
114char model_name[64]; 114char model_name[64];
115#if NKSYMS || defined(DDB) || defined(MODULAR) 115#if NKSYMS || defined(DDB) || defined(MODULAR)
116void *startsym, *endsym; 116void *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
124u_int timebase_freq = TIMEBASE_FREQ; 124u_int timebase_freq = TIMEBASE_FREQ;
125#else 125#else
126u_int timebase_freq = 0; 126u_int timebase_freq = 0;
127#endif 127#endif
128 128
 129int ofw_quiesce;
 130
129extern int ofwmsr; 131extern int ofwmsr;
130extern int chosen; 132extern int chosen;
131extern uint32_t ticks_per_sec; 133extern uint32_t ticks_per_sec;
132extern uint32_t ns_per_tick; 134extern uint32_t ns_per_tick;
133extern uint32_t ticks_per_intr; 135extern uint32_t ticks_per_intr;
134 136
135static int save_ofmap(struct ofw_translations *, int); 137static int save_ofmap(struct ofw_translations *, int);
136static void restore_ofmap(struct ofw_translations *, int); 138static void restore_ofmap(struct ofw_translations *, int);
137static void set_timebase(void); 139static void set_timebase(void);
138 140
139extern void cpu_spinstart(u_int); 141extern void cpu_spinstart(u_int);
140extern volatile u_int cpu_spinstart_ack; 142extern volatile u_int cpu_spinstart_ack;
141 143
142void 144void
143ofwoea_initppc(u_int startkernel, u_int endkernel, char *args) 145ofwoea_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
320void 325void
321set_timebase(void) 326set_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
356found: 361found:
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
374static int 379static int
375save_ofmap(struct ofw_translations *map, int maxlen) 380save_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*/
397void 402void
398restore_ofmap(struct ofw_translations *map, int len) 403restore_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)
443static u_int16_t 448static u_int16_t
444ranges_bitmap(int node, u_int16_t bitmap) 449ranges_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 }
477noranges: 482noranges:
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
485void 490void
486ofwoea_batinit(void) 491ofwoea_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 */
541struct powerpc_bus_space genppc_isa_io_space_tag = { 546struct 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
546struct powerpc_bus_space genppc_isa_mem_space_tag = { 551struct 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 */
554static char ex_storage[EXSTORAGE_MAX][EXTENT_FIXED_STORAGE_SIZE(EXTMAP_RANGES)] 559static char ex_storage[EXSTORAGE_MAX][EXTENT_FIXED_STORAGE_SIZE(EXTMAP_RANGES)]
555 __attribute__((aligned(8))); 560 __attribute__((aligned(8)));
556 561
557 562
558static void 563static void
559find_ranges(int base, rangemap_t *regions, int *cur, int type) 564find_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;
655rec: 660rec:
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
664static int 669static int
665find_lowest_range(rangemap_t *ranges, int nrof, int type) 670find_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
689int 694int
690ofwoea_map_space(int rangetype, int iomem, int node, 695ofwoea_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(&region, 0, sizeof(region)); 703 memset(&region, 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(&region, &list[range], sizeof(rangemap_t)); 780 memcpy(&region, &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
846void 851void
847ofwoea_bus_space_init(void) 852ofwoea_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}