xref: /openbsd/sys/dev/acpi/acpimcfg.c (revision a6445c1d)
1 /* $OpenBSD: acpimcfg.c,v 1.2 2011/01/05 22:29:31 kettenis Exp $ */
2 /*
3  * Copyright (c) 2010 Mark Kettenis <kettenis@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 
22 #include <machine/apicvar.h>
23 
24 #include <dev/acpi/acpireg.h>
25 #include <dev/acpi/acpivar.h>
26 #include <dev/pci/pcivar.h>
27 
28 int acpimcfg_match(struct device *, void *, void *);
29 void acpimcfg_attach(struct device *, struct device *, void *);
30 
31 struct cfattach acpimcfg_ca = {
32 	sizeof(struct device), acpimcfg_match, acpimcfg_attach
33 };
34 
35 struct cfdriver acpimcfg_cd = {
36 	NULL, "acpimcfg", DV_DULL
37 };
38 
39 int
40 acpimcfg_match(struct device *parent, void *match, void *aux)
41 {
42 	struct acpi_attach_args *aaa = aux;
43 	struct acpi_table_header *hdr;
44 
45 	/*
46 	 * If we do not have a table, it is not us
47 	 */
48 	if (aaa->aaa_table == NULL)
49 		return (0);
50 
51 	/*
52 	 * If it is an MCFG table, we can attach
53 	 */
54 	hdr = (struct acpi_table_header *)aaa->aaa_table;
55 	if (memcmp(hdr->signature, MCFG_SIG, sizeof(MCFG_SIG) - 1) != 0)
56 		return (0);
57 
58 	return (1);
59 }
60 
61 void
62 acpimcfg_attach(struct device *parent, struct device *self, void *aux)
63 {
64 	struct acpi_attach_args *aaa = aux;
65 	struct acpi_mcfg *mcfg = (struct acpi_mcfg *)aaa->aaa_table;
66 
67 	printf(" addr 0x%llx, bus %d-%d\n", mcfg->base_address,
68 	    mcfg->min_bus_number, mcfg->max_bus_number);
69 
70 	/*
71 	 * Some (broken?) BIOSen have an MCFG table for an empty bus
72 	 * range.  Ignore those tables.
73 	 */
74 	if (mcfg->min_bus_number == mcfg->max_bus_number)
75 		return;
76 
77 	pci_mcfg_addr = mcfg->base_address;
78 	pci_mcfg_min_bus = mcfg->min_bus_number;
79 	pci_mcfg_max_bus = mcfg->max_bus_number;
80 }
81