#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.27 2026/04/26 18:02:57 thorpej Exp $");
#include "opt_mvmeconf.h"
#include "vmetwo.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kcore.h>
#define _M68K_BUS_DMA_PRIVATE
#define _M68K_BUS_SPACE_PRIVATE
#include <machine/bus.h>
#undef _M68K_BUS_DMA_PRIVATE
#undef _M68K_BUS_SPACE_PRIVATE
#include <machine/cpu.h>
#include <m68k/seglist.h>
#include <mvme68k/dev/mainbus.h>
#if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
#if NVMETWO == 0
#include <dev/vme/vmevar.h>
#include <dev/mvme/mvmebus.h>
#include <dev/mvme/vme_twovar.h>
#endif
#endif
void mainbus_attach(device_t, device_t, void *);
int mainbus_match(device_t, cfdata_t, void *);
int mainbus_print(void *, const char *);
CFATTACH_DECL_NEW(mainbus, 0,
mainbus_match, mainbus_attach, NULL, NULL);
struct mainbus_devices {
const char *md_name;
bus_addr_t md_offset;
};
#ifdef MVME147
static struct mainbus_devices mainbusdevs_147[] = {
{"pcc", MAINBUS_PCC_OFFSET},
{"timekeeper", MAINBUS_TK147_OFFSET},
{NULL, 0}
};
#endif
#if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
static struct mainbus_devices mainbusdevs_1x7[] = {
{"pcctwo", MAINBUS_PCCTWO_OFFSET},
{"vmetwo", MAINBUS_VMETWO_OFFSET},
{"timekeeper", MAINBUS_TIMEKEEPER_OFFSET},
{NULL, 0}
};
#endif
static int
mvme68k_bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
int flags)
{
extern paddr_t avail_start, avail_end;
bus_addr_t high;
if (flags & BUS_DMA_ONBOARD_RAM) {
high = phys_seg_list[0].ps_avail_end;
} else {
high = avail_end;
}
return _bus_dmamem_alloc_common(t, avail_start, high,
size, alignment, boundary, segs, nsegs, rsegs, flags);
}
struct m68k_bus_dma_tag _mainbus_dma_tag = {
NULL,
0,
_bus_dmamap_create,
_bus_dmamap_destroy,
_bus_dmamap_load_direct,
_bus_dmamap_load_mbuf_direct,
_bus_dmamap_load_uio_direct,
_bus_dmamap_load_raw_direct,
_bus_dmamap_unload,
_bus_dmamap_sync,
mvme68k_bus_dmamem_alloc,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
_bus_dmamem_mmap
};
int
mainbus_match(device_t parent, cfdata_t cf, void *args)
{
static int mainbus_matched;
if (mainbus_matched)
return 0;
return (mainbus_matched = 1);
}
void
mainbus_attach(device_t parent, device_t self, void *args)
{
struct mainbus_attach_args ma;
struct mainbus_devices *devices;
int i;
printf("\n");
switch (machineid) {
#ifdef MVME147
case MVME_147:
devices = mainbusdevs_147;
break;
#endif
#if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
case MVME_162:
case MVME_167:
case MVME_172:
case MVME_177:
devices = mainbusdevs_1x7;
break;
#endif
default:
panic("mainbus_attach: impossible CPU type");
}
for (i = 0; devices[i].md_name != NULL; ++i) {
#if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
#if NVMETWO == 0
if (devices[i].md_offset == MAINBUS_VMETWO_OFFSET
#if defined(MVME147)
&& machineid != MVME_147
#endif
) {
(void)vmetwo_probe(&m68k_simple_bus_space,
intiobase_phys + MAINBUS_VMETWO_OFFSET);
continue;
}
#endif
#endif
ma.ma_name = devices[i].md_name;
ma.ma_dmat = &_mainbus_dma_tag;
ma.ma_bust = &m68k_simple_bus_space;
ma.ma_offset = devices[i].md_offset + intiobase_phys;
(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
}
#if defined(MVME162) || defined(MVME172) || defined(MVME167) || defined(MVME177)
#if defined(MVME147)
if (machineid != MVME_147)
#endif
{
ma.ma_name = "memc";
ma.ma_dmat = &_mainbus_dma_tag;
ma.ma_bust = &m68k_simple_bus_space;
ma.ma_offset = MAINBUS_MEMC1_OFFSET + intiobase_phys;
(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
ma.ma_offset = MAINBUS_MEMC2_OFFSET + intiobase_phys;
(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
}
#endif
#if defined(MVME162) || defined(MVME172)
#if defined(MVME147) || defined(MVME167) || defined(MVME177)
if (machineid == MVME_162 || machineid == MVME_172)
#endif
{
ma.ma_name = "ipack";
ma.ma_dmat = &_mainbus_dma_tag;
ma.ma_bust = &m68k_simple_bus_space;
ma.ma_offset = MAINBUS_IPACK_OFFSET + intiobase_phys;
(void)config_found(self, &ma, mainbus_print, CFARGS_NONE);
}
#endif
}
int
mainbus_print(void *aux, const char *cp)
{
struct mainbus_attach_args *ma;
ma = aux;
if (cp)
aprint_normal("%s at %s", ma->ma_name, cp);
aprint_normal(" address 0x%lx", ma->ma_offset);
return UNCONF;
}