diff options
Diffstat (limited to 'sys/arch/i386/pci/agp_machdep.c')
-rw-r--r-- | sys/arch/i386/pci/agp_machdep.c | 87 |
1 files changed, 48 insertions, 39 deletions
diff --git a/sys/arch/i386/pci/agp_machdep.c b/sys/arch/i386/pci/agp_machdep.c index 5af66c3131a..c4e4ec37988 100644 --- a/sys/arch/i386/pci/agp_machdep.c +++ b/sys/arch/i386/pci/agp_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agp_machdep.c,v 1.18 2014/07/12 18:44:42 tedu Exp $ */ +/* $OpenBSD: agp_machdep.c,v 1.19 2014/09/20 16:15:16 kettenis Exp $ */ /* * Copyright (c) 2008 - 2009 Owain G. Ainsworth <oga@openbsd.org> @@ -74,38 +74,25 @@ struct agp_map { bus_addr_t addr; bus_size_t size; int flags; + vaddr_t va; }; -extern struct extent *ioport_ex; extern struct extent *iomem_ex; int agp_init_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size, int flags, struct agp_map **mapp) { - struct extent *ex; - struct agp_map *map; - int error; - - switch (tag) { - case I386_BUS_SPACE_IO: - ex = ioport_ex; - if (flags & BUS_SPACE_MAP_LINEAR) - return (EINVAL); - break; - - case I386_BUS_SPACE_MEM: - ex = iomem_ex; - break; - - default: - panic("agp_init_map: bad bus space tag"); - } + struct agp_map *map; + int error; + + KASSERT(tag == I386_BUS_SPACE_MEM); + /* * We grab the extent out of the bus region ourselves * so we don't need to do these allocations every time. */ - error = extent_alloc_region(ex, address, size, + error = extent_alloc_region(iomem_ex, address, size, EX_NOWAIT | EX_MALLOCOK); if (error) return (error); @@ -119,6 +106,12 @@ agp_init_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size, map->size = size; map->flags = flags; + map->va = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none, &kd_waitok); + if (map->va == 0) { + free(map, M_AGP, sizeof(*map)); + return (ENOMEM); + } + *mapp = map; return (0); } @@ -126,25 +119,11 @@ agp_init_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size, void agp_destroy_map(struct agp_map *map) { - struct extent *ex; - - switch (map->bst) { - case I386_BUS_SPACE_IO: - ex = ioport_ex; - break; - - case I386_BUS_SPACE_MEM: - ex = iomem_ex; - break; - - default: - panic("agp_destroy_map: bad bus space tag"); - } - - if (extent_free(ex, map->addr, map->size, + if (extent_free(iomem_ex, map->addr, map->size, EX_NOWAIT | EX_MALLOCOK )) - printf("agp_destroy_map: can't free region\n"); - free(map, M_AGP, 0); + printf("%s: can't free region\n",__func__); + km_free((void *)map->va, PAGE_SIZE, &kv_any, &kp_none); + free(map, M_AGP, sizeof(*map)); } @@ -162,3 +141,33 @@ agp_unmap_subregion(struct agp_map *map, bus_space_handle_t bsh, { return (_bus_space_unmap(map->bst, bsh, size, NULL)); } + +void +agp_map_atomic(struct agp_map *map, bus_size_t offset, + bus_space_handle_t *bshp) +{ + int pmap_flags = PMAP_NOCACHE; + paddr_t pa; + + KASSERT((offset & PGOFSET) == 0); + + if (map->flags & BUS_SPACE_MAP_CACHEABLE) + pmap_flags = 0; + else if (map->flags & BUS_SPACE_MAP_PREFETCHABLE) + pmap_flags = PMAP_WC; + + pa = bus_space_mmap(map->bst, map->addr, offset, 0, 0); + pmap_kenter_pa(map->va, pa | pmap_flags, VM_PROT_READ | VM_PROT_WRITE); + pmap_update(pmap_kernel()); + + *bshp = (bus_space_handle_t)map->va; +} + +void +agp_unmap_atomic(struct agp_map *map, bus_space_handle_t bsh) +{ + KASSERT(bsh == (bus_space_handle_t)map->va); + + pmap_kremove(map->va, PAGE_SIZE); + pmap_update(pmap_kernel()); +} |