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