diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1999-01-03 17:55:14 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1999-01-03 17:55:14 +0000 |
commit | f9f294a5cb938bf77d479214c5480e09619d428c (patch) | |
tree | 07815f752c3d8e73241c8ff04040e29f1c137062 | |
parent | d22711f6ff76890d56da0120fe0bd9c38ebb60f0 (diff) |
implement bus_space_{un,}map w/ extents
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 141 | ||||
-rw-r--r-- | sys/arch/hppa/include/bus.h | 21 |
2 files changed, 144 insertions, 18 deletions
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 2b745791d30..7b1732b6f1a 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.1 1998/12/30 02:13:52 mickey Exp $ */ +/* $OpenBSD: machdep.c,v 1.2 1999/01/03 17:55:13 mickey Exp $ */ /* * Copyright (c) 1998 Michael Shalayeff @@ -99,6 +99,7 @@ #include <sys/sysctl.h> #include <sys/core.h> #include <sys/kcore.h> +#include <sys/extent.h> #ifdef SYSVMSG #include <sys/msg.h> #endif @@ -172,8 +173,14 @@ struct itlb_stats itlb_stats; struct tlbd_stats tlbd_stats; #endif +int hppa_malloc_ok; +struct extent *hppa_ex; +static long mem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; + void delay_init __P((void)); static __inline void fall __P((int, int, int, int, int)); +int bus_mem_add_mapping __P((bus_addr_t bpa, bus_size_t size, int cacheable, + bus_space_handle_t *bshp)); void hppa_init() @@ -248,6 +255,15 @@ hppa_init() vstart = hppa_round_page(&end); vend = VM_MAX_KERNEL_ADDRESS; + /* we hope this won't fail */ + hppa_ex = extent_create("mem", 0x0, 0xffffffff, M_DEVBUF, + (caddr_t)mem_ex_storage, + sizeof(mem_ex_storage), + EX_NOCOALESCE|EX_NOWAIT); + if (extent_alloc_region(hppa_ex, 0, (vm_offset_t)PAGE0->imm_max_mem, + EX_NOWAIT)) + panic("cannot reserve main memory"); + /* * Allocate space for system data structures. We are given * a starting virtual address and we return a final virtual @@ -503,6 +519,7 @@ cpu_startup() printf("kernel does not support -c; continuing..\n"); #endif } + hppa_malloc_ok = 1; configure(); } @@ -685,6 +702,125 @@ btlb_insert(space, va, pa, lenp, prot) return i; } +int +bus_space_map (t, bpa, size, cacheable, bshp) + bus_space_tag_t t; + bus_addr_t bpa; + bus_size_t size; + int cacheable; + bus_space_handle_t *bshp; +{ + extern u_int virtual_avail; + register int error; + + bpa += HPPA_BUS_TAG_BASE(t); + if ((error = extent_alloc_region(hppa_ex, bpa, size, EX_NOWAIT | + (hppa_malloc_ok? EX_MALLOCOK : 0)))) + return (error); + + if ((bpa > 0 && bpa < virtual_avail) || + (bpa > HPPA_IOBEGIN)) { + *bshp = bpa; + return 0; + } + + if ((error = bus_mem_add_mapping(bpa, size, cacheable, bshp))) { + if (extent_free(hppa_ex, bpa, size, EX_NOWAIT | + (hppa_malloc_ok? EX_MALLOCOK : 0))) { + printf ("bus_space_map: pa 0x%lx, size 0x%lx\n", + bpa, size); + printf ("bus_space_map: can't free region\n"); + } + } + + return 0; +} + +void +bus_space_unmap (t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + register u_long sva, eva; + register bus_addr_t bpa; + + sva = hppa_trunc_page(bsh); + eva = hppa_round_page(bsh + size); + +#ifdef DIAGNOSTIC + if (eva <= sva) + panic("bus_space_unmap: overflow"); +#endif + + bpa = kvtop((caddr_t)bsh); + if (bpa != bsh) + kmem_free(kernel_map, sva, eva - sva); + + if (extent_free(hppa_ex, bpa, size, EX_NOWAIT | + (hppa_malloc_ok? EX_MALLOCOK : 0))) { + printf("bus_space_unmap: ps 0x%lx, size 0x%lx\n", + bpa, size); + printf("bus_space_unmap: can't free region\n"); + } +} + +int +bus_space_alloc (t, rstart, rend, size, align, bndary, cacheable, addrp, bshp) + bus_space_tag_t t; + bus_addr_t rstart, rend; + bus_size_t size, align, bndary; + int cacheable; + bus_addr_t *addrp; + bus_space_handle_t *bshp; +{ + return -1; +} + +void +bus_space_free(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + +} + +int +bus_mem_add_mapping(bpa, size, cacheable, bshp) + bus_addr_t bpa; + bus_size_t size; + int cacheable; + bus_space_handle_t *bshp; +{ + register u_long spa, epa; + register vm_offset_t va; + + spa = hppa_trunc_page(bpa); + epa = hppa_round_page(bpa + size); + +#ifdef DIAGNOSTIC + if (epa <= spa) + panic("bus_mem_add_mapping: overflow"); +#endif + + if (!(va = kmem_alloc_pageable(kernel_map, epa - spa))) + return (ENOMEM); + + *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET)); + + for (; spa < epa; spa += NBPG, va += NBPG) { + pmap_enter(pmap_kernel(), va, spa, + VM_PROT_READ | VM_PROT_WRITE, TRUE); + if (!cacheable) + pmap_changebit(spa, TLB_UNCACHEABLE, ~0); + else + pmap_changebit(spa, 0, ~TLB_UNCACHEABLE); + } + + return 0; +} + void bus_space_barrier(tag, h, off, l, op) bus_space_tag_t tag; @@ -700,7 +836,8 @@ bus_space_barrier(tag, h, off, l, op) p &= ~dcache_line_mask; do { - __asm __volatile ("fdc %%r0(%%sr0,%0)":: "r" (p)); + __asm __volatile ("pdc %%r0(%%sr0,%0)":: "r" (p)); + __asm __volatile ("fic %%r0(%%sr0,%0)":: "r" (p)); p += dcache_line_mask + 1; l -= dcache_line_mask + 1; } while (l); diff --git a/sys/arch/hppa/include/bus.h b/sys/arch/hppa/include/bus.h index cd56d46b65a..0720798268a 100644 --- a/sys/arch/hppa/include/bus.h +++ b/sys/arch/hppa/include/bus.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bus.h,v 1.6 1998/12/29 22:20:27 mickey Exp $ */ +/* $OpenBSD: bus.h,v 1.7 1999/01/03 17:55:13 mickey Exp $ */ /* * Copyright (c) 1998 Michael Shalayeff @@ -52,21 +52,10 @@ typedef u_long bus_space_handle_t; __asm __volatile ("rsm %1, %%r0\n\tfdc %%r0(%0)\n\tssm %1, %%r0" \ :: "r" (pa), "i" (PSW_D)); -/* no extent handlng for now - we won't have overlaps from PDC anyway */ -static __inline int -bus_space_map (bus_space_tag_t t, bus_addr_t addr, bus_size_t size, - int cacheable, bus_space_handle_t *bshp) -{ - *bshp = addr + HPPA_BUS_TAG_BASE(t); - return 0; -} - -static __inline void -bus_space_unmap (bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) -{ - /* nothing to do */ -} +int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr, bus_size_t size, + int cacheable, bus_space_handle_t *bshp)); +void bus_space_unmap __P((bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t size)); int bus_space_subregion __P((bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)); |