1*8ff6f65dSthorpej /* $NetBSD: mainbus.c,v 1.31 2023/12/20 06:36:01 thorpej Exp $ */
216b9c606Sthorpej
316b9c606Sthorpej /*-
416b9c606Sthorpej * Copyright (c) 2001 The NetBSD Foundation, Inc.
516b9c606Sthorpej * All rights reserved.
616b9c606Sthorpej *
716b9c606Sthorpej * This code is derived from software contributed to The NetBSD Foundation
816b9c606Sthorpej * by Jason R. Thorpe.
916b9c606Sthorpej *
1016b9c606Sthorpej * Redistribution and use in source and binary forms, with or without
1116b9c606Sthorpej * modification, are permitted provided that the following conditions
1216b9c606Sthorpej * are met:
1316b9c606Sthorpej * 1. Redistributions of source code must retain the above copyright
1416b9c606Sthorpej * notice, this list of conditions and the following disclaimer.
1516b9c606Sthorpej * 2. Redistributions in binary form must reproduce the above copyright
1616b9c606Sthorpej * notice, this list of conditions and the following disclaimer in the
1716b9c606Sthorpej * documentation and/or other materials provided with the distribution.
1816b9c606Sthorpej *
1916b9c606Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2016b9c606Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2116b9c606Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2216b9c606Sthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2316b9c606Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2416b9c606Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2516b9c606Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2616b9c606Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2716b9c606Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2816b9c606Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2916b9c606Sthorpej * POSSIBILITY OF SUCH DAMAGE.
3016b9c606Sthorpej */
3116b9c606Sthorpej
326fdfc66cSlukem #include <sys/cdefs.h>
33*8ff6f65dSthorpej __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.31 2023/12/20 06:36:01 thorpej Exp $");
346fdfc66cSlukem
3516b9c606Sthorpej #include "opt_algor_p4032.h"
3616b9c606Sthorpej #include "opt_algor_p5064.h"
3716b9c606Sthorpej #include "opt_algor_p6032.h"
3816b9c606Sthorpej
3916b9c606Sthorpej #include "opt_pci.h"
4016b9c606Sthorpej
4116b9c606Sthorpej #include <sys/param.h>
42391925c7Sdyoung #include <sys/bus.h>
43f5439ed7Smatt #include <sys/conf.h>
44f5439ed7Smatt #include <sys/device.h>
45f5439ed7Smatt #include <sys/reboot.h>
46f5439ed7Smatt #include <sys/systm.h>
47f5439ed7Smatt
48f5439ed7Smatt #include <algor/autoconf.h>
4916b9c606Sthorpej
50636e9cd0Sthorpej #include <mips/cache.h>
51636e9cd0Sthorpej
5216b9c606Sthorpej #include <dev/pci/pcivar.h>
5316b9c606Sthorpej #include <dev/pci/pciconf.h>
5416b9c606Sthorpej
55f5e6f05cSthorpej #if defined(PCI_NETBSD_CONFIGURE) && defined(PCI_NETBSD_ENABLE_IDE)
56f5e6f05cSthorpej #if defined(ALGOR_P5064) || defined(ALGOR_P6032)
57f5e6f05cSthorpej #include <dev/pci/pciide_piix_reg.h>
58f5e6f05cSthorpej #endif /* ALGOR_P5064 || ALGOR_P6032 */
59f5e6f05cSthorpej #endif /* PCI_NETBSD_CONFIGURE && PCI_NETBSD_ENABLE_IDE */
60f5e6f05cSthorpej
6116b9c606Sthorpej #include "locators.h"
6216b9c606Sthorpej #include "pci.h"
6316b9c606Sthorpej
64612b7ee5Smatt int mainbus_match(device_t, cfdata_t, void *);
65612b7ee5Smatt void mainbus_attach(device_t, device_t, void *);
6616b9c606Sthorpej
67612b7ee5Smatt CFATTACH_DECL_NEW(mainbus, 0,
685a9ddc14Sthorpej mainbus_match, mainbus_attach, NULL, NULL);
6916b9c606Sthorpej
7016b9c606Sthorpej int mainbus_print(void *, const char *);
71612b7ee5Smatt int mainbus_submatch(device_t, cfdata_t,
7244bf0a7eSdrochner const int *, void *);
7316b9c606Sthorpej
7416b9c606Sthorpej /* There can be only one. */
7516b9c606Sthorpej int mainbus_found;
7616b9c606Sthorpej
7771cb790fSthorpej struct mainbusdev {
7871cb790fSthorpej const char *md_name;
7971cb790fSthorpej bus_addr_t md_addr;
8071cb790fSthorpej int md_irq;
8171cb790fSthorpej };
8271cb790fSthorpej
8371cb790fSthorpej #if defined(ALGOR_P4032)
8471cb790fSthorpej #include <algor/algor/algor_p4032reg.h>
8571cb790fSthorpej #include <algor/algor/algor_p4032var.h>
8671cb790fSthorpej
8771cb790fSthorpej struct mainbusdev mainbusdevs[] = {
8871cb790fSthorpej { "cpu", -1, -1 },
8971cb790fSthorpej { "mcclock", P4032_RTC, P4032_IRQ_RTC },
9071cb790fSthorpej { "com", P4032_COM1, P4032_IRQ_COM1 },
9171cb790fSthorpej { "com", P4032_COM2, P4032_IRQ_COM2 },
9271cb790fSthorpej { "lpt", P4032_LPT, P4032_IRQ_LPT },
9371cb790fSthorpej { "pckbc", P4032_PCKBC, P4032_IRQ_PCKBC },
9471cb790fSthorpej { "fdc", P4032_FDC, P4032_IRQ_FLOPPY },
9571cb790fSthorpej { "vtpbc", P4032_V962PBC, -1 },
9671cb790fSthorpej
9771cb790fSthorpej { NULL, 0, 0 },
9871cb790fSthorpej };
99ca8ce3aeSthorpej
100ca8ce3aeSthorpej /* Reserve the bottom 64K of the I/O space for ISA devices. */
101ca8ce3aeSthorpej #define PCI_IO_START 0x00010000
102ca8ce3aeSthorpej #define PCI_IO_END 0x000effff
103ca8ce3aeSthorpej #define PCI_MEM_START 0x01000000
104ca8ce3aeSthorpej #define PCI_MEM_END 0x07ffffff
105ca8ce3aeSthorpej #define PCI_CHIPSET &p4032_configuration.ac_pc
10671cb790fSthorpej #endif /* ALGOR_P4032 */
10771cb790fSthorpej
10816b9c606Sthorpej #if defined(ALGOR_P5064)
10916b9c606Sthorpej #include <algor/algor/algor_p5064reg.h>
11016b9c606Sthorpej #include <algor/algor/algor_p5064var.h>
11116b9c606Sthorpej
11271cb790fSthorpej struct mainbusdev mainbusdevs[] = {
11371cb790fSthorpej { "cpu", -1, -1 },
11471cb790fSthorpej { "vtpbc", P5064_V360EPC, -1 },
11516b9c606Sthorpej
11671cb790fSthorpej { NULL, 0, 0 },
11716b9c606Sthorpej };
118ca8ce3aeSthorpej
119ca8ce3aeSthorpej /*
120ca8ce3aeSthorpej * Reserve the bottom 512K of the I/O space for ISA devices.
121ca8ce3aeSthorpej * According to the PMON sources, this is a work-around for
122ca8ce3aeSthorpej * a bug in the ISA bridge.
123ca8ce3aeSthorpej */
124ca8ce3aeSthorpej #define PCI_IO_START 0x00080000
125ca8ce3aeSthorpej #define PCI_IO_END 0x00ffffff
126ca8ce3aeSthorpej #define PCI_MEM_START 0x01000000
127ca8ce3aeSthorpej #define PCI_MEM_END 0x07ffffff
128ca8ce3aeSthorpej #define PCI_IDE_DEV 2
129ca8ce3aeSthorpej #define PCI_IDE_FUNC 1
130ca8ce3aeSthorpej #define PCI_CHIPSET &p5064_configuration.ac_pc
13116b9c606Sthorpej #endif /* ALGOR_P5064 */
13216b9c606Sthorpej
1330c37c9e8Sthorpej #if defined(ALGOR_P6032)
1340c37c9e8Sthorpej #include <algor/algor/algor_p6032reg.h>
1350c37c9e8Sthorpej #include <algor/algor/algor_p6032var.h>
1360c37c9e8Sthorpej
1370c37c9e8Sthorpej struct mainbusdev mainbusdevs[] = {
1380c37c9e8Sthorpej { "cpu", -1, -1 },
1390c37c9e8Sthorpej { "bonito", BONITO_REG_BASE, -1 },
1400c37c9e8Sthorpej
1410c37c9e8Sthorpej { NULL, 0, 0 },
1420c37c9e8Sthorpej };
143ca8ce3aeSthorpej
144ca8ce3aeSthorpej /* Reserve the bottom 64K of the I/O space for ISA devices. */
145ca8ce3aeSthorpej #define PCI_IO_START 0x00010000
146ca8ce3aeSthorpej #define PCI_IO_END 0x000effff
147ca8ce3aeSthorpej #define PCI_MEM_START 0x01000000
148ca8ce3aeSthorpej #define PCI_MEM_END 0x0affffff
149ca8ce3aeSthorpej #define PCI_IDE_DEV 17
150ca8ce3aeSthorpej #define PCI_IDE_FUNC 1
151ca8ce3aeSthorpej #define PCI_CHIPSET &p6032_configuration.ac_pc
1520c37c9e8Sthorpej #endif /* ALGOR_P6032 */
1530c37c9e8Sthorpej
154ca8ce3aeSthorpej #define PCI_IO_SIZE ((PCI_IO_END - PCI_IO_START) + 1)
155ca8ce3aeSthorpej #define PCI_MEM_SIZE ((PCI_MEM_END - PCI_MEM_START) + 1)
156ca8ce3aeSthorpej
15716b9c606Sthorpej int
mainbus_match(device_t parent,cfdata_t cf,void * aux)158612b7ee5Smatt mainbus_match(device_t parent, cfdata_t cf, void *aux)
15916b9c606Sthorpej {
16016b9c606Sthorpej
16116b9c606Sthorpej if (mainbus_found)
16216b9c606Sthorpej return (0);
16316b9c606Sthorpej
16416b9c606Sthorpej return (1);
16516b9c606Sthorpej }
16616b9c606Sthorpej
16716b9c606Sthorpej void
mainbus_attach(device_t parent,device_t self,void * aux)168612b7ee5Smatt mainbus_attach(device_t parent, device_t self, void *aux)
16916b9c606Sthorpej {
17071cb790fSthorpej struct mainbus_attach_args ma;
17171cb790fSthorpej struct mainbusdev *md;
17271cb790fSthorpej bus_space_tag_t st;
17316b9c606Sthorpej
17416b9c606Sthorpej mainbus_found = 1;
17516b9c606Sthorpej
17616b9c606Sthorpej printf("\n");
17716b9c606Sthorpej
17816b9c606Sthorpej #if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
179ca8ce3aeSthorpej struct pciconf_resources *pcires = pciconf_resource_init();
18071cb790fSthorpej
181ca8ce3aeSthorpej pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
182ca8ce3aeSthorpej PCI_IO_START, PCI_IO_SIZE);
183ca8ce3aeSthorpej pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
184ca8ce3aeSthorpej PCI_MEM_START, PCI_MEM_SIZE);
18516b9c606Sthorpej
186ca8ce3aeSthorpej pci_configure_bus(PCI_CHIPSET, pcires, 0,
187ca8ce3aeSthorpej mips_cache_info.mci_dcache_align);
188ca8ce3aeSthorpej pciconf_resource_fini(pcires);
189f5e6f05cSthorpej
190f5e6f05cSthorpej #if defined(PCI_NETBSD_ENABLE_IDE)
191f5e6f05cSthorpej /*
192f5e6f05cSthorpej * Perhaps PMON has not enabled the IDE controller. Easy to
193f5e6f05cSthorpej * fix -- just set the ENABLE bits for each channel in the
194f5e6f05cSthorpej * IDETIM register. Just clear all the bits for the channel
195f5e6f05cSthorpej * except for the ENABLE bits -- the `pciide' driver will
196f5e6f05cSthorpej * properly configure it later.
197f5e6f05cSthorpej */
198ca8ce3aeSthorpej pcitag_t idetag = pci_make_tag(PCI_CHIPSET, 0, PCI_IDE_DEV,
199ca8ce3aeSthorpej PCI_IDE_FUNC);
200ca8ce3aeSthorpej pcireg_t idetim = 0;
201f5e6f05cSthorpej if (PCI_NETBSD_ENABLE_IDE & 0x01)
202f5e6f05cSthorpej idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, 0);
203f5e6f05cSthorpej if (PCI_NETBSD_ENABLE_IDE & 0x02)
204f5e6f05cSthorpej idetim = PIIX_IDETIM_SET(idetim, PIIX_IDETIM_IDE, 1);
205ca8ce3aeSthorpej pci_conf_write(PCI_CHIPSET, idetag, PIIX_IDETIM, idetim);
206f5e6f05cSthorpej #endif
20716b9c606Sthorpej #endif /* NPCI > 0 && defined(PCI_NETBSD_CONFIGURE) */
20816b9c606Sthorpej
20971cb790fSthorpej #if defined(ALGOR_P4032)
21071cb790fSthorpej st = &p4032_configuration.ac_lociot;
21171cb790fSthorpej #elif defined(ALGOR_P5064)
21271cb790fSthorpej st = NULL;
2130c37c9e8Sthorpej #elif defined(ALGOR_P6032)
2140c37c9e8Sthorpej st = NULL;
21571cb790fSthorpej #endif
21671cb790fSthorpej
21771cb790fSthorpej for (md = mainbusdevs; md->md_name != NULL; md++) {
21871cb790fSthorpej ma.ma_name = md->md_name;
21971cb790fSthorpej ma.ma_st = st;
22071cb790fSthorpej ma.ma_addr = md->md_addr;
22171cb790fSthorpej ma.ma_irq = md->md_irq;
2222685996bSthorpej config_found(self, &ma, mainbus_print,
223c7fb772bSthorpej CFARGS(.submatch = mainbus_submatch));
22416b9c606Sthorpej }
22571cb790fSthorpej }
22616b9c606Sthorpej
22716b9c606Sthorpej int
mainbus_print(void * aux,const char * pnp)22816b9c606Sthorpej mainbus_print(void *aux, const char *pnp)
22916b9c606Sthorpej {
23016b9c606Sthorpej struct mainbus_attach_args *ma = aux;
23116b9c606Sthorpej
23216b9c606Sthorpej if (pnp)
23341a403fbSthorpej aprint_normal("%s at %s", ma->ma_name, pnp);
23416b9c606Sthorpej if (ma->ma_addr != (bus_addr_t) -1)
235eee38be7Smatt aprint_normal(" addr %#" PRIxBUSADDR, ma->ma_addr);
23616b9c606Sthorpej
23716b9c606Sthorpej return (UNCONF);
23816b9c606Sthorpej }
23916b9c606Sthorpej
24016b9c606Sthorpej int
mainbus_submatch(device_t parent,cfdata_t cf,const int * ldesc,void * aux)241612b7ee5Smatt mainbus_submatch(device_t parent, cfdata_t cf,
24244bf0a7eSdrochner const int *ldesc, void *aux)
24316b9c606Sthorpej {
24416b9c606Sthorpej struct mainbus_attach_args *ma = aux;
24516b9c606Sthorpej
24616b9c606Sthorpej if (cf->cf_loc[MAINBUSCF_ADDR] != MAINBUSCF_ADDR_DEFAULT &&
24716b9c606Sthorpej cf->cf_loc[MAINBUSCF_ADDR] != ma->ma_addr)
24816b9c606Sthorpej return (0);
24916b9c606Sthorpej
2506c88de3bSthorpej return (config_match(parent, cf, aux));
25116b9c606Sthorpej }
252