#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.25 2026/04/26 10:52:14 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/vmem.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
#include <uvm/uvm_extern.h>
int
bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
vmem_addr_t kva;
vsize_t offset;
int error;
if (t->bustype == HP300_BUS_SPACE_INTIO) {
*bshp = (bus_space_handle_t)IIOV(INTIOBASE + bpa);
return 0;
}
if (t->bustype != HP300_BUS_SPACE_DIO &&
t->bustype != HP300_BUS_SPACE_SGC)
panic("%s: bad space tag", __func__);
offset = m68k_page_offset(bpa);
size = m68k_round_page(offset + size);
error = vmem_alloc(extio_arena, size, VM_BESTFIT | VM_NOSLEEP, &kva);
if (error) {
return error;
}
vaddr_t va = kva;
vaddr_t eva = kva + size;
bpa = m68k_trunc_page(bpa);
while (va < eva) {
pmap_kenter_pa(va, bpa, VM_PROT_READ | VM_PROT_WRITE,
PMAP_NOCACHE);
va += PAGE_SIZE;
bpa += PAGE_SIZE;
}
*bshp = (bus_space_handle_t)(kva + offset);
return 0;
}
int
bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
bus_addr_t *bpap, bus_space_handle_t *bshp)
{
return EINVAL;
}
void
bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{
panic("%s: shouldn't be here", __func__);
}
void
bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{
vaddr_t kva;
vsize_t offset;
if (t->bustype == HP300_BUS_SPACE_INTIO) {
return;
}
if (t->bustype != HP300_BUS_SPACE_DIO &&
t->bustype != HP300_BUS_SPACE_SGC)
panic("%s: bad space tag", __func__);
kva = m68k_trunc_page(bsh);
offset = m68k_page_offset(bsh);
size = m68k_round_page(offset + size);
KASSERT(bsh >= (vaddr_t)extiobase);
KASSERT(bsh < ((vaddr_t)extiobase + ptoa(EIOMAPSIZE)));
pmap_kremove(kva, size);
vmem_free(extio_arena, kva, size);
}
int
bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
{
*nbshp = bsh + offset;
return 0;
}
int
hp300_bus_space_probe(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, int sz)
{
label_t faultbuf;
int i;
nofault = &faultbuf;
if (setjmp(nofault)) {
nofault = NULL;
return 0;
}
switch (sz) {
case 1:
i = bus_space_read_1(t, bsh, offset);
break;
case 2:
i = bus_space_read_2(t, bsh, offset);
break;
case 4:
i = bus_space_read_4(t, bsh, offset);
break;
default:
panic("%s: unupported data size %d", __func__, sz);
}
__USE(i);
nofault = NULL;
return 1;
}