]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bhnd/bhnd.c
tcpdump: remove undesired svn:keywords property from contrib
[FreeBSD/FreeBSD.git] / sys / dev / bhnd / bhnd.c
1 /*-
2  * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
3  * Copyright (c) 2017 The FreeBSD Foundation
4  * All rights reserved.
5  *
6  * Portions of this software were developed by Landon Fuller
7  * under sponsorship from the FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer,
14  *    without modification.
15  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
17  *    redistribution must be conditioned upon including a substantially
18  *    similar Disclaimer requirement for further binary redistribution.
19  *
20  * NO WARRANTY
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
24  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
26  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGES.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 /*
38  * Broadcom Home Networking Division (HND) Bus Driver.
39  * 
40  * The Broadcom HND family of devices consists of both SoCs and host-connected
41  * networking chipsets containing a common family of Broadcom IP cores,
42  * including an integrated MIPS and/or ARM cores.
43  * 
44  * HND devices expose a nearly identical interface whether accessible over a 
45  * native SoC interconnect, or when connected via a host interface such as 
46  * PCIe. As a result, the majority of hardware support code should be re-usable 
47  * across host drivers for HND networking chipsets, as well as FreeBSD support 
48  * for Broadcom MIPS/ARM HND SoCs.
49  * 
50  * Earlier HND models used the siba(4) on-chip interconnect, while later models
51  * use bcma(4); the programming model is almost entirely independent
52  * of the actual underlying interconect.
53  */
54
55 #include <sys/param.h>
56 #include <sys/kernel.h>
57 #include <sys/bus.h>
58 #include <sys/module.h>
59 #include <sys/systm.h>
60
61 #include <machine/bus.h>
62 #include <sys/rman.h>
63 #include <machine/resource.h>
64
65 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
66
67 #include "bhnd_chipc_if.h"
68 #include "bhnd_nvram_if.h"
69
70 #include "bhnd.h"
71 #include "bhndreg.h"
72 #include "bhndvar.h"
73
74 #include "bhnd_private.h"
75
76 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
77
78 /**
79  * bhnd_generic_probe_nomatch() reporting configuration.
80  */
81 static const struct bhnd_nomatch {
82         uint16_t        vendor;         /**< core designer */
83         uint16_t        device;         /**< core id */
84         bool            if_verbose;     /**< print when bootverbose is set. */
85 } bhnd_nomatch_table[] = {
86         { BHND_MFGID_ARM,       BHND_COREID_OOB_ROUTER,         true    },
87         { BHND_MFGID_ARM,       BHND_COREID_EROM,               true    },
88         { BHND_MFGID_ARM,       BHND_COREID_PL301,              true    },
89         { BHND_MFGID_ARM,       BHND_COREID_APB_BRIDGE,         true    },
90         { BHND_MFGID_ARM,       BHND_COREID_AXI_UNMAPPED,       false   },
91
92         { BHND_MFGID_INVALID,   BHND_COREID_INVALID,            false   }
93 };
94
95 static int                       bhnd_delete_children(struct bhnd_softc *sc);
96
97 /**
98  * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
99  *
100  * This implementation calls device_probe_and_attach() for each of the device's
101  * children, in bhnd probe order.
102  */
103 int
104 bhnd_generic_attach(device_t dev)
105 {
106         struct bhnd_softc       *sc;
107         int                      error;
108
109         if (device_is_attached(dev))
110                 return (EBUSY);
111
112         sc = device_get_softc(dev);
113         sc->dev = dev;
114
115         /* Probe and attach all children */
116         if ((error = bhnd_bus_probe_children(dev))) {
117                 bhnd_delete_children(sc);
118                 return (error);
119         }
120
121         return (0);
122 }
123
124 /**
125  * Detach and delete all children, in reverse of their attach order.
126  */
127 static int
128 bhnd_delete_children(struct bhnd_softc *sc)
129 {
130         device_t                *devs;
131         int                      ndevs;
132         int                      error;
133
134         /* Fetch children in detach order */
135         error = bhnd_bus_get_children(sc->dev, &devs, &ndevs,
136             BHND_DEVICE_ORDER_DETACH);
137         if (error)
138                 return (error);
139
140         /* Perform detach */
141         for (int i = 0; i < ndevs; i++) {
142                 device_t child = devs[i];
143
144                 /* Terminate on first error */
145                 if ((error = device_delete_child(sc->dev, child)))
146                         goto cleanup;
147         }
148
149 cleanup:
150         bhnd_bus_free_children(devs);
151         return (error);
152 }
153
154 /**
155  * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
156  *
157  * This implementation calls device_detach() for each of the device's
158  * children, in reverse bhnd probe order, terminating if any call to
159  * device_detach() fails.
160  */
161 int
162 bhnd_generic_detach(device_t dev)
163 {
164         struct bhnd_softc       *sc;
165         int                      error;
166
167         if (!device_is_attached(dev))
168                 return (EBUSY);
169
170         sc = device_get_softc(dev);
171
172         if ((error = bhnd_delete_children(sc)))
173                 return (error);
174
175         return (0);
176 }
177
178 /**
179  * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
180  * 
181  * This implementation calls device_shutdown() for each of the device's
182  * children, in reverse bhnd probe order, terminating if any call to
183  * device_shutdown() fails.
184  */
185 int
186 bhnd_generic_shutdown(device_t dev)
187 {
188         device_t        *devs;
189         int              ndevs;
190         int              error;
191
192         if (!device_is_attached(dev))
193                 return (EBUSY);
194
195         /* Fetch children in detach order */
196         error = bhnd_bus_get_children(dev, &devs, &ndevs,
197             BHND_DEVICE_ORDER_DETACH);
198         if (error)
199                 return (error);
200
201         /* Perform shutdown */
202         for (int i = 0; i < ndevs; i++) {
203                 device_t child = devs[i];
204
205                 /* Terminate on first error */
206                 if ((error = device_shutdown(child)))
207                         goto cleanup;
208         }
209
210 cleanup:
211         bhnd_bus_free_children(devs);
212         return (error);
213 }
214
215 /**
216  * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
217  *
218  * This implementation calls BUS_RESUME_CHILD() for each of the device's
219  * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
220  * fails.
221  */
222 int
223 bhnd_generic_resume(device_t dev)
224 {
225         device_t        *devs;
226         int              ndevs;
227         int              error;
228
229         if (!device_is_attached(dev))
230                 return (EBUSY);
231
232         /* Fetch children in attach order */
233         error = bhnd_bus_get_children(dev, &devs, &ndevs,
234             BHND_DEVICE_ORDER_ATTACH);
235         if (error)
236                 return (error);
237
238         /* Perform resume */
239         for (int i = 0; i < ndevs; i++) {
240                 device_t child = devs[i];
241
242                 /* Terminate on first error */
243                 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
244                         goto cleanup;
245         }
246
247 cleanup:
248         bhnd_bus_free_children(devs);
249         return (error);
250 }
251
252 /**
253  * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
254  *
255  * This implementation calls BUS_SUSPEND_CHILD() for each of the device's
256  * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
257  * fails, the suspend operation is terminated and any devices that were
258  * suspended are resumed immediately by calling their BUS_RESUME_CHILD()
259  * methods.
260  */
261 int
262 bhnd_generic_suspend(device_t dev)
263 {
264         device_t        *devs;
265         int              ndevs;
266         int              error;
267
268         if (!device_is_attached(dev))
269                 return (EBUSY);
270
271         /* Fetch children in detach order */
272         error = bhnd_bus_get_children(dev, &devs, &ndevs,
273             BHND_DEVICE_ORDER_DETACH);
274         if (error)
275                 return (error);
276
277         /* Perform suspend */
278         for (int i = 0; i < ndevs; i++) {
279                 device_t child = devs[i];
280                 error = BUS_SUSPEND_CHILD(device_get_parent(child), child);
281
282                 /* On error, resume suspended devices and then terminate */
283                 if (error) {
284                         for (int j = 0; j < i; j++) {
285                                 BUS_RESUME_CHILD(device_get_parent(devs[j]),
286                                     devs[j]);
287                         }
288
289                         goto cleanup;
290                 }
291         }
292
293 cleanup:
294         bhnd_bus_free_children(devs);
295         return (error);
296 }
297
298 /**
299  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
300  *
301  * This implementation determines probe ordering based on the device's class
302  * and other properties, including whether the device is serving as a host
303  * bridge.
304  */
305 int
306 bhnd_generic_get_probe_order(device_t dev, device_t child)
307 {
308         switch (bhnd_get_class(child)) {
309         case BHND_DEVCLASS_CC:
310                 /* Must be early enough to provide NVRAM access to the
311                  * host bridge */
312                 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST);
313
314         case BHND_DEVCLASS_CC_B:
315                 /* fall through */
316         case BHND_DEVCLASS_PMU:
317                 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY);
318
319         case BHND_DEVCLASS_SOC_ROUTER:
320                 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE);
321
322         case BHND_DEVCLASS_SOC_BRIDGE:
323                 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST);
324                 
325         case BHND_DEVCLASS_CPU:
326                 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST);
327
328         case BHND_DEVCLASS_RAM:
329                 /* fall through */
330         case BHND_DEVCLASS_MEMC:
331                 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY);
332                 
333         case BHND_DEVCLASS_NVRAM:
334                 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY);
335
336         case BHND_DEVCLASS_PCI:
337         case BHND_DEVCLASS_PCIE:
338         case BHND_DEVCLASS_PCCARD:
339         case BHND_DEVCLASS_ENET:
340         case BHND_DEVCLASS_ENET_MAC:
341         case BHND_DEVCLASS_ENET_PHY:
342         case BHND_DEVCLASS_WLAN:
343         case BHND_DEVCLASS_WLAN_MAC:
344         case BHND_DEVCLASS_WLAN_PHY:
345         case BHND_DEVCLASS_EROM:
346         case BHND_DEVCLASS_OTHER:
347         case BHND_DEVCLASS_INVALID:
348                 if (bhnd_bus_find_hostb_device(dev) == child)
349                         return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
350
351                 return (BHND_PROBE_DEFAULT);
352         default:
353                 return (BHND_PROBE_DEFAULT);
354         }
355 }
356
357 /**
358  * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU().
359  */
360 int
361 bhnd_generic_alloc_pmu(device_t dev, device_t child)
362 {
363         struct bhnd_softc               *sc;
364         struct bhnd_resource            *r;
365         struct bhnd_core_clkctl         *clkctl;
366         struct resource_list            *rl;
367         struct resource_list_entry      *rle;
368         device_t                         pmu_dev;
369         bhnd_addr_t                      r_addr;
370         bhnd_size_t                      r_size;
371         bus_size_t                       pmu_regs;
372         u_int                            max_latency;
373         int                              error;
374
375         GIANT_REQUIRED; /* for newbus */
376
377         if (device_get_parent(child) != dev)
378                 return (EINVAL);
379
380         sc = device_get_softc(dev);
381         clkctl = bhnd_get_pmu_info(child);
382         pmu_regs = BHND_CLK_CTL_ST;
383
384         /* already allocated? */
385         if (clkctl != NULL) {
386                 panic("duplicate PMU allocation for %s",
387                     device_get_nameunit(child));
388         }
389
390         /* Determine address+size of the core's PMU register block */
391         error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr,
392             &r_size);
393         if (error) {
394                 device_printf(sc->dev, "error fetching register block info for "
395                     "%s: %d\n", device_get_nameunit(child), error);
396                 return (error);
397         }
398
399         if (r_size < (pmu_regs + sizeof(uint32_t))) {
400                 device_printf(sc->dev, "pmu offset %#jx would overrun %s "
401                     "register block\n", (uintmax_t)pmu_regs,
402                     device_get_nameunit(child));
403                 return (ENODEV);
404         }
405
406         /* Locate actual resource containing the core's register block */
407         if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) {
408                 device_printf(dev, "NULL resource list returned for %s\n",
409                     device_get_nameunit(child));
410                 return (ENXIO);
411         }
412
413         if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) {
414                 device_printf(dev, "cannot locate core register resource "
415                     "for %s\n", device_get_nameunit(child));
416                 return (ENXIO);
417         }
418
419         if (rle->res == NULL) {
420                 device_printf(dev, "core register resource unallocated for "
421                     "%s\n", device_get_nameunit(child));
422                 return (ENXIO);
423         }
424
425         if (r_addr+pmu_regs < rman_get_start(rle->res) ||
426             r_addr+pmu_regs >= rman_get_end(rle->res))
427         {
428                 device_printf(dev, "core register resource does not map PMU "
429                     "registers at %#jx\n for %s\n", r_addr+pmu_regs,
430                     device_get_nameunit(child));
431                 return (ENXIO);
432         }
433
434         /* Adjust PMU register offset relative to the actual start address
435          * of the core's register block allocation.
436          * 
437          * XXX: The saved offset will be invalid if bus_adjust_resource is
438          * used to modify the resource's start address.
439          */
440         if (rman_get_start(rle->res) > r_addr)
441                 pmu_regs -= rman_get_start(rle->res) - r_addr;
442         else
443                 pmu_regs -= r_addr - rman_get_start(rle->res);
444
445         /* Retain a PMU reference for the clkctl instance state */
446         pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU);
447         if (pmu_dev == NULL) {
448                 device_printf(sc->dev, "PMU not found\n");
449                 return (ENXIO);
450         }
451
452         /* Fetch the maximum transition latency from our PMU */
453         max_latency = bhnd_pmu_get_max_transition_latency(pmu_dev);
454
455         /* Allocate a new bhnd_resource wrapping the standard resource we
456          * fetched from the resource list; we'll free this in
457          * bhnd_generic_release_pmu() */
458         r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
459         if (r == NULL) {
460                 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
461                 return (ENOMEM);
462         }
463
464         r->res = rle->res;
465         r->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0);
466
467         /* Allocate the clkctl instance */
468         clkctl = bhnd_alloc_core_clkctl(child, pmu_dev, r, pmu_regs,
469             max_latency);
470         if (clkctl == NULL) {
471                 free(r, M_BHND);
472                 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
473                 return (ENOMEM);
474         }
475
476         bhnd_set_pmu_info(child, clkctl);
477         return (0);
478 }
479
480 /**
481  * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU().
482  */
483 int
484 bhnd_generic_release_pmu(device_t dev, device_t child)
485 {
486         struct bhnd_softc       *sc;
487         struct bhnd_core_clkctl *clkctl;
488         struct bhnd_resource    *r;
489         device_t                 pmu_dev;
490
491         GIANT_REQUIRED; /* for newbus */
492         
493         sc = device_get_softc(dev);
494
495         if (device_get_parent(child) != dev)
496                 return (EINVAL);
497
498         clkctl = bhnd_get_pmu_info(child);
499         if (clkctl == NULL)
500                 panic("pmu over-release for %s", device_get_nameunit(child));
501
502         /* Clear all FORCE, AREQ, and ERSRC flags, unless we're already in
503          * RESET. Suspending a core clears clkctl automatically (and attempting
504          * to access the PMU registers in a suspended core will trigger a
505          * system livelock). */
506         if (!bhnd_is_hw_suspended(clkctl->cc_dev)) {
507                 BHND_CLKCTL_LOCK(clkctl);
508
509                 /* Clear all FORCE, AREQ, and ERSRC flags */
510                 BHND_CLKCTL_SET_4(clkctl, 0x0, BHND_CCS_FORCE_MASK |
511                     BHND_CCS_AREQ_MASK | BHND_CCS_ERSRC_REQ_MASK);
512
513                 BHND_CLKCTL_UNLOCK(clkctl);
514         }
515
516         /* Clear child's PMU info reference */
517         bhnd_set_pmu_info(child, NULL);
518
519         /* Before freeing the clkctl instance, save a pointer to resources we
520          * need to clean up manually */
521         r = clkctl->cc_res;
522         pmu_dev = clkctl->cc_pmu_dev;
523
524         /* Free the clkctl instance */
525         bhnd_free_core_clkctl(clkctl);
526
527         /* Free the child's bhnd resource wrapper */
528         free(r, M_BHND);
529
530         /* Release the child's PMU provider reference */
531         bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
532
533         return (0);
534 }
535
536 /**
537  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_LATENCY().
538  */
539 int
540 bhnd_generic_get_clock_latency(device_t dev, device_t child, bhnd_clock clock,
541     u_int *latency)
542 {
543         struct bhnd_core_clkctl *clkctl;
544
545         if (device_get_parent(child) != dev)
546                 return (EINVAL);
547
548         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
549                 panic("no active PMU allocation");
550
551         return (bhnd_pmu_get_clock_latency(clkctl->cc_pmu_dev, clock, latency));
552 }
553
554 /**
555  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_FREQ().
556  */
557 int
558 bhnd_generic_get_clock_freq(device_t dev, device_t child, bhnd_clock clock,
559     u_int *freq)
560 {
561         struct bhnd_core_clkctl *clkctl;
562
563         if (device_get_parent(child) != dev)
564                 return (EINVAL);
565
566         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
567                 panic("no active PMU allocation");
568
569         return (bhnd_pmu_get_clock_freq(clkctl->cc_pmu_dev, clock, freq));
570 }
571
572 /**
573  * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK().
574  */
575 int
576 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock)
577 {
578         struct bhnd_softc       *sc;
579         struct bhnd_core_clkctl *clkctl;
580         uint32_t                 avail;
581         uint32_t                 req;
582         int                      error;
583
584         sc = device_get_softc(dev);
585
586         if (device_get_parent(child) != dev)
587                 return (EINVAL);
588
589         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
590                 panic("no active PMU allocation");
591
592         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
593
594         avail = 0x0;
595         req = 0x0;
596
597         switch (clock) {
598         case BHND_CLOCK_DYN:
599                 break;
600         case BHND_CLOCK_ILP:
601                 req |= BHND_CCS_FORCEILP;
602                 break;
603         case BHND_CLOCK_ALP:
604                 req |= BHND_CCS_FORCEALP;
605                 avail |= BHND_CCS_ALPAVAIL;
606                 break;
607         case BHND_CLOCK_HT:
608                 req |= BHND_CCS_FORCEHT;
609                 avail |= BHND_CCS_HTAVAIL;
610                 break;
611         default:
612                 device_printf(dev, "%s requested unknown clock: %#x\n",
613                     device_get_nameunit(clkctl->cc_dev), clock);
614                 return (ENODEV);
615         }
616
617         BHND_CLKCTL_LOCK(clkctl);
618
619         /* Issue request */
620         BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_FORCE_MASK);
621
622         /* Wait for clock availability */
623         error = bhnd_core_clkctl_wait(clkctl, avail, avail);
624
625         BHND_CLKCTL_UNLOCK(clkctl);
626
627         return (error);
628 }
629
630 /**
631  * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS().
632  */
633 int
634 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks)
635 {
636         struct bhnd_softc       *sc;
637         struct bhnd_core_clkctl *clkctl;
638         uint32_t                 avail;
639         uint32_t                 req;
640         int                      error;
641
642         sc = device_get_softc(dev);
643
644         if (device_get_parent(child) != dev)
645                 return (EINVAL);
646
647         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
648                 panic("no active PMU allocation");
649
650         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
651
652         sc = device_get_softc(dev);
653
654         avail = 0x0;
655         req = 0x0;
656
657         /* Build clock request flags */
658         if (clocks & BHND_CLOCK_DYN)            /* nothing to enable */
659                 clocks &= ~BHND_CLOCK_DYN;
660
661         if (clocks & BHND_CLOCK_ILP)            /* nothing to enable */
662                 clocks &= ~BHND_CLOCK_ILP;
663
664         if (clocks & BHND_CLOCK_ALP) {
665                 req |= BHND_CCS_ALPAREQ;
666                 avail |= BHND_CCS_ALPAVAIL;
667                 clocks &= ~BHND_CLOCK_ALP;
668         }
669
670         if (clocks & BHND_CLOCK_HT) {
671                 req |= BHND_CCS_HTAREQ;
672                 avail |= BHND_CCS_HTAVAIL;
673                 clocks &= ~BHND_CLOCK_HT;
674         }
675
676         /* Check for unknown clock values */
677         if (clocks != 0x0) {
678                 device_printf(dev, "%s requested unknown clocks: %#x\n",
679                     device_get_nameunit(clkctl->cc_dev), clocks);
680                 return (ENODEV);
681         }
682
683         BHND_CLKCTL_LOCK(clkctl);
684
685         /* Issue request */
686         BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_AREQ_MASK);
687
688         /* Wait for clock availability */
689         error = bhnd_core_clkctl_wait(clkctl, avail, avail);
690
691         BHND_CLKCTL_UNLOCK(clkctl);
692
693         return (error);
694 }
695
696 /**
697  * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC().
698  */
699 int
700 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc)
701 {
702         struct bhnd_softc       *sc;
703         struct bhnd_core_clkctl *clkctl;
704         uint32_t                 req;
705         uint32_t                 avail;
706         int                      error;
707
708         sc = device_get_softc(dev);
709
710         if (device_get_parent(child) != dev)
711                 return (EINVAL);
712
713         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
714                 panic("no active PMU allocation");
715
716         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
717
718         sc = device_get_softc(dev);
719
720         if (rsrc > BHND_CCS_ERSRC_MAX)
721                 return (EINVAL);
722
723         req = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
724         avail = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_STS);
725
726         BHND_CLKCTL_LOCK(clkctl);
727
728         /* Write request */
729         BHND_CLKCTL_SET_4(clkctl, req, req);
730
731         /* Wait for resource availability */
732         error = bhnd_core_clkctl_wait(clkctl, avail, avail);
733
734         BHND_CLKCTL_UNLOCK(clkctl);
735
736         return (error);
737 }
738
739 /**
740  * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC().
741  */
742 int
743 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc)
744 {
745         struct bhnd_softc       *sc;
746         struct bhnd_core_clkctl *clkctl;
747         uint32_t                 mask;
748
749         sc = device_get_softc(dev);
750
751         if (device_get_parent(child) != dev)
752                 return (EINVAL);
753
754         if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
755                 panic("no active PMU allocation");
756
757
758         BHND_ASSERT_CLKCTL_AVAIL(clkctl);
759
760         sc = device_get_softc(dev);
761
762         if (rsrc > BHND_CCS_ERSRC_MAX)
763                 return (EINVAL);
764
765         mask = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
766
767         /* Clear request */
768         BHND_CLKCTL_LOCK(clkctl);
769         BHND_CLKCTL_SET_4(clkctl, 0x0, mask);
770         BHND_CLKCTL_UNLOCK(clkctl);
771
772         return (0);
773 }
774
775 /**
776  * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
777  * 
778  * This implementation assumes that port and region numbers are 0-indexed and
779  * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
780  * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
781  * within the defined range.
782  */
783 static bool
784 bhnd_generic_is_region_valid(device_t dev, device_t child,
785     bhnd_port_type type, u_int port, u_int region)
786 {
787         if (port >= bhnd_get_port_count(child, type))
788                 return (false);
789
790         if (region >= bhnd_get_region_count(child, type, port))
791                 return (false);
792
793         return (true);
794 }
795
796 /**
797  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
798  * 
799  * This implementation searches @p dev for a registered NVRAM child device.
800  * 
801  * If no NVRAM device is registered with @p dev, the request is delegated to
802  * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
803  */
804 int
805 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
806     void *buf, size_t *size, bhnd_nvram_type type)
807 {
808         struct bhnd_softc       *sc;
809         device_t                 nvram, parent;
810         int                      error;
811
812         sc = device_get_softc(dev);
813
814         /* If a NVRAM device is available, consult it first */
815         nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM);
816         if (nvram != NULL) {
817                 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type);
818                 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM);
819                 return (error);
820         }
821
822         /* Otherwise, try to delegate to parent */
823         if ((parent = device_get_parent(dev)) == NULL)
824                 return (ENODEV);
825
826         return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
827             name, buf, size, type));
828 }
829
830 /**
831  * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
832  * 
833  * This implementation requests the device's struct resource_list via
834  * BUS_GET_RESOURCE_LIST.
835  */
836 int
837 bhnd_generic_print_child(device_t dev, device_t child)
838 {
839         struct resource_list    *rl;
840         int                     retval = 0;
841
842         retval += bus_print_child_header(dev, child);
843
844         rl = BUS_GET_RESOURCE_LIST(dev, child);
845         
846         
847         if (rl != NULL) {
848                 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
849                     "%#jx");
850
851                 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
852                     "%#jd");
853         }
854
855         retval += printf(" at core %u", bhnd_get_core_index(child));
856
857         retval += bus_print_child_domain(dev, child);
858         retval += bus_print_child_footer(dev, child);
859
860         return (retval);
861 }
862
863 /**
864  * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
865  * 
866  * This implementation requests the device's struct resource_list via
867  * BUS_GET_RESOURCE_LIST.
868  */
869 void
870 bhnd_generic_probe_nomatch(device_t dev, device_t child)
871 {
872         struct resource_list            *rl;
873         const struct bhnd_nomatch       *nm;
874         bool                             report;
875
876         /* Fetch reporting configuration for this device */
877         report = true;
878         for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
879                 if (nm->vendor != bhnd_get_vendor(child))
880                         continue;
881
882                 if (nm->device != bhnd_get_device(child))
883                         continue;
884
885                 report = false;
886                 if (bootverbose && nm->if_verbose)
887                         report = true;
888                 break;
889         }
890         
891         if (!report)
892                 return;
893
894         /* Print the non-matched device info */
895         device_printf(dev, "<%s %s, rev %hhu>", bhnd_get_vendor_name(child),
896                 bhnd_get_device_name(child), bhnd_get_hwrev(child));
897
898         rl = BUS_GET_RESOURCE_LIST(dev, child);
899         if (rl != NULL) {
900                 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
901                 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd");
902         }
903
904         printf(" at core %u (no driver attached)\n",
905             bhnd_get_core_index(child));
906 }
907
908 /**
909  * Default implementation of BUS_CHILD_PNPINFO_STR().
910  */
911 static int
912 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
913     size_t buflen)
914 {
915         if (device_get_parent(child) != dev) {
916                 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child,
917                     buf, buflen));
918         }
919
920         snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx",
921             bhnd_get_vendor(child), bhnd_get_device(child),
922             bhnd_get_hwrev(child));
923
924         return (0);
925 }
926
927 /**
928  * Default implementation of BUS_CHILD_LOCATION_STR().
929  */
930 static int
931 bhnd_child_location_str(device_t dev, device_t child, char *buf,
932     size_t buflen)
933 {
934         bhnd_addr_t     addr;
935         bhnd_size_t     size;
936         
937         if (device_get_parent(child) != dev) {
938                 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child,
939                     buf, buflen));
940         }
941
942
943         if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) {
944                 /* No device default port/region */
945                 if (buflen > 0)
946                         *buf = '\0';
947                 return (0);
948         }
949
950         snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr);
951         return (0);
952 }
953
954 /**
955  * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
956  * 
957  * This implementation manages internal bhnd(4) state, and must be called
958  * by subclassing drivers.
959  */
960 void
961 bhnd_generic_child_deleted(device_t dev, device_t child)
962 {
963         struct bhnd_softc       *sc;
964
965         sc = device_get_softc(dev);
966
967         /* Free device info */
968         if (bhnd_get_pmu_info(child) != NULL) {
969                 /* Releasing PMU requests automatically would be nice,
970                  * but we can't reference per-core PMU register
971                  * resource after driver detach */
972                 panic("%s leaked device pmu state\n",
973                     device_get_nameunit(child));
974         }
975 }
976
977 /**
978  * Helper function for implementing BUS_SUSPEND_CHILD().
979  *
980  * TODO: Power management
981  * 
982  * If @p child is not a direct child of @p dev, suspension is delegated to
983  * the @p dev parent.
984  */
985 int
986 bhnd_generic_suspend_child(device_t dev, device_t child)
987 {
988         if (device_get_parent(child) != dev)
989                 BUS_SUSPEND_CHILD(device_get_parent(dev), child);
990
991         return bus_generic_suspend_child(dev, child);
992 }
993
994 /**
995  * Helper function for implementing BUS_RESUME_CHILD().
996  *
997  * TODO: Power management
998  * 
999  * If @p child is not a direct child of @p dev, suspension is delegated to
1000  * the @p dev parent.
1001  */
1002 int
1003 bhnd_generic_resume_child(device_t dev, device_t child)
1004 {
1005         if (device_get_parent(child) != dev)
1006                 BUS_RESUME_CHILD(device_get_parent(dev), child);
1007
1008         return bus_generic_resume_child(dev, child);
1009 }
1010
1011
1012 /**
1013  * Default bhnd(4) bus driver implementation of BUS_SETUP_INTR().
1014  *
1015  * This implementation of BUS_SETUP_INTR() will delegate interrupt setup
1016  * to the parent of @p dev, if any.
1017  */
1018 int
1019 bhnd_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1020     int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
1021     void **cookiep)
1022 {
1023         return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr,
1024             arg, cookiep));
1025 }
1026
1027 /*
1028  * Delegate all indirect I/O to the parent device. When inherited by
1029  * non-bridged bus implementations, resources will never be marked as
1030  * indirect, and these methods will never be called.
1031  */
1032 #define BHND_IO_READ(_type, _name, _method)                             \
1033 static _type                                                            \
1034 bhnd_read_ ## _name (device_t dev, device_t child,                      \
1035     struct bhnd_resource *r, bus_size_t offset)                         \
1036 {                                                                       \
1037         return (BHND_BUS_READ_ ## _method(                              \
1038                     device_get_parent(dev), child, r, offset));         \
1039 }
1040
1041 #define BHND_IO_WRITE(_type, _name, _method)                            \
1042 static void                                                             \
1043 bhnd_write_ ## _name (device_t dev, device_t child,                     \
1044     struct bhnd_resource *r, bus_size_t offset, _type value)            \
1045 {                                                                       \
1046         return (BHND_BUS_WRITE_ ## _method(                             \
1047                     device_get_parent(dev), child, r, offset,           \
1048                     value));    \
1049 }
1050
1051 #define BHND_IO_MISC(_type, _op, _method)                               \
1052 static void                                                             \
1053 bhnd_ ## _op (device_t dev, device_t child,                             \
1054     struct bhnd_resource *r, bus_size_t offset, _type datap,            \
1055     bus_size_t count)                                                   \
1056 {                                                                       \
1057         BHND_BUS_ ## _method(device_get_parent(dev), child, r,          \
1058             offset, datap, count);                                      \
1059 }       
1060
1061 #define BHND_IO_METHODS(_type, _size)                                   \
1062         BHND_IO_READ(_type, _size, _size)                               \
1063         BHND_IO_WRITE(_type, _size, _size)                              \
1064                                                                         \
1065         BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size)         \
1066         BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size)        \
1067                                                                         \
1068         BHND_IO_MISC(_type*, read_multi_ ## _size,                      \
1069             READ_MULTI_ ## _size)                                       \
1070         BHND_IO_MISC(_type*, write_multi_ ## _size,                     \
1071             WRITE_MULTI_ ## _size)                                      \
1072                                                                         \
1073         BHND_IO_MISC(_type*, read_multi_stream_ ## _size,               \
1074            READ_MULTI_STREAM_ ## _size)                                 \
1075         BHND_IO_MISC(_type*, write_multi_stream_ ## _size,              \
1076            WRITE_MULTI_STREAM_ ## _size)                                \
1077                                                                         \
1078         BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size)   \
1079         BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \
1080                                                                         \
1081         BHND_IO_MISC(_type*, read_region_ ## _size,                     \
1082             READ_REGION_ ## _size)                                      \
1083         BHND_IO_MISC(_type*, write_region_ ## _size,                    \
1084             WRITE_REGION_ ## _size)                                     \
1085                                                                         \
1086         BHND_IO_MISC(_type*, read_region_stream_ ## _size,              \
1087             READ_REGION_STREAM_ ## _size)                               \
1088         BHND_IO_MISC(_type*, write_region_stream_ ## _size,             \
1089             WRITE_REGION_STREAM_ ## _size)                              \
1090
1091 BHND_IO_METHODS(uint8_t, 1);
1092 BHND_IO_METHODS(uint16_t, 2);
1093 BHND_IO_METHODS(uint32_t, 4);
1094
1095 static void 
1096 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
1097     bus_size_t offset, bus_size_t length, int flags)
1098 {
1099         BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
1100             flags);
1101 }
1102
1103 static device_method_t bhnd_methods[] = {
1104         /* Device interface */ \
1105         DEVMETHOD(device_attach,                bhnd_generic_attach),
1106         DEVMETHOD(device_detach,                bhnd_generic_detach),
1107         DEVMETHOD(device_shutdown,              bhnd_generic_shutdown),
1108         DEVMETHOD(device_suspend,               bhnd_generic_suspend),
1109         DEVMETHOD(device_resume,                bhnd_generic_resume),
1110
1111         /* Bus interface */
1112         DEVMETHOD(bus_child_deleted,            bhnd_generic_child_deleted),
1113         DEVMETHOD(bus_probe_nomatch,            bhnd_generic_probe_nomatch),
1114         DEVMETHOD(bus_print_child,              bhnd_generic_print_child),
1115         DEVMETHOD(bus_child_pnpinfo_str,        bhnd_child_pnpinfo_str),
1116         DEVMETHOD(bus_child_location_str,       bhnd_child_location_str),
1117
1118         DEVMETHOD(bus_suspend_child,            bhnd_generic_suspend_child),
1119         DEVMETHOD(bus_resume_child,             bhnd_generic_resume_child),
1120
1121         DEVMETHOD(bus_set_resource,             bus_generic_rl_set_resource),
1122         DEVMETHOD(bus_get_resource,             bus_generic_rl_get_resource),
1123         DEVMETHOD(bus_delete_resource,          bus_generic_rl_delete_resource),
1124         DEVMETHOD(bus_alloc_resource,           bus_generic_rl_alloc_resource),
1125         DEVMETHOD(bus_adjust_resource,          bus_generic_adjust_resource),
1126         DEVMETHOD(bus_release_resource,         bus_generic_rl_release_resource),
1127         DEVMETHOD(bus_activate_resource,        bus_generic_activate_resource),
1128         DEVMETHOD(bus_deactivate_resource,      bus_generic_deactivate_resource),
1129
1130         DEVMETHOD(bus_setup_intr,               bhnd_generic_setup_intr),
1131         DEVMETHOD(bus_teardown_intr,            bus_generic_teardown_intr),
1132         DEVMETHOD(bus_config_intr,              bus_generic_config_intr),
1133         DEVMETHOD(bus_bind_intr,                bus_generic_bind_intr),
1134         DEVMETHOD(bus_describe_intr,            bus_generic_describe_intr),
1135
1136         DEVMETHOD(bus_get_dma_tag,              bus_generic_get_dma_tag),
1137
1138         /* BHND interface */
1139         DEVMETHOD(bhnd_bus_get_chipid,          bhnd_bus_generic_get_chipid),
1140         DEVMETHOD(bhnd_bus_is_hw_disabled,      bhnd_bus_generic_is_hw_disabled),
1141         DEVMETHOD(bhnd_bus_read_board_info,     bhnd_bus_generic_read_board_info),
1142
1143         DEVMETHOD(bhnd_bus_get_probe_order,     bhnd_generic_get_probe_order),
1144
1145         DEVMETHOD(bhnd_bus_alloc_pmu,           bhnd_generic_alloc_pmu),
1146         DEVMETHOD(bhnd_bus_release_pmu,         bhnd_generic_release_pmu),
1147         DEVMETHOD(bhnd_bus_request_clock,       bhnd_generic_request_clock),
1148         DEVMETHOD(bhnd_bus_enable_clocks,       bhnd_generic_enable_clocks),
1149         DEVMETHOD(bhnd_bus_request_ext_rsrc,    bhnd_generic_request_ext_rsrc),
1150         DEVMETHOD(bhnd_bus_release_ext_rsrc,    bhnd_generic_release_ext_rsrc),
1151         DEVMETHOD(bhnd_bus_get_clock_latency,   bhnd_generic_get_clock_latency),
1152         DEVMETHOD(bhnd_bus_get_clock_freq,      bhnd_generic_get_clock_freq),
1153
1154         DEVMETHOD(bhnd_bus_is_region_valid,     bhnd_generic_is_region_valid),
1155         DEVMETHOD(bhnd_bus_get_nvram_var,       bhnd_generic_get_nvram_var),
1156
1157         /* BHND interface (bus I/O) */
1158         DEVMETHOD(bhnd_bus_read_1,              bhnd_read_1),
1159         DEVMETHOD(bhnd_bus_read_2,              bhnd_read_2),
1160         DEVMETHOD(bhnd_bus_read_4,              bhnd_read_4),
1161         DEVMETHOD(bhnd_bus_write_1,             bhnd_write_1),
1162         DEVMETHOD(bhnd_bus_write_2,             bhnd_write_2),
1163         DEVMETHOD(bhnd_bus_write_4,             bhnd_write_4),
1164
1165         DEVMETHOD(bhnd_bus_read_stream_1,       bhnd_read_stream_1),
1166         DEVMETHOD(bhnd_bus_read_stream_2,       bhnd_read_stream_2),
1167         DEVMETHOD(bhnd_bus_read_stream_4,       bhnd_read_stream_4),
1168         DEVMETHOD(bhnd_bus_write_stream_1,      bhnd_write_stream_1),
1169         DEVMETHOD(bhnd_bus_write_stream_2,      bhnd_write_stream_2),
1170         DEVMETHOD(bhnd_bus_write_stream_4,      bhnd_write_stream_4),
1171
1172         DEVMETHOD(bhnd_bus_read_multi_1,        bhnd_read_multi_1),
1173         DEVMETHOD(bhnd_bus_read_multi_2,        bhnd_read_multi_2),
1174         DEVMETHOD(bhnd_bus_read_multi_4,        bhnd_read_multi_4),
1175         DEVMETHOD(bhnd_bus_write_multi_1,       bhnd_write_multi_1),
1176         DEVMETHOD(bhnd_bus_write_multi_2,       bhnd_write_multi_2),
1177         DEVMETHOD(bhnd_bus_write_multi_4,       bhnd_write_multi_4),
1178         
1179         DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1),
1180         DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2),
1181         DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4),
1182         DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
1183         DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
1184         DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
1185
1186         DEVMETHOD(bhnd_bus_set_multi_1,         bhnd_set_multi_1),
1187         DEVMETHOD(bhnd_bus_set_multi_2,         bhnd_set_multi_2),
1188         DEVMETHOD(bhnd_bus_set_multi_4,         bhnd_set_multi_4),
1189
1190         DEVMETHOD(bhnd_bus_set_region_1,        bhnd_set_region_1),
1191         DEVMETHOD(bhnd_bus_set_region_2,        bhnd_set_region_2),
1192         DEVMETHOD(bhnd_bus_set_region_4,        bhnd_set_region_4),
1193
1194         DEVMETHOD(bhnd_bus_read_region_1,       bhnd_read_region_1),
1195         DEVMETHOD(bhnd_bus_read_region_2,       bhnd_read_region_2),
1196         DEVMETHOD(bhnd_bus_read_region_4,       bhnd_read_region_4),
1197         DEVMETHOD(bhnd_bus_write_region_1,      bhnd_write_region_1),
1198         DEVMETHOD(bhnd_bus_write_region_2,      bhnd_write_region_2),
1199         DEVMETHOD(bhnd_bus_write_region_4,      bhnd_write_region_4),
1200
1201         DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1),
1202         DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2),
1203         DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4),
1204         DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1),
1205         DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2),
1206         DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4),
1207
1208         DEVMETHOD(bhnd_bus_barrier,                     bhnd_barrier),
1209
1210         DEVMETHOD_END
1211 };
1212
1213 devclass_t bhnd_devclass;       /**< bhnd bus. */
1214 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */
1215 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */
1216
1217 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
1218 MODULE_VERSION(bhnd, 1);