diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1998-12-30 02:13:53 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1998-12-30 02:13:53 +0000 |
commit | 72acd704233e7498e6e2e108ba1b339e52b6c9c7 (patch) | |
tree | 024b00ed6ba320e7d4ca9194703c3e00417dae11 /sys/arch | |
parent | c3b8cc3af16e7116fc97398772c72603698d1e0d (diff) |
machdep; more work needed
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 956 |
1 files changed, 956 insertions, 0 deletions
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c new file mode 100644 index 00000000000..2b745791d30 --- /dev/null +++ b/sys/arch/hppa/hppa/machdep.c @@ -0,0 +1,956 @@ +/* $OpenBSD: machdep.c,v 1.1 1998/12/30 02:13:52 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright 1996 1995 by Open Software Foundation, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * (c) Copyright 1988 HEWLETT-PACKARD COMPANY + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Hewlett-Packard Company not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Hewlett-Packard Company makes no representations about the + * suitability of this software for any purpose. + */ +/* + * Copyright (c) 1990,1991,1992,1994 The University of Utah and + * the Computer Systems Laboratory (CSL). All rights reserved. + * + * THE UNIVERSITY OF UTAH AND CSL PROVIDE THIS SOFTWARE IN ITS "AS IS" + * CONDITION, AND DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES + * WHATSOEVER RESULTING FROM ITS USE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Utah $Hdr: model_dep.c 1.34 94/12/14$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/signalvar.h> +#include <sys/kernel.h> +#include <sys/map.h> +#include <sys/proc.h> +#include <sys/buf.h> +#include <sys/reboot.h> +#include <sys/device.h> +#include <sys/conf.h> +#include <sys/file.h> +#include <sys/callout.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/msgbuf.h> +#include <sys/ioctl.h> +#include <sys/tty.h> +#include <sys/user.h> +#include <sys/exec.h> +#include <sys/sysctl.h> +#include <sys/core.h> +#include <sys/kcore.h> +#ifdef SYSVMSG +#include <sys/msg.h> +#endif +#ifdef SYSVSEM +#include <sys/sem.h> +#endif +#ifdef SYSVSHM +#include <sys/shm.h> +#endif + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> +#include <vm/vm_page.h> + +#include <dev/cons.h> + +#include <machine/pdc.h> +#include <machine/iomod.h> +#include <machine/psl.h> +#include <machine/reg.h> +#include <machine/cpufunc.h> +#include <machine/autoconf.h> + +#ifdef DDB +#include <machine/db_machdep.h> +#include <ddb/db_access.h> +#include <ddb/db_sym.h> +#include <ddb/db_extern.h> +#endif + +#include <hppa/dev/boards.h> +#include <hppa/dev/boards_data.h> + +/* + * Declare these as initialized data so we can patch them. + */ +int nswbuf = 0; + + +vm_offset_t istackptr; +int cold = 1; +int kernelmapped; /* set when kernel is mapped */ +int msgbufmapped; /* set when safe to use msgbuf */ + +/* + * used in locore.S + */ +struct pdc_cache pdc_cache PDC_ALIGNMENT; +int icache_stride; +int dcache_stride; +int dcache_line_mask; +int dcache_size; +double fpu_zero = 0.0; + +/* the following is used externally (sysctl_hw) */ +char machine[] = "hppa"; +char cpu_model[128]; +u_int cpu_ticksnum, cpu_ticksdenom, cpu_hzticks; +dev_t bootdev; +int totalphysmem, physmem, resvmem, esym; +struct user *proc0paddr; +int copr_sfu_config; +int fpcopr_version; + +#ifdef TLB_STATS +struct dtlb_stats dtlb_stats; +struct itlb_stats itlb_stats; +struct tlbd_stats tlbd_stats; +#endif + +void delay_init __P((void)); +static __inline void fall __P((int, int, int, int, int)); + +void +hppa_init() +{ + extern int kernel_text, end; + struct pdc_hwtlb pdc_hwtlb PDC_ALIGNMENT; + struct pdc_coproc pdc_coproc PDC_ALIGNMENT; + vm_offset_t v, vstart, vend; + register int pdcerr; + int usehpt; + + /* init PDC iface, so we can call em easy */ + pdc_init(); + + /* calculate cpu speed */ + cpu_hzticks = (PAGE0->mem_10msec * 100) / hz; + delay_init(); + + /* + * get cache parameters from the PDC + */ + if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_DFLT, + &pdc_cache)) < 0) { +#ifdef DIAGNOSTIC + printf("Warning: PDC_CACHE call Ret'd %d\n", pdcerr); +#endif + } + + dcache_line_mask = pdc_cache.dc_conf.cc_line * 16 - 1; + dcache_size = pdc_cache.dc_size; + dcache_stride = pdc_cache.dc_stride; + icache_stride = pdc_cache.ic_stride; + + /* + * purge TLBs and flush caches + */ + if (pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_PURGE_ALL) < 0) + printf("WARNING: BTLB purge failed\n"); + ptlball(); + fcacheall(); + + /* calculate HPT size */ + hpt_hashsize = PAGE0->imm_max_mem / NBPG; + mtctl(hpt_hashsize - 1, CR_HPTMASK); + + /* + * If we want to use the HW TLB support, ensure that it exists. + */ + if (pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_INFO, &pdc_hwtlb) && + !pdc_hwtlb.min_size && !pdc_hwtlb.max_size) { + printf("WARNING: no HW tlb walker\n"); + usehpt = 0; + } else { + usehpt = 1; +#ifdef DEBUG + printf("hwtlb: %u-%u, %u/", + pdc_hwtlb.min_size, pdc_hwtlb.max_size, hpt_hashsize); +#endif + if (hpt_hashsize > pdc_hwtlb.max_size) + hpt_hashsize = pdc_hwtlb.max_size; + else if (hpt_hashsize < pdc_hwtlb.min_size) + hpt_hashsize = pdc_hwtlb.min_size; +#ifdef DEBUG + printf("%u (0x%x)\n", hpt_hashsize, + hpt_hashsize * sizeof(struct hpt_entry)); +#endif + } + + totalphysmem = PAGE0->imm_max_mem / NBPG; + resvmem = ((vm_offset_t)&kernel_text) / NBPG; + + vstart = hppa_round_page(&end); + vend = VM_MAX_KERNEL_ADDRESS; + + /* + * Allocate space for system data structures. We are given + * a starting virtual address and we return a final virtual + * address; along the way we set each data structure pointer. + * + * We call allocsys() with 0 to find out how much space we want, + * allocate that much and fill it with zeroes, and the call + * allocsys() again with the correct base virtual address. + */ + + v = vstart; +#define valloc(name, type, num) \ + (name) = (type *)v; v = (vm_offset_t)((name)+(num)) + +#ifdef REAL_CLISTS + valloc(cfree, struct cblock, nclist); +#endif + valloc(callout, struct callout, ncallout); + nswapmap = maxproc * 2; + valloc(swapmap, struct map, nswapmap); +#ifdef SYSVSHM + valloc(shmsegs, struct shmid_ds, shminfo.shmmni); +#endif +#ifdef SYSVSEM + valloc(sema, struct semid_ds, seminfo.semmni); + valloc(sem, struct sem, seminfo.semmns); + /* This is pretty disgusting! */ + valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); +#endif +#ifdef SYSVMSG + valloc(msgpool, char, msginfo.msgmax); + valloc(msgmaps, struct msgmap, msginfo.msgseg); + valloc(msghdrs, struct msg, msginfo.msgtql); + valloc(msqids, struct msqid_ds, msginfo.msgmni); +#endif + +#ifndef BUFCACHEPERCENT +#define BUFCACHEPERCENT 10 +#endif /* BUFCACHEPERCENT */ + + if (bufpages == 0) + bufpages = totalphysmem / BUFCACHEPERCENT / CLSIZE; + if (nbuf == 0) { + nbuf = bufpages; + if (nbuf < 16) + nbuf = 16; + } + + /* Restrict to at most 70% filled kvm */ + if (nbuf * MAXBSIZE > + (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) * 7 / 10) + nbuf = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / + MAXBSIZE * 7 / 10; + + /* More buffer pages than fits into the buffers is senseless. */ + if (bufpages > nbuf * MAXBSIZE / CLBYTES) + bufpages = nbuf * MAXBSIZE / CLBYTES; + + if (nswbuf == 0) { + nswbuf = (nbuf / 2) & ~1; /* force even */ + if (nswbuf > 256) + nswbuf = 256; /* sanity */ + } + + valloc(swbuf, struct buf, nswbuf); + valloc(buf, struct buf, nbuf); +#undef valloc + bzero ((void *)vstart, (v - vstart)); + vstart = v; + + pmap_bootstrap(&vstart, &vend); + physmem = totalphysmem - btoc(vstart); + + /* alloc msgbuf */ + if (!(msgbufp = (void *)pmap_steal_memory(sizeof(struct msgbuf), + NULL, NULL))) + panic("cannot allocate msgbuf"); + msgbufmapped = 1; + +#ifdef DEBUG + printf("mem: %x+%x, %x\n", physmem, resvmem, totalphysmem); +#endif + /* Turn on the HW TLB assist */ + if (usehpt) { + if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_TLB, + PDC_TLB_CONFIG, &pdc_hwtlb, hpt_table, + sizeof(struct hpt_entry) * hpt_hashsize, + PDC_TLB_WORD3)) < 0) { + printf("Warning: HW TLB init failed (%d), disabled\n", + pdcerr); + usehpt = 0; + } else + printf("HW TLB(%d entries at 0x%x) initialized (%d)\n", + hpt_hashsize, hpt_table, pdcerr); + } + + /* + * Locate any coprocessors and enable them by setting up the CCR. + * SFU's are ignored (since we dont have any). Also, initialize + * the floating point registers here. + */ + if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT, + &pdc_coproc)) < 0) + printf("WARNING: PDC_COPROC call Ret'd %d\n", pdcerr); + else { +#ifdef DEBUG + printf("pdc_coproc: %x, %x\n", pdc_coproc.ccr_enable, + pdc_coproc.ccr_present); +#endif + } + copr_sfu_config = pdc_coproc.ccr_enable; + mtctl(copr_sfu_config & CCR_MASK, CR_CCR); +/* + fprinit(&fpcopr_version); + fpcopr_version = (fpcopr_version & 0x003ff800) >> 11; + mtctl(CR_CCR, 0); +*/ + /* + * Clear the FAULT light (so we know when we get a real one) + * PDC_COPROC apparently turns it on (for whatever reason). + */ + pdcerr = PDC_OSTAT(PDC_OSTAT_RUN) | 0xCEC0; + (void) (*pdc)(PDC_CHASSIS, PDC_CHASSIS_DISP, pdcerr); + +#ifdef DDB + ddb_init(); +#endif +#ifdef DEBUG + printf("hppa_init: leaving\n"); +#endif + kernelmapped++; +} + +void +cpu_startup() +{ + struct pdc_model pdc_model; + register const struct hppa_board_info *bip; + vm_offset_t minaddr, maxaddr; + vm_size_t size; + int base, residual; + int err, i; +#ifdef DEBUG + extern int pmapdebug; + int opmapdebug = pmapdebug; + + pmapdebug = 0; +#endif + + /* good night */ + printf(version); + + /* identify system type */ + if ((err = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO, + &pdc_model)) < 0) { +#ifdef DEBUG + printf("WARNING: PDC_MODEL failed (%d)\n", err); +#endif + } else { + i = pdc_model.hvers >> 4; /* board type */ + for (bip = hppa_knownboards; + bip->bi_id >= 0 && bip->bi_id != i; bip++); + if (bip->bi_id >= 0) { + /* my babe said: 6010, 481, 0, 0, 77b657b1, 0, 4 */ + sprintf(cpu_model, "HP9000/%s rev %x", + bip->bi_name, pdc_model.arch_rev); + } else + sprintf(cpu_model, "HP9000/(UNKNOWN %x)", i); + printf("%s\n", cpu_model); + } + + printf("real mem = %d (%d reserved for PROM, %d used by OpenBSD)\n", + ctob(totalphysmem), ctob(resvmem), ctob(physmem)); + + /* + * Now allocate buffers proper. They are different than the above + * in that they usually occupy more virtual memory than physical. + */ + size = MAXBSIZE * nbuf; + buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers, + &maxaddr, size, TRUE); + minaddr = (vm_offset_t)buffers; + if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0, + &minaddr, size, FALSE) != KERN_SUCCESS) + panic("cpu_startup: cannot allocate buffers"); + + base = bufpages / nbuf; + residual = bufpages % nbuf; + for (i = 0; i < nbuf; i++) { + /* + * First <residual> buffers get (base+1) physical pages + * allocated for them. The rest get (base) physical pages. + * + * The rest of each buffer occupies virtual space, + * but has no physical memory allocated for it. + */ + vm_map_pageable(buffer_map, minaddr, minaddr + + CLBYTES * (base + (i < residual)), FALSE); + vm_map_simplify(buffer_map, minaddr); + minaddr += MAXBSIZE; + } + + /* + * Allocate a submap for exec arguments. This map effectively + * limits the number of processes exec'ing at any time. + */ + exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, + 16*NCARGS, TRUE); + + /* + * Allocate a submap for physio + */ + phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, + VM_PHYS_SIZE, TRUE); + + /* + * Finally, allocate mbuf pool. Since mclrefcnt is an off-size + * we use the more space efficient malloc in place of kmem_alloc. + */ + mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, + M_MBUF, M_NOWAIT); + bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); + mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, + VM_MBUF_SIZE, FALSE); + + /* + * Initialize callouts + */ + callfree = callout; + for (i = 1; i < ncallout; i++) + callout[i-1].c_next = &callout[i]; + callout[i-1].c_next = NULL; + +#ifdef DEBUG + pmapdebug = opmapdebug; +#endif + printf("avail mem = %ld\n", ptoa(cnt.v_free_count)); + printf("using %d buffers containing %d bytes of memory\n", + nbuf, bufpages * CLBYTES); + + /* + * Set up buffers, so they can be used to read disk labels. + */ + bufinit(); + + /* + * Configure the system. + */ + if (boothowto & RB_CONFIG) { +#ifdef BOOT_CONFIG + user_config(); +#else + printf("kernel does not support -c; continuing..\n"); +#endif + } + configure(); +} + +/* + * compute cpu_ticksdenom and cpu_ticksnum such as: + * + * cpu_ticksnum / cpu_ticksdenom = t + delta + * delta -> 0 + */ +void +delay_init(void) +{ + register u_int num, denom, delta, mdelta; + + mdelta = UINT_MAX; + for (denom = 1; denom < 1000; denom++) { + num = (PAGE0->mem_10msec * denom) / 10000; + delta = num * 10000 / denom - PAGE0->mem_10msec; + if (!delta) { + cpu_ticksdenom = denom; + cpu_ticksnum = num; + break; + } else if (delta < mdelta) { + cpu_ticksdenom = denom; + cpu_ticksnum = num; + } + } +} + +void +delay(us) + u_int us; +{ + register u_int start, end, n; + + mfctl(CR_ITMR, start); + while (us) { + n = min(100, us); + end = start + n * cpu_ticksnum / cpu_ticksdenom; + + /* N.B. Interval Timer may wrap around */ + if (end < start) + do + mfctl(CR_ITMR, start); + while (start > end); + + do + mfctl(CR_ITMR, start); + while (start < end); + + us -= n; + mfctl(CR_ITMR, start); + } +} + +static __inline void +fall(c_base, c_count, c_loop, c_stride, data) + int c_base, c_count, c_loop, c_stride, data; +{ + register int loop; /* Internal vars */ + + for (; c_count--; c_base += c_stride) + for (loop = c_loop; loop--; ) + if (data) + fdce(0, c_base); + else + fice(0, c_base); + +} + +void +fcacheall() +{ + /* + * Flush the instruction, then data cache. + */ + fall (pdc_cache.ic_base, pdc_cache.ic_count, + pdc_cache.ic_loop, pdc_cache.ic_stride, 0); + sync_caches(); + fall (pdc_cache.dc_base, pdc_cache.dc_count, + pdc_cache.dc_loop, pdc_cache.dc_stride, 1); + sync_caches(); +} + +void +ptlball() +{ + register pa_space_t sp; + register vm_offset_t off; + register int six, oix, lix; + int sixend, oixend, lixend; + + /* instruction TLB */ + sixend = pdc_cache.it_sp_count; + oixend = pdc_cache.it_off_count; + lixend = pdc_cache.it_loop; + sp = pdc_cache.it_sp_base; + for (six = 0; six < sixend; six++) { + off = pdc_cache.it_off_base; + for (oix = 0; oix < oixend; oix++) { + for (lix = 0; lix < lixend; lix++) + pitlbe(sp, off); + off += pdc_cache.it_off_stride; + } + sp += pdc_cache.it_sp_stride; + } + + /* data TLB */ + sixend = pdc_cache.dt_sp_count; + oixend = pdc_cache.dt_off_count; + lixend = pdc_cache.dt_loop; + sp = pdc_cache.dt_sp_base; + for (six = 0; six < sixend; six++) { + off = pdc_cache.dt_off_base; + for (oix = 0; oix < oixend; oix++) { + for (lix = 0; lix < lixend; lix++) + pdtlbe(sp, off); + off += pdc_cache.dt_off_stride; + } + sp += pdc_cache.dt_sp_stride; + } +} + +int +btlb_insert(space, va, pa, lenp, prot) + pa_space_t space; + vm_offset_t va, pa; + vm_size_t *lenp; + u_int prot; +{ + static u_int32_t mask; + struct pdc_btlb pdc_btlb PDC_ALIGNMENT; + register vm_size_t len; + register int pdcerr, i; + + if ((pdcerr = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, + PDC_BTLB_DEFAULT, &pdc_btlb)) < 0) { +#ifdef DEBUG + printf("WARNING: PDC_BTLB call Ret'd %d\n", pdcerr); +#endif + return -1; + } + + /* align size */ + for (len = pdc_btlb.min_size << PGSHIFT; len < *lenp; len <<= 1); + len >>= PGSHIFT; + i = ffs(~mask) - 1; + if (len > pdc_btlb.max_size || i < 0) { +#ifdef DEBUG + printf("btln_insert: too big (%u < %u < %u)\n", + pdc_btlb.min_size, len, pdc_btlb.max_size); +#endif + return -(ENOMEM); + } + + mask |= 1 << i; + pa >>= PGSHIFT; + va >>= PGSHIFT; + /* check address alignment */ + if (pa & (len - 1)) + printf("WARNING: BTLB address misaligned\n"); + + /* ensure IO space is uncached */ + if ((pa & 0xF0000) == 0xF0000) + prot |= TLB_UNCACHEABLE; + +#ifdef DEBUG + printf ("btlb_insert(%d): %x:%x, %x, %x, %x\n", + i, space, va, pa, len, prot); +#endif + if (pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_INSERT, + space, va, pa, len, prot, i) < 0) { +#ifdef DEBUG + printf("WARNING: BTLB insert failed (%d)\n", pdcerr); +#endif + return -(EINVAL); + } + *lenp = len << PGSHIFT; + + return i; +} + +void +bus_space_barrier(tag, h, off, l, op) + bus_space_tag_t tag; + bus_space_handle_t h; + bus_addr_t off; + bus_size_t l; + int op; +{ + register u_int32_t p = h + off; + + l += p & dcache_line_mask; + l = (l + dcache_line_mask) & ~dcache_line_mask; + p &= ~dcache_line_mask; + + do { + __asm __volatile ("fdc %%r0(%%sr0,%0)":: "r" (p)); + p += dcache_line_mask + 1; + l -= dcache_line_mask + 1; + } while (l); +} + +void +boot(howto) + int howto; +{ + /* TODO: probably save howto into stable storage */ + + if (howto & RB_HALT) { + printf("System halted!\n"); + splhigh(); + __asm __volatile("stwas %0, 0(%1)" + :: "r" (CMD_STOP), + "r" (LBCAST_ADDR + iomod_command)); + } else { + printf("rebooting..."); + DELAY(1000000); + __asm __volatile("stwas %0, 0(%1)" + :: "r" (CMD_RESET), + "r" (LBCAST_ADDR + iomod_command)); + } + + for(;;); /* loop while bus reset is comming up */ + /* NOTREACHED */ +} + +int +copystr(src, dst, size, lenp) + const void *src; + void *dst; + size_t size; + size_t *lenp; +{ + return 0; +} + +int +copyinstr(src, dst, size, lenp) + const void *src; + void *dst; + size_t size; + size_t *lenp; +{ + return 0; +} + + +int +copyoutstr(src, dst, size, lenp) + const void *src; + void *dst; + size_t size; + size_t *lenp; +{ + return 0; +} + + +int +copyin(src, dst, size) + const void *src; + void *dst; + size_t size; +{ + return 0; +} + +int +copyout(src, dst, size) + const void *src; + void *dst; + size_t size; +{ + return 0; +} + +int +fubyte(addr) + const void *addr; +{ + return 0; +} + +int +subyte(addr, val) + void *addr; + int val; +{ + return 0; +} + +int +suibyte(addr, val) + void *addr; + int val; +{ + return 0; +} + +long +fuword(addr) + const void *addr; +{ + return 0; +} + +long +fuiword(addr) + const void *addr; +{ + return 0; +} + +int +suword(addr, val) + void *addr; + long val; +{ + return 0; +} + +int +suiword(addr, val) + void *addr; + long val; +{ + return 0; +} + +int +fuswintr(addr) + const caddr_t addr; +{ + return 0; +} + +int +suswintr(addr, val) + caddr_t addr; + u_int val; +{ + return 0; +} + + +/* + * setrunqueue(p) + * proc *p; + * + * Call should be made at splclock(), and p->p_stat should be SRUN. + */ +void +setrunqueue(p) +struct proc *p; +{ + +} + +/* + * remrunqueue(p) + * + * Call should be made at splclock(). + */ +void +remrunqueue(p) + struct proc *p; +{ +} + +/* + * Set registers on exec. + */ +void +setregs(p, pack, stack, retval) + register struct proc *p; + struct exec_package *pack; + u_long stack; + register_t *retval; +{ +} + +/* + * Send an interrupt to process. + */ +void +sendsig(catcher, sig, mask, code, type, val) + sig_t catcher; + int sig, mask; + u_long code; + int type; + union sigval val; +{ + +} + +int +sys_sigreturn(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + return EINVAL; +} + +/* + * machine dependent system variables. + */ +int +cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) + int *name; + u_int namelen; + void *oldp; + size_t *oldlenp; + void *newp; + size_t newlen; + struct proc *p; +{ + dev_t consdev; + /* all sysctl names at this level are terminal */ + if (namelen != 1) + return (ENOTDIR); /* overloaded */ + switch (name[0]) { + case CPU_CONSDEV: + if (cn_tab != NULL) + consdev = cn_tab->cn_dev; + else + consdev = NODEV; + return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, + sizeof consdev)); + default: + return (EOPNOTSUPP); + } + /* NOTREACHED */ +} + + +/* + * consinit: + * initialize the system console. + */ +void +consinit() +{ + static int initted; + + if (!initted) { + initted++; + cninit(); + } +} |