Sat Apr 11 15:29:58 2015 UTC ()
Tweak cpu start up slightly and print TTBR for cortex_mmuinfo when
VERBOSE_INIT_ARM


(skrll)
diff -r1.59 -r1.60 src/sys/arch/evbarm/rpi/rpi_machdep.c

cvs diff -r1.59 -r1.60 src/sys/arch/evbarm/rpi/Attic/rpi_machdep.c (switch to unified diff)

--- src/sys/arch/evbarm/rpi/Attic/rpi_machdep.c 2015/03/15 22:54:03 1.59
+++ src/sys/arch/evbarm/rpi/Attic/rpi_machdep.c 2015/04/11 15:29:58 1.60
@@ -1,1189 +1,1194 @@ @@ -1,1189 +1,1194 @@
1/* $NetBSD: rpi_machdep.c,v 1.59 2015/03/15 22:54:03 joerg Exp $ */ 1/* $NetBSD: rpi_machdep.c,v 1.60 2015/04/11 15:29:58 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2012 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 Nick Hudson 8 * by Nick Hudson
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: rpi_machdep.c,v 1.59 2015/03/15 22:54:03 joerg Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.60 2015/04/11 15:29:58 skrll Exp $");
34 34
35#include "opt_arm_debug.h" 35#include "opt_arm_debug.h"
36#include "opt_bcm283x.h" 36#include "opt_bcm283x.h"
37#include "opt_cpuoptions.h" 37#include "opt_cpuoptions.h"
38#include "opt_ddb.h" 38#include "opt_ddb.h"
39#include "opt_evbarm_boardtype.h" 39#include "opt_evbarm_boardtype.h"
40#include "opt_kgdb.h" 40#include "opt_kgdb.h"
41#include "opt_rpi.h" 41#include "opt_rpi.h"
42#include "opt_vcprop.h" 42#include "opt_vcprop.h"
43 43
44#include "sdhc.h" 44#include "sdhc.h"
45#include "bcmdwctwo.h" 45#include "bcmdwctwo.h"
46#include "bcmspi.h" 46#include "bcmspi.h"
47#include "bsciic.h" 47#include "bsciic.h"
48#include "plcom.h" 48#include "plcom.h"
49#include "genfb.h" 49#include "genfb.h"
50#include "ukbd.h" 50#include "ukbd.h"
51 51
52#include <sys/param.h> 52#include <sys/param.h>
53#include <sys/device.h> 53#include <sys/device.h>
54#include <sys/termios.h> 54#include <sys/termios.h>
55#include <sys/reboot.h> 55#include <sys/reboot.h>
56#include <sys/sysctl.h> 56#include <sys/sysctl.h>
57#include <sys/bus.h> 57#include <sys/bus.h>
58 58
59#include <net/if_ether.h> 59#include <net/if_ether.h>
60#include <prop/proplib.h> 60#include <prop/proplib.h>
61 61
62#include <dev/cons.h> 62#include <dev/cons.h>
63 63
64#include <uvm/uvm_extern.h> 64#include <uvm/uvm_extern.h>
65 65
66#include <arm/arm32/machdep.h> 66#include <arm/arm32/machdep.h>
67 67
68#include <machine/autoconf.h> 68#include <machine/autoconf.h>
69#include <machine/vmparam.h> 69#include <machine/vmparam.h>
70#include <machine/bootconfig.h> 70#include <machine/bootconfig.h>
71#include <machine/pmap.h> 71#include <machine/pmap.h>
72 72
73#include <arm/broadcom/bcm2835reg.h> 73#include <arm/broadcom/bcm2835reg.h>
74#include <arm/broadcom/bcm2835var.h> 74#include <arm/broadcom/bcm2835var.h>
75#include <arm/broadcom/bcm2835_pmvar.h> 75#include <arm/broadcom/bcm2835_pmvar.h>
76#include <arm/broadcom/bcm2835_mbox.h> 76#include <arm/broadcom/bcm2835_mbox.h>
77#include <arm/broadcom/bcm_amba.h> 77#include <arm/broadcom/bcm_amba.h>
78 78
79#include <evbarm/rpi/vcio.h> 79#include <evbarm/rpi/vcio.h>
80#include <evbarm/rpi/vcpm.h> 80#include <evbarm/rpi/vcpm.h>
81#include <evbarm/rpi/vcprop.h> 81#include <evbarm/rpi/vcprop.h>
82 82
83#include <evbarm/rpi/rpi.h> 83#include <evbarm/rpi/rpi.h>
84 84
85#include <arm/cortex/gtmr_var.h> 85#include <arm/cortex/gtmr_var.h>
86 86
87#ifdef DDB 87#ifdef DDB
88#include <machine/db_machdep.h> 88#include <machine/db_machdep.h>
89#include <ddb/db_sym.h> 89#include <ddb/db_sym.h>
90#include <ddb/db_extern.h> 90#include <ddb/db_extern.h>
91#endif 91#endif
92 92
93#if NPLCOM > 0 93#if NPLCOM > 0
94#include <evbarm/dev/plcomreg.h> 94#include <evbarm/dev/plcomreg.h>
95#include <evbarm/dev/plcomvar.h> 95#include <evbarm/dev/plcomvar.h>
96#endif 96#endif
97 97
98#if NGENFB > 0 98#if NGENFB > 0
99#include <dev/videomode/videomode.h> 99#include <dev/videomode/videomode.h>
100#include <dev/videomode/edidvar.h> 100#include <dev/videomode/edidvar.h>
101#include <dev/wscons/wsconsio.h> 101#include <dev/wscons/wsconsio.h>
102#endif 102#endif
103 103
104#if NUKBD > 0 104#if NUKBD > 0
105#include <dev/usb/ukbdvar.h> 105#include <dev/usb/ukbdvar.h>
106#endif 106#endif
107 107
108extern int KERNEL_BASE_phys[]; 108extern int KERNEL_BASE_phys[];
109extern int KERNEL_BASE_virt[]; 109extern int KERNEL_BASE_virt[];
110 110
111BootConfig bootconfig; /* Boot config storage */ 111BootConfig bootconfig; /* Boot config storage */
112static char bootargs[VCPROP_MAXCMDLINE]; 112static char bootargs[VCPROP_MAXCMDLINE];
113char *boot_args = NULL; 113char *boot_args = NULL;
114 114
115static void rpi_bootparams(void); 115static void rpi_bootparams(void);
116static void rpi_device_register(device_t, void *); 116static void rpi_device_register(device_t, void *);
117 117
118/* 118/*
119 * Macros to translate between physical and virtual for a subset of the 119 * Macros to translate between physical and virtual for a subset of the
120 * kernel address space. *Not* for general use. 120 * kernel address space. *Not* for general use.
121 */ 121 */
122 122
123#define KERN_VTOPDIFF KERNEL_BASE_VOFFSET 123#define KERN_VTOPDIFF KERNEL_BASE_VOFFSET
124#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va - KERN_VTOPDIFF)) 124#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va - KERN_VTOPDIFF))
125#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa + KERN_VTOPDIFF)) 125#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa + KERN_VTOPDIFF))
126 126
127#ifndef RPI_FB_WIDTH 127#ifndef RPI_FB_WIDTH
128#define RPI_FB_WIDTH 1280 128#define RPI_FB_WIDTH 1280
129#endif 129#endif
130#ifndef RPI_FB_HEIGHT 130#ifndef RPI_FB_HEIGHT
131#define RPI_FB_HEIGHT 720 131#define RPI_FB_HEIGHT 720
132#endif 132#endif
133 133
134#if 0 134#if 0
135#define PLCONADDR BCM2835_UART0_BASE 135#define PLCONADDR BCM2835_UART0_BASE
136#endif 136#endif
137 137
138#ifdef BCM2836 138#ifdef BCM2836
139#define PLCONADDR 0x3f201000 139#define PLCONADDR 0x3f201000
140#else 140#else
141#define PLCONADDR 0x20201000 141#define PLCONADDR 0x20201000
142#endif 142#endif
143 143
144#ifndef CONSDEVNAME 144#ifndef CONSDEVNAME
145#define CONSDEVNAME "plcom" 145#define CONSDEVNAME "plcom"
146#endif 146#endif
147 147
148#ifndef PLCONSPEED 148#ifndef PLCONSPEED
149#define PLCONSPEED B115200 149#define PLCONSPEED B115200
150#endif 150#endif
151#ifndef PLCONMODE 151#ifndef PLCONMODE
152#define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 152#define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
153#endif 153#endif
154#ifndef PLCOMCNUNIT 154#ifndef PLCOMCNUNIT
155#define PLCOMCNUNIT -1 155#define PLCOMCNUNIT -1
156#endif 156#endif
157 157
158#if (NPLCOM > 0) 158#if (NPLCOM > 0)
159static const bus_addr_t consaddr = (bus_addr_t)PLCONADDR; 159static const bus_addr_t consaddr = (bus_addr_t)PLCONADDR;
160 160
161int plcomcnspeed = PLCONSPEED; 161int plcomcnspeed = PLCONSPEED;
162int plcomcnmode = PLCONMODE; 162int plcomcnmode = PLCONMODE;
163#endif 163#endif
164 164
165#include "opt_kgdb.h" 165#include "opt_kgdb.h"
166#if (NPLCOM == 0) 166#if (NPLCOM == 0)
167#error Enable plcom for KGDB support 167#error Enable plcom for KGDB support
168#endif 168#endif
169#ifdef KGDB 169#ifdef KGDB
170#include <sys/kgdb.h> 170#include <sys/kgdb.h>
171static void kgdb_port_init(void); 171static void kgdb_port_init(void);
172#endif 172#endif
173 173
174#if (NPLCOM > 0 && (defined(PLCONSOLE) || defined(KGDB))) 174#if (NPLCOM > 0 && (defined(PLCONSOLE) || defined(KGDB)))
175static struct plcom_instance rpi_pi = { 175static struct plcom_instance rpi_pi = {
176 .pi_type = PLCOM_TYPE_PL011, 176 .pi_type = PLCOM_TYPE_PL011,
177 .pi_flags = PLC_FLAG_32BIT_ACCESS, 177 .pi_flags = PLC_FLAG_32BIT_ACCESS,
178 .pi_iot = &bcm2835_bs_tag, 178 .pi_iot = &bcm2835_bs_tag,
179 .pi_size = BCM2835_UART0_SIZE 179 .pi_size = BCM2835_UART0_SIZE
180 }; 180 };
181#endif 181#endif
182 182
183/* Smallest amount of RAM start.elf could give us. */ 183/* Smallest amount of RAM start.elf could give us. */
184#define RPI_MINIMUM_SPLIT (128U * 1024 * 1024) 184#define RPI_MINIMUM_SPLIT (128U * 1024 * 1024)
185 185
186static struct __aligned(16) { 186static struct __aligned(16) {
187 struct vcprop_buffer_hdr vb_hdr; 187 struct vcprop_buffer_hdr vb_hdr;
188 struct vcprop_tag_fwrev vbt_fwrev; 188 struct vcprop_tag_fwrev vbt_fwrev;
189 struct vcprop_tag_boardmodel vbt_boardmodel; 189 struct vcprop_tag_boardmodel vbt_boardmodel;
190 struct vcprop_tag_boardrev vbt_boardrev; 190 struct vcprop_tag_boardrev vbt_boardrev;
191 struct vcprop_tag_macaddr vbt_macaddr; 191 struct vcprop_tag_macaddr vbt_macaddr;
192 struct vcprop_tag_memory vbt_memory; 192 struct vcprop_tag_memory vbt_memory;
193 struct vcprop_tag_boardserial vbt_serial; 193 struct vcprop_tag_boardserial vbt_serial;
194 struct vcprop_tag_dmachan vbt_dmachan; 194 struct vcprop_tag_dmachan vbt_dmachan;
195 struct vcprop_tag_cmdline vbt_cmdline; 195 struct vcprop_tag_cmdline vbt_cmdline;
196 struct vcprop_tag_clockrate vbt_emmcclockrate; 196 struct vcprop_tag_clockrate vbt_emmcclockrate;
197 struct vcprop_tag_clockrate vbt_armclockrate; 197 struct vcprop_tag_clockrate vbt_armclockrate;
198 struct vcprop_tag end; 198 struct vcprop_tag end;
199} vb = 199} vb =
200{ 200{
201 .vb_hdr = { 201 .vb_hdr = {
202 .vpb_len = sizeof(vb), 202 .vpb_len = sizeof(vb),
203 .vpb_rcode = VCPROP_PROCESS_REQUEST, 203 .vpb_rcode = VCPROP_PROCESS_REQUEST,
204 }, 204 },
205 .vbt_fwrev = { 205 .vbt_fwrev = {
206 .tag = { 206 .tag = {
207 .vpt_tag = VCPROPTAG_GET_FIRMWAREREV, 207 .vpt_tag = VCPROPTAG_GET_FIRMWAREREV,
208 .vpt_len = VCPROPTAG_LEN(vb.vbt_fwrev), 208 .vpt_len = VCPROPTAG_LEN(vb.vbt_fwrev),
209 .vpt_rcode = VCPROPTAG_REQUEST 209 .vpt_rcode = VCPROPTAG_REQUEST
210 }, 210 },
211 }, 211 },
212 .vbt_boardmodel = { 212 .vbt_boardmodel = {
213 .tag = { 213 .tag = {
214 .vpt_tag = VCPROPTAG_GET_BOARDMODEL, 214 .vpt_tag = VCPROPTAG_GET_BOARDMODEL,
215 .vpt_len = VCPROPTAG_LEN(vb.vbt_boardmodel), 215 .vpt_len = VCPROPTAG_LEN(vb.vbt_boardmodel),
216 .vpt_rcode = VCPROPTAG_REQUEST 216 .vpt_rcode = VCPROPTAG_REQUEST
217 }, 217 },
218 }, 218 },
219 .vbt_boardrev = { 219 .vbt_boardrev = {
220 .tag = { 220 .tag = {
221 .vpt_tag = VCPROPTAG_GET_BOARDREVISION, 221 .vpt_tag = VCPROPTAG_GET_BOARDREVISION,
222 .vpt_len = VCPROPTAG_LEN(vb.vbt_boardrev), 222 .vpt_len = VCPROPTAG_LEN(vb.vbt_boardrev),
223 .vpt_rcode = VCPROPTAG_REQUEST 223 .vpt_rcode = VCPROPTAG_REQUEST
224 }, 224 },
225 }, 225 },
226 .vbt_macaddr = { 226 .vbt_macaddr = {
227 .tag = { 227 .tag = {
228 .vpt_tag = VCPROPTAG_GET_MACADDRESS, 228 .vpt_tag = VCPROPTAG_GET_MACADDRESS,
229 .vpt_len = VCPROPTAG_LEN(vb.vbt_macaddr), 229 .vpt_len = VCPROPTAG_LEN(vb.vbt_macaddr),
230 .vpt_rcode = VCPROPTAG_REQUEST 230 .vpt_rcode = VCPROPTAG_REQUEST
231 }, 231 },
232 }, 232 },
233 .vbt_memory = { 233 .vbt_memory = {
234 .tag = { 234 .tag = {
235 .vpt_tag = VCPROPTAG_GET_ARMMEMORY, 235 .vpt_tag = VCPROPTAG_GET_ARMMEMORY,
236 .vpt_len = VCPROPTAG_LEN(vb.vbt_memory), 236 .vpt_len = VCPROPTAG_LEN(vb.vbt_memory),
237 .vpt_rcode = VCPROPTAG_REQUEST 237 .vpt_rcode = VCPROPTAG_REQUEST
238 }, 238 },
239 }, 239 },
240 .vbt_serial = { 240 .vbt_serial = {
241 .tag = { 241 .tag = {
242 .vpt_tag = VCPROPTAG_GET_BOARDSERIAL, 242 .vpt_tag = VCPROPTAG_GET_BOARDSERIAL,
243 .vpt_len = VCPROPTAG_LEN(vb.vbt_serial), 243 .vpt_len = VCPROPTAG_LEN(vb.vbt_serial),
244 .vpt_rcode = VCPROPTAG_REQUEST 244 .vpt_rcode = VCPROPTAG_REQUEST
245 }, 245 },
246 }, 246 },
247 .vbt_dmachan = { 247 .vbt_dmachan = {
248 .tag = { 248 .tag = {
249 .vpt_tag = VCPROPTAG_GET_DMACHAN, 249 .vpt_tag = VCPROPTAG_GET_DMACHAN,
250 .vpt_len = VCPROPTAG_LEN(vb.vbt_dmachan), 250 .vpt_len = VCPROPTAG_LEN(vb.vbt_dmachan),
251 .vpt_rcode = VCPROPTAG_REQUEST 251 .vpt_rcode = VCPROPTAG_REQUEST
252 }, 252 },
253 }, 253 },
254 .vbt_cmdline = { 254 .vbt_cmdline = {
255 .tag = { 255 .tag = {
256 .vpt_tag = VCPROPTAG_GET_CMDLINE, 256 .vpt_tag = VCPROPTAG_GET_CMDLINE,
257 .vpt_len = VCPROPTAG_LEN(vb.vbt_cmdline), 257 .vpt_len = VCPROPTAG_LEN(vb.vbt_cmdline),
258 .vpt_rcode = VCPROPTAG_REQUEST 258 .vpt_rcode = VCPROPTAG_REQUEST
259 }, 259 },
260 }, 260 },
261 .vbt_emmcclockrate = { 261 .vbt_emmcclockrate = {
262 .tag = { 262 .tag = {
263 .vpt_tag = VCPROPTAG_GET_CLOCKRATE, 263 .vpt_tag = VCPROPTAG_GET_CLOCKRATE,
264 .vpt_len = VCPROPTAG_LEN(vb.vbt_emmcclockrate), 264 .vpt_len = VCPROPTAG_LEN(vb.vbt_emmcclockrate),
265 .vpt_rcode = VCPROPTAG_REQUEST 265 .vpt_rcode = VCPROPTAG_REQUEST
266 }, 266 },
267 .id = VCPROP_CLK_EMMC 267 .id = VCPROP_CLK_EMMC
268 }, 268 },
269 .vbt_armclockrate = { 269 .vbt_armclockrate = {
270 .tag = { 270 .tag = {
271 .vpt_tag = VCPROPTAG_GET_CLOCKRATE, 271 .vpt_tag = VCPROPTAG_GET_CLOCKRATE,
272 .vpt_len = VCPROPTAG_LEN(vb.vbt_armclockrate), 272 .vpt_len = VCPROPTAG_LEN(vb.vbt_armclockrate),
273 .vpt_rcode = VCPROPTAG_REQUEST 273 .vpt_rcode = VCPROPTAG_REQUEST
274 }, 274 },
275 .id = VCPROP_CLK_ARM 275 .id = VCPROP_CLK_ARM
276 }, 276 },
277 .end = { 277 .end = {
278 .vpt_tag = VCPROPTAG_NULL 278 .vpt_tag = VCPROPTAG_NULL
279 } 279 }
280}; 280};
281 281
282#if NGENFB > 0 282#if NGENFB > 0
283static struct __aligned(16) { 283static struct __aligned(16) {
284 struct vcprop_buffer_hdr vb_hdr; 284 struct vcprop_buffer_hdr vb_hdr;
285 struct vcprop_tag_edidblock vbt_edid; 285 struct vcprop_tag_edidblock vbt_edid;
286 struct vcprop_tag end; 286 struct vcprop_tag end;
287} vb_edid = 287} vb_edid =
288{ 288{
289 .vb_hdr = { 289 .vb_hdr = {
290 .vpb_len = sizeof(vb_edid), 290 .vpb_len = sizeof(vb_edid),
291 .vpb_rcode = VCPROP_PROCESS_REQUEST, 291 .vpb_rcode = VCPROP_PROCESS_REQUEST,
292 }, 292 },
293 .vbt_edid = { 293 .vbt_edid = {
294 .tag = { 294 .tag = {
295 .vpt_tag = VCPROPTAG_GET_EDID_BLOCK, 295 .vpt_tag = VCPROPTAG_GET_EDID_BLOCK,
296 .vpt_len = VCPROPTAG_LEN(vb_edid.vbt_edid), 296 .vpt_len = VCPROPTAG_LEN(vb_edid.vbt_edid),
297 .vpt_rcode = VCPROPTAG_REQUEST, 297 .vpt_rcode = VCPROPTAG_REQUEST,
298 }, 298 },
299 .blockno = 0, 299 .blockno = 0,
300 }, 300 },
301 .end = { 301 .end = {
302 .vpt_tag = VCPROPTAG_NULL 302 .vpt_tag = VCPROPTAG_NULL
303 } 303 }
304}; 304};
305 305
306static struct __aligned(16) { 306static struct __aligned(16) {
307 struct vcprop_buffer_hdr vb_hdr; 307 struct vcprop_buffer_hdr vb_hdr;
308 struct vcprop_tag_fbres vbt_res; 308 struct vcprop_tag_fbres vbt_res;
309 struct vcprop_tag_fbres vbt_vres; 309 struct vcprop_tag_fbres vbt_vres;
310 struct vcprop_tag_fbdepth vbt_depth; 310 struct vcprop_tag_fbdepth vbt_depth;
311 struct vcprop_tag_fbalpha vbt_alpha; 311 struct vcprop_tag_fbalpha vbt_alpha;
312 struct vcprop_tag_allocbuf vbt_allocbuf; 312 struct vcprop_tag_allocbuf vbt_allocbuf;
313 struct vcprop_tag_blankscreen vbt_blank; 313 struct vcprop_tag_blankscreen vbt_blank;
314 struct vcprop_tag_fbpitch vbt_pitch; 314 struct vcprop_tag_fbpitch vbt_pitch;
315 struct vcprop_tag end; 315 struct vcprop_tag end;
316} vb_setfb = 316} vb_setfb =
317{ 317{
318 .vb_hdr = { 318 .vb_hdr = {
319 .vpb_len = sizeof(vb_setfb), 319 .vpb_len = sizeof(vb_setfb),
320 .vpb_rcode = VCPROP_PROCESS_REQUEST, 320 .vpb_rcode = VCPROP_PROCESS_REQUEST,
321 }, 321 },
322 .vbt_res = { 322 .vbt_res = {
323 .tag = { 323 .tag = {
324 .vpt_tag = VCPROPTAG_SET_FB_RES, 324 .vpt_tag = VCPROPTAG_SET_FB_RES,
325 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_res), 325 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_res),
326 .vpt_rcode = VCPROPTAG_REQUEST, 326 .vpt_rcode = VCPROPTAG_REQUEST,
327 }, 327 },
328 .width = 0, 328 .width = 0,
329 .height = 0, 329 .height = 0,
330 }, 330 },
331 .vbt_vres = { 331 .vbt_vres = {
332 .tag = { 332 .tag = {
333 .vpt_tag = VCPROPTAG_SET_FB_VRES, 333 .vpt_tag = VCPROPTAG_SET_FB_VRES,
334 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_vres), 334 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_vres),
335 .vpt_rcode = VCPROPTAG_REQUEST, 335 .vpt_rcode = VCPROPTAG_REQUEST,
336 }, 336 },
337 .width = 0, 337 .width = 0,
338 .height = 0, 338 .height = 0,
339 }, 339 },
340 .vbt_depth = { 340 .vbt_depth = {
341 .tag = { 341 .tag = {
342 .vpt_tag = VCPROPTAG_SET_FB_DEPTH, 342 .vpt_tag = VCPROPTAG_SET_FB_DEPTH,
343 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_depth), 343 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_depth),
344 .vpt_rcode = VCPROPTAG_REQUEST, 344 .vpt_rcode = VCPROPTAG_REQUEST,
345 }, 345 },
346 .bpp = 32, 346 .bpp = 32,
347 }, 347 },
348 .vbt_alpha = { 348 .vbt_alpha = {
349 .tag = { 349 .tag = {
350 .vpt_tag = VCPROPTAG_SET_FB_ALPHA_MODE, 350 .vpt_tag = VCPROPTAG_SET_FB_ALPHA_MODE,
351 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_alpha), 351 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_alpha),
352 .vpt_rcode = VCPROPTAG_REQUEST, 352 .vpt_rcode = VCPROPTAG_REQUEST,
353 }, 353 },
354 .state = VCPROP_ALPHA_IGNORED, 354 .state = VCPROP_ALPHA_IGNORED,
355 }, 355 },
356 .vbt_allocbuf = { 356 .vbt_allocbuf = {
357 .tag = { 357 .tag = {
358 .vpt_tag = VCPROPTAG_ALLOCATE_BUFFER, 358 .vpt_tag = VCPROPTAG_ALLOCATE_BUFFER,
359 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_allocbuf), 359 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_allocbuf),
360 .vpt_rcode = VCPROPTAG_REQUEST, 360 .vpt_rcode = VCPROPTAG_REQUEST,
361 }, 361 },
362 .address = PAGE_SIZE, /* alignment */ 362 .address = PAGE_SIZE, /* alignment */
363 }, 363 },
364 .vbt_blank = { 364 .vbt_blank = {
365 .tag = { 365 .tag = {
366 .vpt_tag = VCPROPTAG_BLANK_SCREEN, 366 .vpt_tag = VCPROPTAG_BLANK_SCREEN,
367 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_blank), 367 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_blank),
368 .vpt_rcode = VCPROPTAG_REQUEST, 368 .vpt_rcode = VCPROPTAG_REQUEST,
369 }, 369 },
370 .state = VCPROP_BLANK_OFF, 370 .state = VCPROP_BLANK_OFF,
371 }, 371 },
372 .vbt_pitch = { 372 .vbt_pitch = {
373 .tag = { 373 .tag = {
374 .vpt_tag = VCPROPTAG_GET_FB_PITCH, 374 .vpt_tag = VCPROPTAG_GET_FB_PITCH,
375 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_pitch), 375 .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_pitch),
376 .vpt_rcode = VCPROPTAG_REQUEST, 376 .vpt_rcode = VCPROPTAG_REQUEST,
377 }, 377 },
378 }, 378 },
379 .end = { 379 .end = {
380 .vpt_tag = VCPROPTAG_NULL, 380 .vpt_tag = VCPROPTAG_NULL,
381 }, 381 },
382}; 382};
383 383
384extern void bcmgenfb_set_console_dev(device_t dev); 384extern void bcmgenfb_set_console_dev(device_t dev);
385void bcmgenfb_set_ioctl(int(*)(void *, void *, u_long, void *, int, struct lwp *)); 385void bcmgenfb_set_ioctl(int(*)(void *, void *, u_long, void *, int, struct lwp *));
386extern void bcmgenfb_ddb_trap_callback(int where); 386extern void bcmgenfb_ddb_trap_callback(int where);
387static int rpi_ioctl(void *, void *, u_long, void *, int, lwp_t *); 387static int rpi_ioctl(void *, void *, u_long, void *, int, lwp_t *);
388 388
389static int rpi_video_on = WSDISPLAYIO_VIDEO_ON; 389static int rpi_video_on = WSDISPLAYIO_VIDEO_ON;
390 390
391#if defined(RPI_HWCURSOR) 391#if defined(RPI_HWCURSOR)
392#define CURSOR_BITMAP_SIZE (64 * 8) 392#define CURSOR_BITMAP_SIZE (64 * 8)
393#define CURSOR_ARGB_SIZE (64 * 64 * 4) 393#define CURSOR_ARGB_SIZE (64 * 64 * 4)
394static uint32_t hcursor = 0; 394static uint32_t hcursor = 0;
395static bus_addr_t pcursor = 0; 395static bus_addr_t pcursor = 0;
396static uint32_t *cmem = NULL; 396static uint32_t *cmem = NULL;
397static int cursor_x = 0, cursor_y = 0, hot_x = 0, hot_y = 0, cursor_on = 0; 397static int cursor_x = 0, cursor_y = 0, hot_x = 0, hot_y = 0, cursor_on = 0;
398static uint32_t cursor_cmap[4]; 398static uint32_t cursor_cmap[4];
399static uint8_t cursor_mask[8 * 64], cursor_bitmap[8 * 64]; 399static uint8_t cursor_mask[8 * 64], cursor_bitmap[8 * 64];
400#endif 400#endif
401#endif 401#endif
402 402
403 403
404static void 404static void
405rpi_bootparams(void) 405rpi_bootparams(void)
406{ 406{
407 bus_space_tag_t iot = &bcm2835_bs_tag; 407 bus_space_tag_t iot = &bcm2835_bs_tag;
408 bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(BCM2835_ARMMBOX_BASE); 408 bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(BCM2835_ARMMBOX_BASE);
409 uint32_t res; 409 uint32_t res;
410 410
411 bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANPM, ( 411 bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANPM, (
412#if (NSDHC > 0) 412#if (NSDHC > 0)
413 (1 << VCPM_POWER_SDCARD) | 413 (1 << VCPM_POWER_SDCARD) |
414#endif 414#endif
415#if (NPLCOM > 0) 415#if (NPLCOM > 0)
416 (1 << VCPM_POWER_UART0) | 416 (1 << VCPM_POWER_UART0) |
417#endif 417#endif
418#if (NBCMDWCTWO > 0) 418#if (NBCMDWCTWO > 0)
419 (1 << VCPM_POWER_USB) | 419 (1 << VCPM_POWER_USB) |
420#endif 420#endif
421#if (NBSCIIC > 0) 421#if (NBSCIIC > 0)
422 (1 << VCPM_POWER_I2C0) | (1 << VCPM_POWER_I2C1) | 422 (1 << VCPM_POWER_I2C0) | (1 << VCPM_POWER_I2C1) |
423 /* (1 << VCPM_POWER_I2C2) | */ 423 /* (1 << VCPM_POWER_I2C2) | */
424#endif 424#endif
425#if (NBCMSPI > 0) 425#if (NBCMSPI > 0)
426 (1 << VCPM_POWER_SPI) | 426 (1 << VCPM_POWER_SPI) |
427#endif 427#endif
428 0) << 4); 428 0) << 4);
429 429
430 bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, KERN_VTOPHYS(&vb)); 430 bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, KERN_VTOPHYS(&vb));
431 431
432 bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res); 432 bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res);
433 433
434 cpu_dcache_inv_range((vaddr_t)&vb, sizeof(vb)); 434 cpu_dcache_inv_range((vaddr_t)&vb, sizeof(vb));
435 435
436 if (!vcprop_buffer_success_p(&vb.vb_hdr)) { 436 if (!vcprop_buffer_success_p(&vb.vb_hdr)) {
437 bootconfig.dramblocks = 1; 437 bootconfig.dramblocks = 1;
438 bootconfig.dram[0].address = 0x0; 438 bootconfig.dram[0].address = 0x0;
439 bootconfig.dram[0].pages = atop(RPI_MINIMUM_SPLIT); 439 bootconfig.dram[0].pages = atop(RPI_MINIMUM_SPLIT);
440 return; 440 return;
441 } 441 }
442 442
443 struct vcprop_tag_memory *vptp_mem = &vb.vbt_memory; 443 struct vcprop_tag_memory *vptp_mem = &vb.vbt_memory;
444 444
445 if (vcprop_tag_success_p(&vptp_mem->tag)) { 445 if (vcprop_tag_success_p(&vptp_mem->tag)) {
446 size_t n = vcprop_tag_resplen(&vptp_mem->tag) / 446 size_t n = vcprop_tag_resplen(&vptp_mem->tag) /
447 sizeof(struct vcprop_memory); 447 sizeof(struct vcprop_memory);
448 448
449 bootconfig.dramblocks = 0; 449 bootconfig.dramblocks = 0;
450 450
451 for (int i = 0; i < n && i < DRAM_BLOCKS; i++) { 451 for (int i = 0; i < n && i < DRAM_BLOCKS; i++) {
452 bootconfig.dram[i].address = vptp_mem->mem[i].base; 452 bootconfig.dram[i].address = vptp_mem->mem[i].base;
453 bootconfig.dram[i].pages = atop(vptp_mem->mem[i].size); 453 bootconfig.dram[i].pages = atop(vptp_mem->mem[i].size);
454 bootconfig.dramblocks++; 454 bootconfig.dramblocks++;
455 } 455 }
456 } 456 }
457 457
458 if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) 458 if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag))
459 curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate; 459 curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate;
460 460
461#ifdef VERBOSE_INIT_ARM 461#ifdef VERBOSE_INIT_ARM
462 if (vcprop_tag_success_p(&vb.vbt_fwrev.tag)) 462 if (vcprop_tag_success_p(&vb.vbt_fwrev.tag))
463 printf("%s: firmware rev %x\n", __func__, 463 printf("%s: firmware rev %x\n", __func__,
464 vb.vbt_fwrev.rev); 464 vb.vbt_fwrev.rev);
465 if (vcprop_tag_success_p(&vb.vbt_macaddr.tag)) 465 if (vcprop_tag_success_p(&vb.vbt_macaddr.tag))
466 printf("%s: mac-address %llx\n", __func__, 466 printf("%s: mac-address %llx\n", __func__,
467 vb.vbt_macaddr.addr); 467 vb.vbt_macaddr.addr);
468 if (vcprop_tag_success_p(&vb.vbt_boardmodel.tag)) 468 if (vcprop_tag_success_p(&vb.vbt_boardmodel.tag))
469 printf("%s: board model %x\n", __func__, 469 printf("%s: board model %x\n", __func__,
470 vb.vbt_boardmodel.model); 470 vb.vbt_boardmodel.model);
471 if (vcprop_tag_success_p(&vb.vbt_boardrev.tag)) 471 if (vcprop_tag_success_p(&vb.vbt_boardrev.tag))
472 printf("%s: board rev %x\n", __func__, 472 printf("%s: board rev %x\n", __func__,
473 vb.vbt_boardrev.rev); 473 vb.vbt_boardrev.rev);
474 if (vcprop_tag_success_p(&vb.vbt_serial.tag)) 474 if (vcprop_tag_success_p(&vb.vbt_serial.tag))
475 printf("%s: board serial %llx\n", __func__, 475 printf("%s: board serial %llx\n", __func__,
476 vb.vbt_serial.sn); 476 vb.vbt_serial.sn);
477 if (vcprop_tag_success_p(&vb.vbt_dmachan.tag)) 477 if (vcprop_tag_success_p(&vb.vbt_dmachan.tag))
478 printf("%s: DMA channel mask 0x%08x\n", __func__, 478 printf("%s: DMA channel mask 0x%08x\n", __func__,
479 vb.vbt_dmachan.mask); 479 vb.vbt_dmachan.mask);
480 480
481 if (vcprop_tag_success_p(&vb.vbt_cmdline.tag)) 481 if (vcprop_tag_success_p(&vb.vbt_cmdline.tag))
482 printf("%s: cmdline %s\n", __func__, 482 printf("%s: cmdline %s\n", __func__,
483 vb.vbt_cmdline.cmdline); 483 vb.vbt_cmdline.cmdline);
484#endif 484#endif
485} 485}
486 486
487 487
488static void 488static void
489rpi_bootstrap(void) 489rpi_bootstrap(void)
490{ 490{
491#if defined(BCM2836) 491#if defined(BCM2836)
492 arm_cpu_max = 4; 492 arm_cpu_max = 4;
493 extern int cortex_mmuinfo; 493 extern int cortex_mmuinfo;
494 bus_space_tag_t iot = &bcm2835_bs_tag; 
495 bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE; 
496 494
497#ifdef VERBOSE_INIT_ARM 495#ifdef VERBOSE_INIT_ARM
498 printf("%s: %d cpus present\n", __func__, arm_cpu_max); 496 printf("%s: %d cpus present\n", __func__, arm_cpu_max);
499#endif 497#endif
500 498
501 extern void cortex_mpstart(void); 
502 cortex_mmuinfo = armreg_ttbr_read(); 499 cortex_mmuinfo = armreg_ttbr_read();
 500#ifdef VERBOSE_INIT_ARM
 501 printf("%s: cortex_mmuinfo %x\n", __func__, cortex_mmuinfo);
 502#endif
 503
 504 extern void cortex_mpstart(void);
503 505
504 for (size_t i = 1; i < arm_cpu_max; i++) { 506 for (size_t i = 1; i < arm_cpu_max; i++) {
 507 bus_space_tag_t iot = &bcm2835_bs_tag;
 508 bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE;
 509
505 bus_space_write_4(iot, ioh, 510 bus_space_write_4(iot, ioh,
506 BCM2836_LOCAL_MAILBOX3_SETN(i), 511 BCM2836_LOCAL_MAILBOX3_SETN(i),
507 (uint32_t)cortex_mpstart); 512 (uint32_t)cortex_mpstart);
508 513
509 int timeout = 20; 514 int timeout = 20;
510 while (timeout-- > 0) { 515 while (timeout-- > 0) {
511 uint32_t val; 516 uint32_t val;
512 517
513 val = bus_space_read_4(iot, ioh, 518 val = bus_space_read_4(iot, ioh,
514 BCM2836_LOCAL_MAILBOX3_CLRN(i)); 519 BCM2836_LOCAL_MAILBOX3_CLRN(i));
515 if (val == 0) 520 if (val == 0)
516 break; 521 break;
517 } 522 }
518 } 523 }
519 524
520 for (int loop = 0; loop < 16; loop++) { 525 for (int loop = 0; loop < 16; loop++) {
521 if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1)) 526 if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1))
522 break; 527 break;
523 gtmr_delay(10000); 528 gtmr_delay(10000);
524 } 529 }
525 530
526 for (size_t i = 1; i < arm_cpu_max; i++) { 531 for (size_t i = 1; i < arm_cpu_max; i++) {
527 if ((arm_cpu_hatched & (1 << i)) == 0) { 532 if ((arm_cpu_hatched & (1 << i)) == 0) {
528 printf("%s: warning: cpu%zu failed to hatch\n", 533 printf("%s: warning: cpu%zu failed to hatch\n",
529 __func__, i); 534 __func__, i);
530 } 535 }
531 } 536 }
532 537
533 /* 538 /*
534 * XXXNH: Disable non-boot CPUs for now 539 * XXXNH: Disable non-boot CPUs for now
535 */ 540 */
536 arm_cpu_hatched = 0; 541 arm_cpu_hatched = 0;
537#endif 542#endif
538} 543}
539 544
540/* 545/*
541 * Static device mappings. These peripheral registers are mapped at 546 * Static device mappings. These peripheral registers are mapped at
542 * fixed virtual addresses very early in initarm() so that we can use 547 * fixed virtual addresses very early in initarm() so that we can use
543 * them while booting the kernel, and stay at the same address 548 * them while booting the kernel, and stay at the same address
544 * throughout whole kernel's life time. 549 * throughout whole kernel's life time.
545 * 550 *
546 * We use this table twice; once with bootstrap page table, and once 551 * We use this table twice; once with bootstrap page table, and once
547 * with kernel's page table which we build up in initarm(). 552 * with kernel's page table which we build up in initarm().
548 * 553 *
549 * Since we map these registers into the bootstrap page table using 554 * Since we map these registers into the bootstrap page table using
550 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map 555 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
551 * registers segment-aligned and segment-rounded in order to avoid 556 * registers segment-aligned and segment-rounded in order to avoid
552 * using the 2nd page tables. 557 * using the 2nd page tables.
553 */ 558 */
554 559
555#define _A(a) ((a) & ~L1_S_OFFSET) 560#define _A(a) ((a) & ~L1_S_OFFSET)
556#define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1)) 561#define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
557 562
558static const struct pmap_devmap rpi_devmap[] = { 563static const struct pmap_devmap rpi_devmap[] = {
559 { 564 {
560 _A(RPI_KERNEL_IO_VBASE), 565 _A(RPI_KERNEL_IO_VBASE),
561 _A(RPI_KERNEL_IO_PBASE), 566 _A(RPI_KERNEL_IO_PBASE),
562 _S(RPI_KERNEL_IO_VSIZE), /* 16Mb */ 567 _S(RPI_KERNEL_IO_VSIZE), /* 16Mb */
563 VM_PROT_READ|VM_PROT_WRITE, 568 VM_PROT_READ|VM_PROT_WRITE,
564 PTE_NOCACHE, 569 PTE_NOCACHE,
565 }, 570 },
566#if defined(BCM2836) 571#if defined(BCM2836)
567 { 572 {
568 _A(RPI_KERNEL_LOCAL_VBASE), 573 _A(RPI_KERNEL_LOCAL_VBASE),
569 _A(RPI_KERNEL_LOCAL_PBASE), 574 _A(RPI_KERNEL_LOCAL_PBASE),
570 _S(RPI_KERNEL_LOCAL_VSIZE), 575 _S(RPI_KERNEL_LOCAL_VSIZE),
571 VM_PROT_READ|VM_PROT_WRITE, 576 VM_PROT_READ|VM_PROT_WRITE,
572 PTE_NOCACHE, 577 PTE_NOCACHE,
573 }, 578 },
574#endif 579#endif
575 { 0, 0, 0, 0, 0 } 580 { 0, 0, 0, 0, 0 }
576}; 581};
577 582
578#undef _A 583#undef _A
579#undef _S 584#undef _S
580 585
581/* 586/*
582 * u_int initarm(...) 587 * u_int initarm(...)
583 * 588 *
584 * Initial entry point on startup. This gets called before main() is 589 * Initial entry point on startup. This gets called before main() is
585 * entered. 590 * entered.
586 * It should be responsible for setting up everything that must be 591 * It should be responsible for setting up everything that must be
587 * in place when main is called. 592 * in place when main is called.
588 * This includes 593 * This includes
589 * Taking a copy of the boot configuration structure. 594 * Taking a copy of the boot configuration structure.
590 * Initialising the physical console so characters can be printed. 595 * Initialising the physical console so characters can be printed.
591 * Setting up page tables for the kernel 596 * Setting up page tables for the kernel
592 */ 597 */
593u_int 598u_int
594initarm(void *arg) 599initarm(void *arg)
595{ 600{
596 601
597 /* 602 /*
598 * Heads up ... Setup the CPU / MMU / TLB functions 603 * Heads up ... Setup the CPU / MMU / TLB functions
599 */ 604 */
600 if (set_cpufuncs()) 605 if (set_cpufuncs())
601 panic("cpu not recognized!"); 606 panic("cpu not recognized!");
602 607
603 /* map some peripheral registers */ 608 /* map some peripheral registers */
604 pmap_devmap_bootstrap((vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE, 609 pmap_devmap_bootstrap((vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE,
605 rpi_devmap); 610 rpi_devmap);
606 611
607 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 612 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
608 613
609 consinit(); 614 consinit();
610 615
611 /* Talk to the user */ 616 /* Talk to the user */
612#define BDSTR(s) _BDSTR(s) 617#define BDSTR(s) _BDSTR(s)
613#define _BDSTR(s) #s 618#define _BDSTR(s) #s
614 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); 619 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
615 620
616#ifdef CORTEX_PMC 621#ifdef CORTEX_PMC
617 cortex_pmc_ccnt_init(); 622 cortex_pmc_ccnt_init();
618#endif 623#endif
619 624
620 rpi_bootparams(); 625 rpi_bootparams();
621 626
622 rpi_bootstrap(); 627 rpi_bootstrap();
623 628
624 if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) { 629 if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) {
625 curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate; 630 curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate;
626#ifdef VERBOSE_INIT_ARM 631#ifdef VERBOSE_INIT_ARM
627 printf("%s: arm clock %d\n", __func__, 632 printf("%s: arm clock %d\n", __func__,
628 vb.vbt_armclockrate.rate); 633 vb.vbt_armclockrate.rate);
629#endif 634#endif
630 } 635 }
631 636
632#ifdef VERBOSE_INIT_ARM 637#ifdef VERBOSE_INIT_ARM
633 printf("initarm: Configuring system ...\n"); 638 printf("initarm: Configuring system ...\n");
634#endif 639#endif
635 640
636 psize_t ram_size = bootconfig.dram[0].pages * PAGE_SIZE; 641 psize_t ram_size = bootconfig.dram[0].pages * PAGE_SIZE;
637 642
638#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS 643#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
639 if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) { 644 if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) {
640 printf("%s: dropping RAM size from %luMB to %uMB\n", 645 printf("%s: dropping RAM size from %luMB to %uMB\n",
641 __func__, (unsigned long) (ram_size >> 20), 646 __func__, (unsigned long) (ram_size >> 20),
642 (KERNEL_VM_BASE - KERNEL_BASE) >> 20); 647 (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
643 ram_size = KERNEL_VM_BASE - KERNEL_BASE; 648 ram_size = KERNEL_VM_BASE - KERNEL_BASE;
644 } 649 }
645#endif 650#endif
646 651
647 /* 652 /*
648 * If MEMSIZE specified less than what we really have, limit ourselves 653 * If MEMSIZE specified less than what we really have, limit ourselves
649 * to that. 654 * to that.
650 */ 655 */
651#ifdef MEMSIZE 656#ifdef MEMSIZE
652 if (ram_size == 0 || ram_size > (unsigned)MEMSIZE * 1024 * 1024) 657 if (ram_size == 0 || ram_size > (unsigned)MEMSIZE * 1024 * 1024)
653 ram_size = (unsigned)MEMSIZE * 1024 * 1024; 658 ram_size = (unsigned)MEMSIZE * 1024 * 1024;
654#else 659#else
655 KASSERTMSG(ram_size > 0, "RAM size unknown and MEMSIZE undefined"); 660 KASSERTMSG(ram_size > 0, "RAM size unknown and MEMSIZE undefined");
656#endif 661#endif
657 662
658 arm32_bootmem_init(bootconfig.dram[0].address, ram_size, 663 arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
659 (uintptr_t)KERNEL_BASE_phys); 664 (uintptr_t)KERNEL_BASE_phys);
660 665
661#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS 666#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
662 const bool mapallmem_p = true; 667 const bool mapallmem_p = true;
663 KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE); 668 KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE);
664#else 669#else
665 const bool mapallmem_p = false; 670 const bool mapallmem_p = false;
666#endif 671#endif
667 672
668 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, rpi_devmap, 673 arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, rpi_devmap,
669 mapallmem_p); 674 mapallmem_p);
670 675
671 cpu_reset_address = bcm2835_system_reset; 676 cpu_reset_address = bcm2835_system_reset;
672 677
673#ifdef VERBOSE_INIT_ARM 678#ifdef VERBOSE_INIT_ARM
674 printf("done.\n"); 679 printf("done.\n");
675#endif 680#endif
676 681
677#ifdef KGDB 682#ifdef KGDB
678 kgdb_port_init(); 683 kgdb_port_init();
679#endif 684#endif
680 685
681#ifdef __HAVE_MEMORY_DISK__ 686#ifdef __HAVE_MEMORY_DISK__
682 md_root_setconf(memory_disk, sizeof memory_disk); 687 md_root_setconf(memory_disk, sizeof memory_disk);
683#endif 688#endif
684 689
685 if (vcprop_tag_success_p(&vb.vbt_cmdline.tag)) 690 if (vcprop_tag_success_p(&vb.vbt_cmdline.tag))
686 strlcpy(bootargs, vb.vbt_cmdline.cmdline, sizeof(bootargs)); 691 strlcpy(bootargs, vb.vbt_cmdline.cmdline, sizeof(bootargs));
687 boot_args = bootargs; 692 boot_args = bootargs;
688 parse_mi_bootargs(boot_args); 693 parse_mi_bootargs(boot_args);
689 694
690#ifdef BOOTHOWTO 695#ifdef BOOTHOWTO
691 boothowto |= BOOTHOWTO; 696 boothowto |= BOOTHOWTO;
692#endif 697#endif
693 698
694 /* we've a specific device_register routine */ 699 /* we've a specific device_register routine */
695 evbarm_device_register = rpi_device_register; 700 evbarm_device_register = rpi_device_register;
696 701
697 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); 702 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
698} 703}
699 704
700void 705void
701consinit(void) 706consinit(void)
702{ 707{
703 static int consinit_called = 0; 708 static int consinit_called = 0;
704 709
705 if (consinit_called != 0) 710 if (consinit_called != 0)
706 return; 711 return;
707 712
708 consinit_called = 1; 713 consinit_called = 1;
709 714
710#if (NPLCOM > 0 && defined(PLCONSOLE)) 715#if (NPLCOM > 0 && defined(PLCONSOLE))
711 /* 716 /*
712 * Initialise the diagnostic serial console 717 * Initialise the diagnostic serial console
713 * This allows a means of generating output during initarm(). 718 * This allows a means of generating output during initarm().
714 */ 719 */
715 rpi_pi.pi_iobase = consaddr; 720 rpi_pi.pi_iobase = consaddr;
716 721
717 plcomcnattach(&rpi_pi, plcomcnspeed, BCM2835_UART0_CLK, 722 plcomcnattach(&rpi_pi, plcomcnspeed, BCM2835_UART0_CLK,
718 plcomcnmode, PLCOMCNUNIT); 723 plcomcnmode, PLCOMCNUNIT);
719 724
720#endif 725#endif
721} 726}
722 727
723#ifdef KGDB 728#ifdef KGDB
724#if !defined(KGDB_PLCOMUNIT) || !defined(KGDB_DEVRATE) || !defined(KGDB_CONMODE) 729#if !defined(KGDB_PLCOMUNIT) || !defined(KGDB_DEVRATE) || !defined(KGDB_CONMODE)
725#error Specify KGDB_PLCOMUNIT, KGDB_DEVRATE and KGDB_CONMODE for KGDB. 730#error Specify KGDB_PLCOMUNIT, KGDB_DEVRATE and KGDB_CONMODE for KGDB.
726#endif 731#endif
727 732
728void 733void
729static kgdb_port_init(void) 734static kgdb_port_init(void)
730{ 735{
731 static int kgdbsinit_called = 0; 736 static int kgdbsinit_called = 0;
732 int res; 737 int res;
733 738
734 if (kgdbsinit_called != 0) 739 if (kgdbsinit_called != 0)
735 return; 740 return;
736 741
737 kgdbsinit_called = 1; 742 kgdbsinit_called = 1;
738 743
739 rpi_pi.pi_iobase = consaddr; 744 rpi_pi.pi_iobase = consaddr;
740 745
741 res = plcom_kgdb_attach(&rpi_pi, KGDB_DEVRATE, BCM2835_UART0_CLK, 746 res = plcom_kgdb_attach(&rpi_pi, KGDB_DEVRATE, BCM2835_UART0_CLK,
742 KGDB_CONMODE, KGDB_PLCOMUNIT); 747 KGDB_CONMODE, KGDB_PLCOMUNIT);
743 if (res) 748 if (res)
744 panic("KGDB uart can not be initialized, err=%d.", res); 749 panic("KGDB uart can not be initialized, err=%d.", res);
745} 750}
746#endif 751#endif
747 752
748#if NGENFB > 0 753#if NGENFB > 0
749static bool 754static bool
750rpi_fb_parse_mode(const char *s, uint32_t *pwidth, uint32_t *pheight) 755rpi_fb_parse_mode(const char *s, uint32_t *pwidth, uint32_t *pheight)
751{ 756{
752 char *x; 757 char *x;
753 758
754 if (strncmp(s, "disable", 7) == 0) 759 if (strncmp(s, "disable", 7) == 0)
755 return false; 760 return false;
756 761
757 x = strchr(s, 'x'); 762 x = strchr(s, 'x');
758 if (x) { 763 if (x) {
759 *pwidth = strtoul(s, NULL, 10); 764 *pwidth = strtoul(s, NULL, 10);
760 *pheight = strtoul(x + 1, NULL, 10); 765 *pheight = strtoul(x + 1, NULL, 10);
761 } 766 }
762 767
763 return true; 768 return true;
764} 769}
765 770
766static bool 771static bool
767rpi_fb_get_edid_mode(uint32_t *pwidth, uint32_t *pheight) 772rpi_fb_get_edid_mode(uint32_t *pwidth, uint32_t *pheight)
768{ 773{
769 struct edid_info ei; 774 struct edid_info ei;
770 uint8_t edid_data[1024]; 775 uint8_t edid_data[1024];
771 uint32_t res; 776 uint32_t res;
772 int error; 777 int error;
773 778
774 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_edid, 779 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_edid,
775 sizeof(vb_edid), &res); 780 sizeof(vb_edid), &res);
776 if (error) { 781 if (error) {
777 printf("%s: mbox request failed (%d)\n", __func__, error); 782 printf("%s: mbox request failed (%d)\n", __func__, error);
778 return false; 783 return false;
779 } 784 }
780 785
781 if (!vcprop_buffer_success_p(&vb_edid.vb_hdr) || 786 if (!vcprop_buffer_success_p(&vb_edid.vb_hdr) ||
782 !vcprop_tag_success_p(&vb_edid.vbt_edid.tag) || 787 !vcprop_tag_success_p(&vb_edid.vbt_edid.tag) ||
783 vb_edid.vbt_edid.status != 0) 788 vb_edid.vbt_edid.status != 0)
784 return false; 789 return false;
785 790
786 memset(edid_data, 0, sizeof(edid_data)); 791 memset(edid_data, 0, sizeof(edid_data));
787 memcpy(edid_data, vb_edid.vbt_edid.data, 792 memcpy(edid_data, vb_edid.vbt_edid.data,
788 sizeof(vb_edid.vbt_edid.data)); 793 sizeof(vb_edid.vbt_edid.data));
789 edid_parse(edid_data, &ei); 794 edid_parse(edid_data, &ei);
790#ifdef VERBOSE_INIT_ARM 795#ifdef VERBOSE_INIT_ARM
791 edid_print(&ei); 796 edid_print(&ei);
792#endif 797#endif
793 798
794 if (ei.edid_preferred_mode) { 799 if (ei.edid_preferred_mode) {
795 *pwidth = ei.edid_preferred_mode->hdisplay; 800 *pwidth = ei.edid_preferred_mode->hdisplay;
796 *pheight = ei.edid_preferred_mode->vdisplay; 801 *pheight = ei.edid_preferred_mode->vdisplay;
797 } 802 }
798 803
799 return true; 804 return true;
800} 805}
801 806
802/* 807/*
803 * Initialize framebuffer console. 808 * Initialize framebuffer console.
804 * 809 *
805 * Some notes about boot parameters: 810 * Some notes about boot parameters:
806 * - If "fb=disable" is present, ignore framebuffer completely. 811 * - If "fb=disable" is present, ignore framebuffer completely.
807 * - If "fb=<width>x<height> is present, use the specified mode. 812 * - If "fb=<width>x<height> is present, use the specified mode.
808 * - If "console=fb" is present, attach framebuffer to console. 813 * - If "console=fb" is present, attach framebuffer to console.
809 */ 814 */
810static bool 815static bool
811rpi_fb_init(prop_dictionary_t dict, void *aux) 816rpi_fb_init(prop_dictionary_t dict, void *aux)
812{ 817{
813 uint32_t width = 0, height = 0; 818 uint32_t width = 0, height = 0;
814 uint32_t res; 819 uint32_t res;
815 char *ptr; 820 char *ptr;
816 int integer; 821 int integer;
817 int error; 822 int error;
818 bool is_bgr = true; 823 bool is_bgr = true;
819 824
820 if (get_bootconf_option(boot_args, "fb", 825 if (get_bootconf_option(boot_args, "fb",
821 BOOTOPT_TYPE_STRING, &ptr)) { 826 BOOTOPT_TYPE_STRING, &ptr)) {
822 if (rpi_fb_parse_mode(ptr, &width, &height) == false) 827 if (rpi_fb_parse_mode(ptr, &width, &height) == false)
823 return false; 828 return false;
824 } 829 }
825 if (width == 0 || height == 0) { 830 if (width == 0 || height == 0) {
826 rpi_fb_get_edid_mode(&width, &height); 831 rpi_fb_get_edid_mode(&width, &height);
827 } 832 }
828 if (width == 0 || height == 0) { 833 if (width == 0 || height == 0) {
829 width = RPI_FB_WIDTH; 834 width = RPI_FB_WIDTH;
830 height = RPI_FB_HEIGHT; 835 height = RPI_FB_HEIGHT;
831 } 836 }
832 837
833 vb_setfb.vbt_res.width = width; 838 vb_setfb.vbt_res.width = width;
834 vb_setfb.vbt_res.height = height; 839 vb_setfb.vbt_res.height = height;
835 vb_setfb.vbt_vres.width = width; 840 vb_setfb.vbt_vres.width = width;
836 vb_setfb.vbt_vres.height = height; 841 vb_setfb.vbt_vres.height = height;
837 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setfb, 842 error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setfb,
838 sizeof(vb_setfb), &res); 843 sizeof(vb_setfb), &res);
839 if (error) { 844 if (error) {
840 printf("%s: mbox request failed (%d)\n", __func__, error); 845 printf("%s: mbox request failed (%d)\n", __func__, error);
841 return false; 846 return false;
842 } 847 }
843 848
844 if (!vcprop_buffer_success_p(&vb_setfb.vb_hdr) || 849 if (!vcprop_buffer_success_p(&vb_setfb.vb_hdr) ||
845 !vcprop_tag_success_p(&vb_setfb.vbt_res.tag) || 850 !vcprop_tag_success_p(&vb_setfb.vbt_res.tag) ||
846 !vcprop_tag_success_p(&vb_setfb.vbt_vres.tag) || 851 !vcprop_tag_success_p(&vb_setfb.vbt_vres.tag) ||
847 !vcprop_tag_success_p(&vb_setfb.vbt_depth.tag) || 852 !vcprop_tag_success_p(&vb_setfb.vbt_depth.tag) ||
848 !vcprop_tag_success_p(&vb_setfb.vbt_allocbuf.tag) || 853 !vcprop_tag_success_p(&vb_setfb.vbt_allocbuf.tag) ||
849 !vcprop_tag_success_p(&vb_setfb.vbt_blank.tag) || 854 !vcprop_tag_success_p(&vb_setfb.vbt_blank.tag) ||
850 !vcprop_tag_success_p(&vb_setfb.vbt_pitch.tag)) { 855 !vcprop_tag_success_p(&vb_setfb.vbt_pitch.tag)) {
851 printf("%s: prop tag failed\n", __func__); 856 printf("%s: prop tag failed\n", __func__);
852 return false; 857 return false;
853 } 858 }
854 859
855#ifdef VERBOSE_INIT_ARM 860#ifdef VERBOSE_INIT_ARM
856 printf("%s: addr = 0x%x size = %d\n", __func__, 861 printf("%s: addr = 0x%x size = %d\n", __func__,
857 vb_setfb.vbt_allocbuf.address, 862 vb_setfb.vbt_allocbuf.address,
858 vb_setfb.vbt_allocbuf.size); 863 vb_setfb.vbt_allocbuf.size);
859 printf("%s: depth = %d\n", __func__, vb_setfb.vbt_depth.bpp); 864 printf("%s: depth = %d\n", __func__, vb_setfb.vbt_depth.bpp);
860 printf("%s: pitch = %d\n", __func__, 865 printf("%s: pitch = %d\n", __func__,
861 vb_setfb.vbt_pitch.linebytes); 866 vb_setfb.vbt_pitch.linebytes);
862 printf("%s: width = %d height = %d\n", __func__, 867 printf("%s: width = %d height = %d\n", __func__,
863 vb_setfb.vbt_res.width, vb_setfb.vbt_res.height); 868 vb_setfb.vbt_res.width, vb_setfb.vbt_res.height);
864 printf("%s: vwidth = %d vheight = %d\n", __func__, 869 printf("%s: vwidth = %d vheight = %d\n", __func__,
865 vb_setfb.vbt_vres.width, vb_setfb.vbt_vres.height); 870 vb_setfb.vbt_vres.width, vb_setfb.vbt_vres.height);
866#endif 871#endif
867 872
868 if (vb_setfb.vbt_allocbuf.address == 0 || 873 if (vb_setfb.vbt_allocbuf.address == 0 ||
869 vb_setfb.vbt_allocbuf.size == 0 || 874 vb_setfb.vbt_allocbuf.size == 0 ||
870 vb_setfb.vbt_res.width == 0 || 875 vb_setfb.vbt_res.width == 0 ||
871 vb_setfb.vbt_res.height == 0 || 876 vb_setfb.vbt_res.height == 0 ||
872 vb_setfb.vbt_vres.width == 0 || 877 vb_setfb.vbt_vres.width == 0 ||
873 vb_setfb.vbt_vres.height == 0 || 878 vb_setfb.vbt_vres.height == 0 ||
874 vb_setfb.vbt_pitch.linebytes == 0) { 879 vb_setfb.vbt_pitch.linebytes == 0) {
875 printf("%s: failed to set mode %ux%u\n", __func__, 880 printf("%s: failed to set mode %ux%u\n", __func__,
876 width, height); 881 width, height);
877 return false; 882 return false;
878 } 883 }
879 884
880 prop_dictionary_set_uint32(dict, "width", vb_setfb.vbt_res.width); 885 prop_dictionary_set_uint32(dict, "width", vb_setfb.vbt_res.width);
881 prop_dictionary_set_uint32(dict, "height", vb_setfb.vbt_res.height); 886 prop_dictionary_set_uint32(dict, "height", vb_setfb.vbt_res.height);
882 prop_dictionary_set_uint8(dict, "depth", vb_setfb.vbt_depth.bpp); 887 prop_dictionary_set_uint8(dict, "depth", vb_setfb.vbt_depth.bpp);
883 prop_dictionary_set_uint16(dict, "linebytes", 888 prop_dictionary_set_uint16(dict, "linebytes",
884 vb_setfb.vbt_pitch.linebytes); 889 vb_setfb.vbt_pitch.linebytes);
885 prop_dictionary_set_uint32(dict, "address", 890 prop_dictionary_set_uint32(dict, "address",
886 vb_setfb.vbt_allocbuf.address); 891 vb_setfb.vbt_allocbuf.address);
887 892
888 /* 893 /*
889 * Old firmware uses BGR. New firmware uses RGB. The get and set 894 * Old firmware uses BGR. New firmware uses RGB. The get and set
890 * pixel order mailbox properties don't seem to work. The firmware 895 * pixel order mailbox properties don't seem to work. The firmware
891 * adds a kernel cmdline option bcm2708_fb.fbswap=<0|1>, so use it 896 * adds a kernel cmdline option bcm2708_fb.fbswap=<0|1>, so use it
892 * to determine pixel order. 0 means BGR, 1 means RGB. 897 * to determine pixel order. 0 means BGR, 1 means RGB.
893 * 898 *
894 * See https://github.com/raspberrypi/linux/issues/514 899 * See https://github.com/raspberrypi/linux/issues/514
895 */ 900 */
896 if (get_bootconf_option(boot_args, "bcm2708_fb.fbswap", 901 if (get_bootconf_option(boot_args, "bcm2708_fb.fbswap",
897 BOOTOPT_TYPE_INT, &integer)) { 902 BOOTOPT_TYPE_INT, &integer)) {
898 is_bgr = integer == 0; 903 is_bgr = integer == 0;
899 } 904 }
900 prop_dictionary_set_bool(dict, "is_bgr", is_bgr); 905 prop_dictionary_set_bool(dict, "is_bgr", is_bgr);
901 906
902 /* if "genfb.type=<n>" is passed in cmdline, override wsdisplay type */ 907 /* if "genfb.type=<n>" is passed in cmdline, override wsdisplay type */
903 if (get_bootconf_option(boot_args, "genfb.type", 908 if (get_bootconf_option(boot_args, "genfb.type",
904 BOOTOPT_TYPE_INT, &integer)) { 909 BOOTOPT_TYPE_INT, &integer)) {
905 prop_dictionary_set_uint32(dict, "wsdisplay_type", integer); 910 prop_dictionary_set_uint32(dict, "wsdisplay_type", integer);
906 } 911 }
907 912
908#if defined(RPI_HWCURSOR) 913#if defined(RPI_HWCURSOR)
909 struct amba_attach_args *aaa = aux; 914 struct amba_attach_args *aaa = aux;
910 bus_space_handle_t hc; 915 bus_space_handle_t hc;
911 916
912 hcursor = rpi_alloc_mem(CURSOR_ARGB_SIZE, PAGE_SIZE, 917 hcursor = rpi_alloc_mem(CURSOR_ARGB_SIZE, PAGE_SIZE,
913 MEM_FLAG_L1_NONALLOCATING | MEM_FLAG_HINT_PERMALOCK); 918 MEM_FLAG_L1_NONALLOCATING | MEM_FLAG_HINT_PERMALOCK);
914 pcursor = rpi_lock_mem(hcursor); 919 pcursor = rpi_lock_mem(hcursor);
915#ifdef RPI_IOCTL_DEBUG 920#ifdef RPI_IOCTL_DEBUG
916 printf("hcursor: %08x\n", hcursor); 921 printf("hcursor: %08x\n", hcursor);
917 printf("pcursor: %08x\n", (uint32_t)pcursor); 922 printf("pcursor: %08x\n", (uint32_t)pcursor);
918 printf("fb: %08x\n", (uint32_t)vb_setfb.vbt_allocbuf.address); 923 printf("fb: %08x\n", (uint32_t)vb_setfb.vbt_allocbuf.address);
919#endif 924#endif
920 if (bus_space_map(aaa->aaa_iot, pcursor, CURSOR_ARGB_SIZE, 925 if (bus_space_map(aaa->aaa_iot, pcursor, CURSOR_ARGB_SIZE,
921 BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE, &hc) != 0) { 926 BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE, &hc) != 0) {
922 printf("couldn't map cursor memory\n"); 927 printf("couldn't map cursor memory\n");
923 } else { 928 } else {
924 int i, j, k; 929 int i, j, k;
925 930
926 cmem = bus_space_vaddr(aaa->aaa_iot, hc); 931 cmem = bus_space_vaddr(aaa->aaa_iot, hc);
927 k = 0; 932 k = 0;
928 for (j = 0; j < 64; j++) { 933 for (j = 0; j < 64; j++) {
929 for (i = 0; i < 64; i++) { 934 for (i = 0; i < 64; i++) {
930 cmem[i + k] = 935 cmem[i + k] =
931 ((i & 8) ^ (j & 8)) ? 0xa0ff0000 : 0xa000ff00; 936 ((i & 8) ^ (j & 8)) ? 0xa0ff0000 : 0xa000ff00;
932 } 937 }
933 k += 64; 938 k += 64;
934 } 939 }
935 cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE); 940 cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE);
936 rpi_fb_initcursor(pcursor, 0, 0); 941 rpi_fb_initcursor(pcursor, 0, 0);
937#ifdef RPI_IOCTL_DEBUG 942#ifdef RPI_IOCTL_DEBUG
938 rpi_fb_movecursor(600, 400, 1); 943 rpi_fb_movecursor(600, 400, 1);
939#else 944#else
940 rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); 945 rpi_fb_movecursor(cursor_x, cursor_y, cursor_on);
941#endif 946#endif
942 } 947 }
943#endif 948#endif
944 949
945 return true; 950 return true;
946} 951}
947 952
948 953
949#if defined(RPI_HWCURSOR) 954#if defined(RPI_HWCURSOR)
950static int 955static int
951rpi_fb_do_cursor(struct wsdisplay_cursor *cur) 956rpi_fb_do_cursor(struct wsdisplay_cursor *cur)
952{ 957{
953 int pos = 0; 958 int pos = 0;
954 int shape = 0; 959 int shape = 0;
955 960
956 if (cur->which & WSDISPLAY_CURSOR_DOCUR) { 961 if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
957 if (cursor_on != cur->enable) { 962 if (cursor_on != cur->enable) {
958 cursor_on = cur->enable; 963 cursor_on = cur->enable;
959 pos = 1; 964 pos = 1;
960 } 965 }
961 } 966 }
962 if (cur->which & WSDISPLAY_CURSOR_DOHOT) { 967 if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
963 968
964 hot_x = cur->hot.x; 969 hot_x = cur->hot.x;
965 hot_y = cur->hot.y; 970 hot_y = cur->hot.y;
966 pos = 1; 971 pos = 1;
967 shape = 1; 972 shape = 1;
968 } 973 }
969 if (cur->which & WSDISPLAY_CURSOR_DOPOS) { 974 if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
970 975
971 cursor_x = cur->pos.x; 976 cursor_x = cur->pos.x;
972 cursor_y = cur->pos.y; 977 cursor_y = cur->pos.y;
973 pos = 1; 978 pos = 1;
974 } 979 }
975 if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { 980 if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
976 int i; 981 int i;
977 uint32_t val; 982 uint32_t val;
978 983
979 for (i = 0; i < min(cur->cmap.count, 3); i++) { 984 for (i = 0; i < min(cur->cmap.count, 3); i++) {
980 val = (cur->cmap.red[i] << 16 ) | 985 val = (cur->cmap.red[i] << 16 ) |
981 (cur->cmap.green[i] << 8) | 986 (cur->cmap.green[i] << 8) |
982 (cur->cmap.blue[i] ) | 987 (cur->cmap.blue[i] ) |
983 0xff000000; 988 0xff000000;
984 cursor_cmap[i + cur->cmap.index + 2] = val; 989 cursor_cmap[i + cur->cmap.index + 2] = val;
985 } 990 }
986 shape = 1; 991 shape = 1;
987 } 992 }
988 if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { 993 if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
989 int err; 994 int err;
990 995
991 err = copyin(cur->mask, cursor_mask, CURSOR_BITMAP_SIZE); 996 err = copyin(cur->mask, cursor_mask, CURSOR_BITMAP_SIZE);
992 err += copyin(cur->image, cursor_bitmap, CURSOR_BITMAP_SIZE); 997 err += copyin(cur->image, cursor_bitmap, CURSOR_BITMAP_SIZE);
993 if (err != 0) 998 if (err != 0)
994 return EFAULT; 999 return EFAULT;
995 shape = 1; 1000 shape = 1;
996 } 1001 }
997 if (shape) { 1002 if (shape) {
998 int i, j, idx; 1003 int i, j, idx;
999 uint8_t mask; 1004 uint8_t mask;
1000 1005
1001 for (i = 0; i < CURSOR_BITMAP_SIZE; i++) { 1006 for (i = 0; i < CURSOR_BITMAP_SIZE; i++) {
1002 mask = 0x01; 1007 mask = 0x01;
1003 for (j = 0; j < 8; j++) { 1008 for (j = 0; j < 8; j++) {
1004 idx = ((cursor_mask[i] & mask) ? 2 : 0) | 1009 idx = ((cursor_mask[i] & mask) ? 2 : 0) |
1005 ((cursor_bitmap[i] & mask) ? 1 : 0); 1010 ((cursor_bitmap[i] & mask) ? 1 : 0);
1006 cmem[i * 8 + j] = cursor_cmap[idx]; 1011 cmem[i * 8 + j] = cursor_cmap[idx];
1007 mask = mask << 1; 1012 mask = mask << 1;
1008 } 1013 }
1009 } 1014 }
1010 /* just in case */ 1015 /* just in case */
1011 cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE); 1016 cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE);
1012 rpi_fb_initcursor(pcursor, hot_x, hot_y); 1017 rpi_fb_initcursor(pcursor, hot_x, hot_y);
1013 } 1018 }
1014 if (pos) { 1019 if (pos) {
1015 rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); 1020 rpi_fb_movecursor(cursor_x, cursor_y, cursor_on);
1016 } 1021 }
1017 return 0; 1022 return 0;
1018} 1023}
1019#endif 1024#endif
1020 1025
1021static int 1026static int
1022rpi_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l) 1027rpi_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l)
1023{ 1028{
1024 1029
1025 switch (cmd) { 1030 switch (cmd) {
1026 case WSDISPLAYIO_SVIDEO: 1031 case WSDISPLAYIO_SVIDEO:
1027 { 1032 {
1028 int d = *(int *)data; 1033 int d = *(int *)data;
1029 if (d == rpi_video_on) 1034 if (d == rpi_video_on)
1030 return 0; 1035 return 0;
1031 rpi_video_on = d; 1036 rpi_video_on = d;
1032 rpi_fb_set_video(d); 1037 rpi_fb_set_video(d);
1033#if defined(RPI_HWCURSOR) 1038#if defined(RPI_HWCURSOR)
1034 rpi_fb_movecursor(cursor_x, cursor_y, 1039 rpi_fb_movecursor(cursor_x, cursor_y,
1035 d ? cursor_on : 0); 1040 d ? cursor_on : 0);
1036#endif 1041#endif
1037 } 1042 }
1038 return 0; 1043 return 0;
1039 case WSDISPLAYIO_GVIDEO: 1044 case WSDISPLAYIO_GVIDEO:
1040 *(int *)data = rpi_video_on; 1045 *(int *)data = rpi_video_on;
1041 return 0; 1046 return 0;
1042#if defined(RPI_HWCURSOR) 1047#if defined(RPI_HWCURSOR)
1043 case WSDISPLAYIO_GCURPOS: 1048 case WSDISPLAYIO_GCURPOS:
1044 { 1049 {
1045 struct wsdisplay_curpos *cp = (void *)data; 1050 struct wsdisplay_curpos *cp = (void *)data;
1046 1051
1047 cp->x = cursor_x; 1052 cp->x = cursor_x;
1048 cp->y = cursor_y; 1053 cp->y = cursor_y;
1049 } 1054 }
1050 return 0; 1055 return 0;
1051 case WSDISPLAYIO_SCURPOS: 1056 case WSDISPLAYIO_SCURPOS:
1052 { 1057 {
1053 struct wsdisplay_curpos *cp = (void *)data; 1058 struct wsdisplay_curpos *cp = (void *)data;
1054 1059
1055 cursor_x = cp->x; 1060 cursor_x = cp->x;
1056 cursor_y = cp->y; 1061 cursor_y = cp->y;
1057 rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); 1062 rpi_fb_movecursor(cursor_x, cursor_y, cursor_on);
1058 } 1063 }
1059 return 0; 1064 return 0;
1060 case WSDISPLAYIO_GCURMAX: 1065 case WSDISPLAYIO_GCURMAX:
1061 { 1066 {
1062 struct wsdisplay_curpos *cp = (void *)data; 1067 struct wsdisplay_curpos *cp = (void *)data;
1063 1068
1064 cp->x = 64; 1069 cp->x = 64;
1065 cp->y = 64; 1070 cp->y = 64;
1066 } 1071 }
1067 return 0; 1072 return 0;
1068 case WSDISPLAYIO_SCURSOR: 1073 case WSDISPLAYIO_SCURSOR:
1069 { 1074 {
1070 struct wsdisplay_cursor *cursor = (void *)data; 1075 struct wsdisplay_cursor *cursor = (void *)data;
1071 1076
1072 return rpi_fb_do_cursor(cursor); 1077 return rpi_fb_do_cursor(cursor);
1073 } 1078 }
1074#endif 1079#endif
1075 default: 1080 default:
1076 return EPASSTHROUGH; 1081 return EPASSTHROUGH;
1077 } 1082 }
1078} 1083}
1079 1084
1080#endif 1085#endif
1081 1086
1082static void 1087static void
1083rpi_device_register(device_t dev, void *aux) 1088rpi_device_register(device_t dev, void *aux)
1084{ 1089{
1085 prop_dictionary_t dict = device_properties(dev); 1090 prop_dictionary_t dict = device_properties(dev);
1086 1091
1087#if defined(BCM2836) 1092#if defined(BCM2836)
1088 if (device_is_a(dev, "armgtmr")) { 1093 if (device_is_a(dev, "armgtmr")) {
1089 /* 1094 /*
1090 * The frequency of the generic timer is the reference 1095 * The frequency of the generic timer is the reference
1091 * frequency. 1096 * frequency.
1092 */ 1097 */
1093 prop_dictionary_set_uint32(dict, "frequency", RPI_REF_FREQ); 1098 prop_dictionary_set_uint32(dict, "frequency", RPI_REF_FREQ);
1094 return; 1099 return;
1095 } 1100 }
1096#endif 1101#endif
1097 1102
1098 if (device_is_a(dev, "bcmdmac") && 1103 if (device_is_a(dev, "bcmdmac") &&
1099 vcprop_tag_success_p(&vb.vbt_dmachan.tag)) { 1104 vcprop_tag_success_p(&vb.vbt_dmachan.tag)) {
1100 prop_dictionary_set_uint32(dict, 1105 prop_dictionary_set_uint32(dict,
1101 "chanmask", vb.vbt_dmachan.mask); 1106 "chanmask", vb.vbt_dmachan.mask);
1102 } 1107 }
1103#if NSDHC > 0 1108#if NSDHC > 0
1104 if (device_is_a(dev, "sdhc") && 1109 if (device_is_a(dev, "sdhc") &&
1105 vcprop_tag_success_p(&vb.vbt_emmcclockrate.tag) && 1110 vcprop_tag_success_p(&vb.vbt_emmcclockrate.tag) &&
1106 vb.vbt_emmcclockrate.rate > 0) { 1111 vb.vbt_emmcclockrate.rate > 0) {
1107 prop_dictionary_set_uint32(dict, 1112 prop_dictionary_set_uint32(dict,
1108 "frequency", vb.vbt_emmcclockrate.rate); 1113 "frequency", vb.vbt_emmcclockrate.rate);
1109 } 1114 }
1110 if (booted_device == NULL && 1115 if (booted_device == NULL &&
1111 device_is_a(dev, "ld") && 1116 device_is_a(dev, "ld") &&
1112 device_is_a(device_parent(dev), "sdmmc")) { 1117 device_is_a(device_parent(dev), "sdmmc")) {
1113 booted_partition = 0; 1118 booted_partition = 0;
1114 booted_device = dev; 1119 booted_device = dev;
1115 } 1120 }
1116#endif 1121#endif
1117 if (device_is_a(dev, "usmsc") && 1122 if (device_is_a(dev, "usmsc") &&
1118 vcprop_tag_success_p(&vb.vbt_macaddr.tag)) { 1123 vcprop_tag_success_p(&vb.vbt_macaddr.tag)) {
1119 const uint8_t enaddr[ETHER_ADDR_LEN] = { 1124 const uint8_t enaddr[ETHER_ADDR_LEN] = {
1120 (vb.vbt_macaddr.addr >> 0) & 0xff, 1125 (vb.vbt_macaddr.addr >> 0) & 0xff,
1121 (vb.vbt_macaddr.addr >> 8) & 0xff, 1126 (vb.vbt_macaddr.addr >> 8) & 0xff,
1122 (vb.vbt_macaddr.addr >> 16) & 0xff, 1127 (vb.vbt_macaddr.addr >> 16) & 0xff,
1123 (vb.vbt_macaddr.addr >> 24) & 0xff, 1128 (vb.vbt_macaddr.addr >> 24) & 0xff,
1124 (vb.vbt_macaddr.addr >> 32) & 0xff, 1129 (vb.vbt_macaddr.addr >> 32) & 0xff,
1125 (vb.vbt_macaddr.addr >> 40) & 0xff 1130 (vb.vbt_macaddr.addr >> 40) & 0xff
1126 }; 1131 };
1127 1132
1128 prop_data_t pd = prop_data_create_data(enaddr, ETHER_ADDR_LEN); 1133 prop_data_t pd = prop_data_create_data(enaddr, ETHER_ADDR_LEN);
1129 KASSERT(pd != NULL); 1134 KASSERT(pd != NULL);
1130 if (prop_dictionary_set(device_properties(dev), "mac-address", 1135 if (prop_dictionary_set(device_properties(dev), "mac-address",
1131 pd) == false) { 1136 pd) == false) {
1132 aprint_error_dev(dev, 1137 aprint_error_dev(dev,
1133 "WARNING: Unable to set mac-address property\n"); 1138 "WARNING: Unable to set mac-address property\n");
1134 } 1139 }
1135 prop_object_release(pd); 1140 prop_object_release(pd);
1136 } 1141 }
1137 1142
1138#if NGENFB > 0 1143#if NGENFB > 0
1139 if (device_is_a(dev, "genfb")) { 1144 if (device_is_a(dev, "genfb")) {
1140 char *ptr; 1145 char *ptr;
1141 1146
1142 bcmgenfb_set_console_dev(dev); 1147 bcmgenfb_set_console_dev(dev);
1143 bcmgenfb_set_ioctl(&rpi_ioctl); 1148 bcmgenfb_set_ioctl(&rpi_ioctl);
1144#ifdef DDB 1149#ifdef DDB
1145 db_trap_callback = bcmgenfb_ddb_trap_callback; 1150 db_trap_callback = bcmgenfb_ddb_trap_callback;
1146#endif 1151#endif
1147 1152
1148 if (rpi_fb_init(dict, aux) == false) 1153 if (rpi_fb_init(dict, aux) == false)
1149 return; 1154 return;
1150 if (get_bootconf_option(boot_args, "console", 1155 if (get_bootconf_option(boot_args, "console",
1151 BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) { 1156 BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) {
1152 prop_dictionary_set_bool(dict, "is_console", true); 1157 prop_dictionary_set_bool(dict, "is_console", true);
1153#if NUKBD > 0 1158#if NUKBD > 0
1154 /* allow ukbd to be the console keyboard */ 1159 /* allow ukbd to be the console keyboard */
1155 ukbd_cnattach(); 1160 ukbd_cnattach();
1156#endif 1161#endif
1157 } else { 1162 } else {
1158 prop_dictionary_set_bool(dict, "is_console", false); 1163 prop_dictionary_set_bool(dict, "is_console", false);
1159 } 1164 }
1160 } 1165 }
1161#endif 1166#endif
1162} 1167}
1163 1168
1164SYSCTL_SETUP(sysctl_machdep_rpi, "sysctl machdep subtree setup (rpi)") 1169SYSCTL_SETUP(sysctl_machdep_rpi, "sysctl machdep subtree setup (rpi)")
1165{ 1170{
1166 sysctl_createv(clog, 0, NULL, NULL, 1171 sysctl_createv(clog, 0, NULL, NULL,
1167 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 1172 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
1168 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); 1173 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
1169 1174
1170 sysctl_createv(clog, 0, NULL, NULL, 1175 sysctl_createv(clog, 0, NULL, NULL,
1171 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 1176 CTLFLAG_PERMANENT|CTLFLAG_READONLY,
1172 CTLTYPE_INT, "firmware_revision", NULL, NULL, 0, 1177 CTLTYPE_INT, "firmware_revision", NULL, NULL, 0,
1173 &vb.vbt_fwrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 1178 &vb.vbt_fwrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1174 1179
1175 sysctl_createv(clog, 0, NULL, NULL, 1180 sysctl_createv(clog, 0, NULL, NULL,
1176 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 1181 CTLFLAG_PERMANENT|CTLFLAG_READONLY,
1177 CTLTYPE_INT, "board_model", NULL, NULL, 0, 1182 CTLTYPE_INT, "board_model", NULL, NULL, 0,
1178 &vb.vbt_boardmodel.model, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 1183 &vb.vbt_boardmodel.model, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1179 1184
1180 sysctl_createv(clog, 0, NULL, NULL, 1185 sysctl_createv(clog, 0, NULL, NULL,
1181 CTLFLAG_PERMANENT|CTLFLAG_READONLY, 1186 CTLFLAG_PERMANENT|CTLFLAG_READONLY,
1182 CTLTYPE_INT, "board_revision", NULL, NULL, 0, 1187 CTLTYPE_INT, "board_revision", NULL, NULL, 0,
1183 &vb.vbt_boardrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 1188 &vb.vbt_boardrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1184 1189
1185 sysctl_createv(clog, 0, NULL, NULL, 1190 sysctl_createv(clog, 0, NULL, NULL,
1186 CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_HEX|CTLFLAG_PRIVATE, 1191 CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_HEX|CTLFLAG_PRIVATE,
1187 CTLTYPE_QUAD, "serial", NULL, NULL, 0, 1192 CTLTYPE_QUAD, "serial", NULL, NULL, 0,
1188 &vb.vbt_serial.sn, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 1193 &vb.vbt_serial.sn, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
1189} 1194}