[BACK]Return to machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / hppa64 / hppa64

Annotation of sys/arch/hppa64/hppa64/machdep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: machdep.c,v 1.7 2007/06/06 17:15:12 deraadt Exp $     */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Michael Shalayeff
                      5:  * All rights reserved.
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
                     16:  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: #include <sys/param.h>
                     21: #include <sys/systm.h>
                     22: #include <sys/signalvar.h>
                     23: #include <sys/kernel.h>
                     24: #include <sys/proc.h>
                     25: #include <sys/buf.h>
                     26: #include <sys/reboot.h>
                     27: #include <sys/device.h>
                     28: #include <sys/conf.h>
                     29: #include <sys/file.h>
                     30: #include <sys/timeout.h>
                     31: #include <sys/malloc.h>
                     32: #include <sys/mbuf.h>
                     33: #include <sys/msgbuf.h>
                     34: #include <sys/ioctl.h>
                     35: #include <sys/tty.h>
                     36: #include <sys/user.h>
                     37: #include <sys/exec.h>
                     38: #include <sys/sysctl.h>
                     39: #include <sys/core.h>
                     40: #include <sys/kcore.h>
                     41: #include <sys/extent.h>
                     42: #ifdef SYSVMSG
                     43: #include <sys/msg.h>
                     44: #endif
                     45:
                     46: #include <sys/mount.h>
                     47: #include <sys/syscallargs.h>
                     48:
                     49: #include <uvm/uvm.h>
                     50: #include <uvm/uvm_page.h>
                     51:
                     52: #include <dev/cons.h>
                     53: #include <dev/clock_subr.h>
                     54:
                     55: #include <machine/pdc.h>
                     56: #include <machine/iomod.h>
                     57: #include <machine/psl.h>
                     58: #include <machine/reg.h>
                     59: #include <machine/autoconf.h>
                     60: #include <machine/kcore.h>
                     61:
                     62: #ifdef COMPAT_HPUX
                     63: #include <compat/hpux/hpux.h>
                     64: #endif
                     65:
                     66: #ifdef DDB
                     67: #include <machine/db_machdep.h>
                     68: #include <ddb/db_access.h>
                     69: #include <ddb/db_sym.h>
                     70: #include <ddb/db_extern.h>
                     71: #endif
                     72:
                     73: #include <hppa/dev/cpudevs.h>
                     74:
                     75: /*
                     76:  * Patchable buffer cache parameters
                     77:  */
                     78: #ifndef BUFCACHEPERCENT
                     79: #define BUFCACHEPERCENT 10
                     80: #endif /* BUFCACHEPERCENT */
                     81:
                     82: #ifdef BUFPAGES
                     83: int bufpages = BUFPAGES;
                     84: #else
                     85: int bufpages = 0;
                     86: #endif
                     87: int bufcachepercent = BUFCACHEPERCENT;
                     88:
                     89: /*
                     90:  * Different kinds of flags used throughout the kernel.
                     91:  */
                     92: int cold = 1;                  /* unset when engine is up to go */
                     93: extern int msgbufmapped;       /* set when safe to use msgbuf */
                     94:
                     95: /*
                     96:  * cache configuration, for most machines is the same
                     97:  * numbers, so it makes sense to do defines w/ numbers depending
                     98:  * on configured cpu types in the kernel
                     99:  */
                    100: int icache_stride, icache_line_mask;
                    101: int dcache_stride, dcache_line_mask;
                    102:
                    103: /*
                    104:  * things to not kill
                    105:  */
                    106: volatile u_int8_t *machine_ledaddr;
                    107: int machine_ledword, machine_leds;
                    108: struct cpu_info cpu0_info;
                    109:
                    110: /*
                    111:  * CPU params (should be the same for all cpus in the system)
                    112:  */
                    113: struct pdc_cache pdc_cache PDC_ALIGNMENT;
                    114: struct pdc_model pdc_model PDC_ALIGNMENT;
                    115:
                    116:        /* w/ a little deviation should be the same for all installed cpus */
                    117: u_int  cpu_ticksnum, cpu_ticksdenom;
                    118:
                    119:        /* exported info */
                    120: char   machine[] = MACHINE;
                    121: char   cpu_model[128];
                    122: int    cpu_hvers;
                    123: enum hppa_cpu_type cpu_type;
                    124: const char *cpu_typename;
                    125: u_int  fpu_version;
                    126: #ifdef COMPAT_HPUX
                    127: int    cpu_model_hpux; /* contains HPUX_SYSCONF_CPU* kind of value */
                    128: #endif
                    129:
                    130: dev_t  bootdev;
                    131: int    physmem, resvmem, resvphysmem, esym;
                    132: paddr_t        avail_end;
                    133:
                    134: /*
                    135:  * Things for MI glue to stick on.
                    136:  */
                    137: struct user *proc0paddr;
                    138: long mem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(32) / sizeof(long)];
                    139: struct extent *hppa_ex;
                    140:
                    141: struct vm_map *exec_map = NULL;
                    142: struct vm_map *phys_map = NULL;
                    143: /* Virtual page frame for /dev/mem (see mem.c) */
                    144: vaddr_t vmmap;
                    145:
                    146: void delay_init(void);
                    147: static __inline void fall(int, int, int, int, int);
                    148: void dumpsys(void);
                    149: void hpmc_dump(void);
                    150: void cpuid(void);
                    151:
                    152: /*
                    153:  * wide used hardware params
                    154:  */
                    155: struct pdc_hwtlb pdc_hwtlb PDC_ALIGNMENT;
                    156: struct pdc_coproc pdc_coproc PDC_ALIGNMENT;
                    157: struct pdc_coherence pdc_coherence PDC_ALIGNMENT;
                    158: struct pdc_spidb pdc_spidbits PDC_ALIGNMENT;
                    159: struct pdc_model pdc_model PDC_ALIGNMENT;
                    160:
                    161: #ifdef DEBUG
                    162: int sigdebug = 0;
                    163: pid_t sigpid = 0;
                    164: #define SDB_FOLLOW     0x01
                    165: #endif
                    166:
                    167: int
                    168: hppa_cpuspeed(int *mhz)
                    169: {
                    170:        *mhz = PAGE0->mem_10msec / 10000;
                    171:
                    172:        return (0);
                    173: }
                    174:
                    175: void
                    176: hppa_init(start)
                    177:        paddr_t start;
                    178: {
                    179:        extern int kernel_text;
                    180:        int error;
                    181:
                    182:        mtctl((long)&cpu0_info, 24);
                    183:
                    184:        pdc_init();     /* init PDC iface, so we can call em easy */
                    185:
                    186:        delay_init();   /* calculate cpu clock ratio */
                    187:
                    188:        cpuid();
                    189:
                    190:        /* cache parameters */
                    191:        if ((error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_DFLT,
                    192:            &pdc_cache)) < 0) {
                    193: #ifdef DEBUG
                    194:                printf("WARNING: PDC_CACHE error %d\n", error);
                    195: #endif
                    196:        }
                    197:
                    198:        dcache_line_mask = pdc_cache.dc_conf.cc_line * 16 - 1;
                    199:        dcache_stride = pdc_cache.dc_stride;
                    200:        icache_line_mask = pdc_cache.ic_conf.cc_line * 16 - 1;
                    201:        icache_stride = pdc_cache.ic_stride;
                    202:
                    203:        /* cache coherence params (pbably available for 8k only) */
                    204:        error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_SETCS,
                    205:            &pdc_coherence, 1, 1, 1, 1);
                    206: #ifdef DEBUG
                    207:        printf ("PDC_CACHE_SETCS: %d, %d, %d, %d (%d)\n",
                    208:            pdc_coherence.ia_cst, pdc_coherence.da_cst,
                    209:            pdc_coherence.ita_cst, pdc_coherence.dta_cst, error);
                    210: #endif
                    211:        error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_GETSPIDB,
                    212:            &pdc_spidbits, 0, 0, 0, 0);
                    213:        printf("SPID bits: 0x%x, error = %d\n", pdc_spidbits.spidbits, error);
                    214:
                    215: #if 0
                    216: TODO hpmc/toc/pfr
                    217:        /* setup hpmc handler */
                    218:        {
                    219:                extern u_int hpmc_v[];  /* from locore.s */
                    220:                register u_int *p = hpmc_v;
                    221:
                    222:                if (pdc_call((iodcio_t)pdc, 0, PDC_INSTR, PDC_INSTR_DFLT, p))
                    223:                        *p = 0x08000240;
                    224:
                    225:                p[6] = (u_int)&hpmc_dump;
                    226:                p[7] = 32;
                    227:                p[5] = -(p[0] + p[1] + p[2] + p[3] + p[4] + p[6] + p[7]);
                    228:        }
                    229:
                    230:        {
                    231:                extern u_int hppa_toc[], hppa_toc_end[];
                    232:                register u_int cksum, *p;
                    233:
                    234:                for (cksum = 0, p = hppa_toc; p < hppa_toc_end; p++)
                    235:                        cksum += *p;
                    236:
                    237:                *p = cksum;
                    238:                PAGE0->ivec_toc = (u_int)&hppa_toc[0];
                    239:                PAGE0->ivec_toclen = (hppa_toc_end - hppa_toc + 1) * 4;
                    240:        }
                    241:
                    242:        {
                    243:                extern u_int hppa_pfr[], hppa_pfr_end[];
                    244:                register u_int cksum, *p;
                    245:
                    246:                for (cksum = 0, p = hppa_pfr; p < hppa_pfr_end; p++)
                    247:                        cksum += *p;
                    248:
                    249:                *p = cksum;
                    250:                PAGE0->ivec_mempf = (u_int)&hppa_pfr[0];
                    251:                PAGE0->ivec_mempflen = (hppa_pfr_end - hppa_pfr + 1) * 4;
                    252:        }
                    253: #endif
                    254:        avail_end = trunc_page(PAGE0->imm_max_mem);
                    255:        if (avail_end > 0x4000000)
                    256:                avail_end = 0x4000000;
                    257:        physmem = btoc(avail_end);
                    258:        resvmem = btoc(((vaddr_t)&kernel_text));
                    259:
                    260:        /* we hope this won't fail */
                    261:        hppa_ex = extent_create("mem", 0, HPPA_PHYSMAP, M_DEVBUF,
                    262:            (caddr_t)mem_ex_storage, sizeof(mem_ex_storage),
                    263:            EX_NOCOALESCE|EX_NOWAIT);
                    264:        if (extent_alloc_region(hppa_ex, 0, (vaddr_t)PAGE0->imm_max_mem,
                    265:            EX_NOWAIT))
                    266:                panic("cannot reserve main memory");
                    267:
                    268: #ifdef SYSVMSG
                    269: {
                    270:        vaddr_t v;
                    271:
                    272:        v = round_page(start);
                    273: #define valloc(name, type, num) (name) = (type *)v; v = (vaddr_t)((name)+(num))
                    274:        valloc(msgpool, char, msginfo.msgmax);
                    275:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
                    276:        valloc(msghdrs, struct msg, msginfo.msgtql);
                    277:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
                    278: #undef valloc
                    279:        v = round_page(v);
                    280:        bzero ((void *)start, (v - start));
                    281:        start = v;
                    282: }
                    283: #endif
                    284:        /* sets resvphysmem */
                    285:        pmap_bootstrap(start);
                    286:
                    287:        /* space has been reserved in pmap_bootstrap() */
                    288:        msgbufp = (struct msgbuf *)((vaddr_t)ptoa(physmem) -
                    289:            round_page(MSGBUFSIZE));
                    290:        initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
                    291:        msgbufmapped = 1;
                    292:
                    293:        /* they say PDC_COPROC might turn fault light on */
                    294:        pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_DISP,
                    295:            PDC_OSTAT(PDC_OSTAT_RUN) | 0xCEC0);
                    296:
                    297:        cpu_cpuspeed = &hppa_cpuspeed;
                    298:
                    299: #ifdef DDB
                    300:        ddb_init();
                    301:        if (boothowto & RB_KDB)
                    302:                Debugger();
                    303: #endif
                    304:        ptlball();
                    305:        ficacheall();
                    306:        fdcacheall();
                    307: printf("out\n");
                    308: }
                    309:
                    310: void
                    311: cpuid()
                    312: {
                    313:        extern u_int fpu_enable;
                    314:        struct pdc_cpuid pdc_cpuid PDC_ALIGNMENT;
                    315:        int error;
                    316:
                    317:        /* identify system type */
                    318:        if ((error = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO,
                    319:            &pdc_model)) < 0) {
                    320: #ifdef DEBUG
                    321:                printf("WARNING: PDC_MODEL error %d\n", error);
                    322: #endif
                    323:                pdc_model.hvers = 0;
                    324:        }
                    325:
                    326:        bzero(&pdc_cpuid, sizeof(pdc_cpuid));
                    327:        if (pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_CPUID,
                    328:            &pdc_cpuid, 0, 0, 0, 0) >= 0) {
                    329:
                    330:                /* patch for old 8200 */
                    331:                if (pdc_cpuid.version == HPPA_CPU_PCXU &&
                    332:                    pdc_cpuid.revision > 0x0d)
                    333:                        pdc_cpuid.version = HPPA_CPU_PCXUP;
                    334:
                    335:                cpu_type = pdc_cpuid.version;
                    336:        }
                    337:
                    338:        /* locate coprocessors and SFUs */
                    339:        bzero(&pdc_coproc, sizeof(pdc_coproc));
                    340:        if ((error = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT,
                    341:            &pdc_coproc, 0, 0, 0, 0)) < 0)
                    342:                printf("WARNING: PDC_COPROC error %d\n", error);
                    343:        else {
                    344:                printf("pdc_coproc: 0x%x, 0x%x; model %x rev %x\n",
                    345:                    pdc_coproc.ccr_enable, pdc_coproc.ccr_present,
                    346:                    pdc_coproc.fpu_model, pdc_coproc.fpu_revision);
                    347:                fpu_enable = pdc_coproc.ccr_enable & 0xc0;
                    348:
                    349:                /* a kludge to detect PCXW */
                    350:                if (pdc_coproc.fpu_model == HPPA_FPU_PCXW)
                    351:                        cpu_type = HPPA_CPU_PCXW;
                    352:        }
                    353:
                    354:        if (!cpu_type)
                    355:                printf("WARNING: UNKNOWN CPU TYPE; GOOD LUCK\n");
                    356:        cpu_typename = hppa_mod_info(HPPA_TYPE_CPU, cpu_type);
                    357:
                    358:        if (pdc_model.arch_rev != 8)
                    359:                panic("CANNOT RUN 64BIT KERNEL on 32BIT CPU");
                    360:
                    361:        {
                    362:                const char *p;
                    363:                char buf[32];
                    364:
                    365:                cpu_hvers = pdc_model.hvers >> 4;
                    366:                if (!cpu_hvers) {
                    367:                        p = "(UNKNOWN)";
                    368:                } else {
                    369:                        p = hppa_mod_info(HPPA_TYPE_BOARD, cpu_hvers);
                    370:                        if (!p) {
                    371:                                snprintf(buf, sizeof buf, "(UNKNOWN 0x%x)",
                    372:                                    cpu_hvers);
                    373:                                p = buf;
                    374:                        }
                    375:                }
                    376:
                    377:                snprintf(cpu_model, sizeof cpu_model,
                    378:                    "HP 9000/%s PA-RISC 2.0", p);
                    379:        }
                    380: #ifdef DEBUG
                    381:        printf("%s\n", cpu_model);
                    382: #endif
                    383: }
                    384:
                    385: void
                    386: cpu_startup(void)
                    387: {
                    388:        vaddr_t minaddr, maxaddr;
                    389:
                    390:        /*
                    391:         * psychodelic kingdom come
                    392:         * ... run, run, run
                    393:         * psychodelic kings and queens
                    394:         * join me in this one love dream
                    395:         */
                    396:        printf("%s%s\n", version, cpu_model);
                    397:        printf("real mem = %u (%u reserved for PROM, %u used by OpenBSD)\n",
                    398:            ctob(physmem), ctob(resvmem), ctob(resvphysmem - resvmem));
                    399:
                    400:        /*
                    401:         * Determine how many buffers to allocate.
                    402:         * We allocate bufcachepercent% of memory for buffer space.
                    403:         */
                    404:        if (bufpages == 0)
                    405:                bufpages = physmem * bufcachepercent / 100;
                    406:
                    407:        /* Restrict to at most 25% filled kvm */
                    408:        if (bufpages >
                    409:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
                    410:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
                    411:                    PAGE_SIZE / 4;
                    412:
                    413: printf("here3\n");
                    414:        /*
                    415:         * Allocate a submap for exec arguments.  This map effectively
                    416:         * limits the number of processes exec'ing at any time.
                    417:         */
                    418:        minaddr = vm_map_min(kernel_map);
                    419:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    420:            16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
                    421:
                    422: printf("here4\n");
                    423:        /*
                    424:         * Allocate a submap for physio
                    425:         */
                    426:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    427:            VM_PHYS_SIZE, 0, FALSE, NULL);
                    428:
                    429: printf("here5\n");
                    430:        printf("avail mem = %lu\n", ptoa(uvmexp.free));
                    431:
                    432:        /*
                    433:         * Set up buffers, so they can be used to read disk labels.
                    434:         */
                    435:        bufinit();
                    436:        vmmap = uvm_km_valloc_wait(kernel_map, NBPG);
                    437:
                    438: printf("here6\n");
                    439:        /*
                    440:         * Configure the system.
                    441:         */
                    442:        if (boothowto & RB_CONFIG) {
                    443: #ifdef BOOT_CONFIG
                    444:                user_config();
                    445: #else
                    446:                printf("kernel does not support -c; continuing..\n");
                    447: #endif
                    448:        }
                    449: printf("here7\n");
                    450: }
                    451:
                    452: /*
                    453:  * initialize the system time from the time of day clock
                    454:  */
                    455: void
                    456: inittodr(t)
                    457:        time_t t;
                    458: {
                    459:        struct pdc_tod tod PDC_ALIGNMENT;
                    460:        int     error, tbad = 0;
                    461:
                    462:        if (t < 12*SECYR) {
                    463:                printf ("WARNING: preposterous time in file system");
                    464:                t = 6*SECYR + 186*SECDAY + SECDAY/2;
                    465:                tbad = 1;
                    466:        }
                    467:
                    468:        if ((error = pdc_call((iodcio_t)pdc,
                    469:            1, PDC_TOD, PDC_TOD_READ, &tod, 0, 0, 0, 0, 0)))
                    470:                printf("clock: failed to fetch (%d)\n", error);
                    471:
                    472:        time.tv_sec = tod.sec;
                    473:        time.tv_usec = tod.usec;
                    474:
                    475:        if (!tbad) {
                    476:                u_long  dt;
                    477:
                    478:                dt = (time.tv_sec < t)?  t - time.tv_sec : time.tv_sec - t;
                    479:
                    480:                if (dt < 2 * SECDAY)
                    481:                        return;
                    482:                printf("WARNING: clock %s %ld days",
                    483:                    time.tv_sec < t? "lost" : "gained", dt / SECDAY);
                    484:        }
                    485:
                    486:        printf (" -- CHECK AND RESET THE DATE!\n");
                    487: }
                    488:
                    489: /*
                    490:  * reset the time of day clock to the value in time
                    491:  */
                    492: void
                    493: resettodr()
                    494: {
                    495:        int error;
                    496:
                    497:        if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE,
                    498:            time.tv_sec, time.tv_usec)))
                    499:                printf("clock: failed to save (%d)\n", error);
                    500: }
                    501:
                    502: /*
                    503:  * compute cpu clock ratio such as:
                    504:  *     cpu_ticksnum / cpu_ticksdenom = t + delta
                    505:  *     delta -> 0
                    506:  */
                    507: void
                    508: delay_init(void)
                    509: {
                    510:        u_long num, denom, delta, mdelta;
                    511:
                    512:        mdelta = ULONG_MAX;
                    513:        for (denom = 1; denom < 1000; denom++) {
                    514:                num = (PAGE0->mem_10msec * denom) / 10000;
                    515:                delta = num * 10000 / denom - PAGE0->mem_10msec;
                    516:                if (!delta) {
                    517:                        cpu_ticksdenom = denom;
                    518:                        cpu_ticksnum = num;
                    519:                        break;
                    520:                } else if (delta < mdelta) {
                    521:                        cpu_ticksdenom = denom;
                    522:                        cpu_ticksnum = num;
                    523:                        mdelta = delta;
                    524:                }
                    525:        }
                    526: printf("nom=%lu denom=%lu\n", cpu_ticksnum, cpu_ticksdenom);
                    527: }
                    528:
                    529: void
                    530: delay(us)
                    531:        u_int us;
                    532: {
                    533:        u_long start, end, n;
                    534:
                    535:        start = mfctl(CR_ITMR);
                    536:        while (us) {
                    537:                n = min(1000, us);
                    538:                end = start + n * cpu_ticksnum / cpu_ticksdenom;
                    539:
                    540:                /* N.B. Interval Timer may wrap around */
                    541:                if (end < start)
                    542:                        do
                    543:                                start = mfctl(CR_ITMR);
                    544:                        while (start > end);
                    545:
                    546:                do
                    547:                        start = mfctl(CR_ITMR);
                    548:                while (start < end);
                    549:
                    550:                us -= n;
                    551:        }
                    552: }
                    553:
                    554: static __inline void
                    555: fall(c_base, c_count, c_loop, c_stride, data)
                    556:        int c_base, c_count, c_loop, c_stride, data;
                    557: {
                    558:        int loop;
                    559:
                    560:        for (; c_count--; c_base += c_stride)
                    561:                for (loop = c_loop; loop--; )
                    562:                        if (data)
                    563:                                __asm __volatile("fdce 0(%%sr0,%0)"
                    564:                                    :: "r" (c_base));
                    565:                        else
                    566:                                __asm __volatile("fice 0(%%sr0,%0)"
                    567:                                    :: "r" (c_base));
                    568: }
                    569:
                    570: void
                    571: ficacheall(void)
                    572: {
                    573:        /*
                    574:         * Flush the instruction, then data cache.
                    575:         */
                    576:        fall(pdc_cache.ic_base, pdc_cache.ic_count, pdc_cache.ic_loop,
                    577:            pdc_cache.ic_stride, 0);
                    578:        sync_caches();
                    579: }
                    580:
                    581: void
                    582: fdcacheall(void)
                    583: {
                    584:        fall(pdc_cache.dc_base, pdc_cache.dc_count, pdc_cache.dc_loop,
                    585:            pdc_cache.dc_stride, 1);
                    586:        sync_caches();
                    587: }
                    588:
                    589: void
                    590: ptlball(void)
                    591: {
                    592:        register pa_space_t sp;
                    593:        register int i, j, k;
                    594:
                    595:        /* instruction TLB */
                    596:        sp = pdc_cache.it_sp_base;
                    597:        for (i = 0; i < pdc_cache.it_sp_count; i++) {
                    598:                register vaddr_t off = pdc_cache.it_off_base;
                    599:                for (j = 0; j < pdc_cache.it_off_count; j++) {
                    600:                        for (k = 0; k < pdc_cache.it_loop; k++)
                    601:                                pitlb(sp, off);
                    602:                        off += pdc_cache.it_off_stride;
                    603:                }
                    604:                sp += pdc_cache.it_sp_stride;
                    605:        }
                    606:
                    607:        /* data TLB */
                    608:        sp = pdc_cache.dt_sp_base;
                    609:        for (i = 0; i < pdc_cache.dt_sp_count; i++) {
                    610:                register vaddr_t off = pdc_cache.dt_off_base;
                    611:                for (j = 0; j < pdc_cache.dt_off_count; j++) {
                    612:                        for (k = 0; k < pdc_cache.dt_loop; k++)
                    613:                                pdtlb(sp, off);
                    614:                        off += pdc_cache.dt_off_stride;
                    615:                }
                    616:                sp += pdc_cache.dt_sp_stride;
                    617:        }
                    618: }
                    619:
                    620: void
                    621: boot(howto)
                    622:        int howto;
                    623: {
                    624:        /* If system is cold, just halt. */
                    625:        if (cold) {
                    626:                /* (Unless the user explicitly asked for reboot.) */
                    627:                if ((howto & RB_USERREQ) == 0)
                    628:                        howto |= RB_HALT;
                    629:        } else {
                    630:
                    631:                boothowto = howto | (boothowto & RB_HALT);
                    632:
                    633:                if (!(howto & RB_NOSYNC)) {
                    634:                        vfs_shutdown();
                    635:                        /*
                    636:                         * If we've been adjusting the clock, the todr
                    637:                         * will be out of synch; adjust it now unless
                    638:                         * the system was sitting in ddb.
                    639:                         */
                    640:                        if ((howto & RB_TIMEBAD) == 0)
                    641:                                resettodr();
                    642:                        else
                    643:                                printf("WARNING: not updating battery clock\n");
                    644:                }
                    645:
                    646:                /* XXX probably save howto into stable storage */
                    647:
                    648:                splhigh();
                    649:
                    650:                if (howto & RB_DUMP)
                    651:                        dumpsys();
                    652:
                    653:                doshutdownhooks();
                    654:        }
                    655:
                    656:        /* in case we came on powerfail interrupt */
                    657:        if (cold_hook)
                    658:                (*cold_hook)(HPPA_COLD_COLD);
                    659:
                    660:        if (howto & RB_HALT) {
                    661:                if (howto & RB_POWERDOWN && cold_hook) {
                    662:                        printf("Powering off...");
                    663:                        DELAY(2000000);
                    664:                        (*cold_hook)(HPPA_COLD_OFF);
                    665:                        DELAY(1000000);
                    666:                }
                    667:
                    668:                printf("System halted!\n");
                    669:                DELAY(2000000);
                    670:                __asm __volatile("stwas %0, 0(%1)"
                    671:                    :: "r" (CMD_STOP), "r" (HPPA_LBCAST + iomod_command));
                    672:        } else {
                    673:                printf("rebooting...");
                    674:                DELAY(2000000);
                    675:                __asm __volatile(".export hppa_reset, entry\n\t"
                    676:                    ".label hppa_reset");
                    677:                __asm __volatile("stwas %0, 0(%1)"
                    678:                    :: "r" (CMD_RESET), "r" (HPPA_LBCAST + iomod_command));
                    679:        }
                    680:
                    681:        for(;;); /* loop while bus reset is comming up */
                    682:        /* NOTREACHED */
                    683: }
                    684:
                    685: u_long dumpmag = 0x8fca0101;   /* magic number */
                    686: int    dumpsize = 0;           /* pages */
                    687: long   dumplo = 0;             /* blocks */
                    688:
                    689: /*
                    690:  * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
                    691:  */
                    692: int
                    693: cpu_dumpsize(void)
                    694: {
                    695:        int size;
                    696:
                    697:        size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
                    698:        if (roundup(size, dbtob(1)) != dbtob(1))
                    699:                return -1;
                    700:
                    701:        return 1;
                    702: }
                    703:
                    704: /*
                    705:  * Called from HPMC handler in locore
                    706:  */
                    707: void
                    708: hpmc_dump(void)
                    709: {
                    710:        printf("HPMC\n");
                    711:
                    712:        cold = 0;
                    713:        boot(RB_NOSYNC);
                    714: }
                    715:
                    716: int
                    717: cpu_dump(void)
                    718: {
                    719:        long buf[dbtob(1) / sizeof (long)];
                    720:        kcore_seg_t     *segp;
                    721:        cpu_kcore_hdr_t *cpuhdrp;
                    722:
                    723:        segp = (kcore_seg_t *)buf;
                    724:        cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp)) / sizeof (long)];
                    725:
                    726:        /*
                    727:         * Generate a segment header.
                    728:         */
                    729:        CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
                    730:        segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
                    731:
                    732:        /*
                    733:         * Add the machine-dependent header info
                    734:         */
                    735:        /* nothing for now */
                    736:
                    737:        return (bdevsw[major(dumpdev)].d_dump)
                    738:            (dumpdev, dumplo, (caddr_t)buf, dbtob(1));
                    739: }
                    740:
                    741: /*
                    742:  * Dump the kernel's image to the swap partition.
                    743:  */
                    744: #define        BYTES_PER_DUMP  NBPG
                    745:
                    746: void
                    747: dumpsys(void)
                    748: {
                    749:        int psize, bytes, i, n;
                    750:        caddr_t maddr;
                    751:        daddr64_t blkno;
                    752:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
                    753:        int error;
                    754:
                    755:        /* Save registers
                    756:        savectx(&dumppcb); */
                    757:
                    758:        if (dumpsize == 0)
                    759:                dumpconf();
                    760:        if (dumplo <= 0) {
                    761:                printf("\ndump to dev %x not possible\n", dumpdev);
                    762:                return;
                    763:        }
                    764:        printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
                    765:
                    766:        psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    767:        printf("dump ");
                    768:        if (psize == -1) {
                    769:                printf("area unavailable\n");
                    770:                return;
                    771:        }
                    772:
                    773:        if (!(error = cpu_dump())) {
                    774:
                    775:                bytes = ctob(physmem);
                    776:                maddr = NULL;
                    777:                blkno = dumplo + cpu_dumpsize();
                    778:                dump = bdevsw[major(dumpdev)].d_dump;
                    779:                for (i = 0; i < bytes; i += n) {
                    780:
                    781:                        /* Print out how many MBs we are to go. */
                    782:                        n = bytes - i;
                    783:                        if (n && (n % (1024*1024)) == 0)
                    784:                                printf("%d ", n / (1024 * 1024));
                    785:
                    786:                        /* Limit size for next transfer. */
                    787:                        if (n > BYTES_PER_DUMP)
                    788:                                n = BYTES_PER_DUMP;
                    789:
                    790:                        if ((error = (*dump)(dumpdev, blkno, maddr, n)))
                    791:                                break;
                    792:                        maddr += n;
                    793:                        blkno += btodb(n);
                    794:                }
                    795:        }
                    796:
                    797:        switch (error) {
                    798:        case ENXIO:     printf("device bad\n");                 break;
                    799:        case EFAULT:    printf("device not ready\n");           break;
                    800:        case EINVAL:    printf("area improper\n");              break;
                    801:        case EIO:       printf("i/o error\n");                  break;
                    802:        case EINTR:     printf("aborted from console\n");       break;
                    803:        case 0:         printf("succeeded\n");                  break;
                    804:        default:        printf("error %d\n", error);            break;
                    805:        }
                    806: }
                    807:
                    808: /* bcopy(), error on fault */
                    809: int
                    810: kcopy(from, to, size)
                    811:        const void *from;
                    812:        void *to;
                    813:        size_t size;
                    814: {
                    815:        return spcopy(HPPA_SID_KERNEL, from, HPPA_SID_KERNEL, to, size);
                    816: }
                    817:
                    818: int
                    819: copystr(src, dst, size, lenp)
                    820:        const void *src;
                    821:        void *dst;
                    822:        size_t size;
                    823:        size_t *lenp;
                    824: {
                    825:        return spstrcpy(HPPA_SID_KERNEL, src, HPPA_SID_KERNEL, dst, size, lenp);
                    826: }
                    827:
                    828: int
                    829: copyinstr(src, dst, size, lenp)
                    830:        const void *src;
                    831:        void *dst;
                    832:        size_t size;
                    833:        size_t *lenp;
                    834: {
                    835:        return spstrcpy(curproc->p_addr->u_pcb.pcb_space, src,
                    836:            HPPA_SID_KERNEL, dst, size, lenp);
                    837: }
                    838:
                    839:
                    840: int
                    841: copyoutstr(src, dst, size, lenp)
                    842:        const void *src;
                    843:        void *dst;
                    844:        size_t size;
                    845:        size_t *lenp;
                    846: {
                    847:        return spstrcpy(HPPA_SID_KERNEL, src,
                    848:            curproc->p_addr->u_pcb.pcb_space, dst, size, lenp);
                    849: }
                    850:
                    851:
                    852: int
                    853: copyin(src, dst, size)
                    854:        const void *src;
                    855:        void *dst;
                    856:        size_t size;
                    857: {
                    858:        return spcopy(curproc->p_addr->u_pcb.pcb_space, src,
                    859:            HPPA_SID_KERNEL, dst, size);
                    860: }
                    861:
                    862: int
                    863: copyout(src, dst, size)
                    864:        const void *src;
                    865:        void *dst;
                    866:        size_t size;
                    867: {
                    868:        return spcopy(HPPA_SID_KERNEL, src,
                    869:            curproc->p_addr->u_pcb.pcb_space, dst, size);
                    870: }
                    871:
                    872: /*
                    873:  * Set registers on exec.
                    874:  */
                    875: void
                    876: setregs(p, pack, stack, retval)
                    877:        struct proc *p;
                    878:        struct exec_package *pack;
                    879:        u_long stack;
                    880:        register_t *retval;
                    881: {
                    882:        extern paddr_t fpu_curpcb;      /* from locore.S */
                    883:        struct trapframe *tf = p->p_md.md_regs;
                    884:        struct pcb *pcb = &p->p_addr->u_pcb;
                    885:        register_t zero;
                    886:
                    887:        tf->tf_flags = TFF_SYS|TFF_LAST;
                    888:        tf->tf_iioq[1] = 4 +
                    889:            (tf->tf_iioq[0] = pack->ep_entry | HPPA_PC_PRIV_USER);
                    890:        tf->tf_rp = 0;
                    891:        tf->tf_args[0] = (u_long)PS_STRINGS;
                    892:        tf->tf_args[1] = tf->tf_args[2] = 0; /* XXX dynload stuff */
                    893:
                    894:        /* setup terminal stack frame */
                    895:        stack = (stack + 0x1f) & ~0x1f;
                    896:        tf->tf_r3 = stack;
                    897:        tf->tf_sp = stack += HPPA_FRAME_SIZE;
                    898:        tf->tf_ret1 = stack - 16;       /* ap */
                    899:        zero = 0;
                    900:        copyout(&zero, (caddr_t)(stack - HPPA_FRAME_SIZE), sizeof(register_t));
                    901:        copyout(&zero, (caddr_t)(stack + HPPA_FRAME_RP), sizeof(register_t));
                    902:
                    903:        /* reset any of the pending FPU exceptions */
                    904:        if (tf->tf_cr30 == fpu_curpcb) {
                    905:                fpu_exit();
                    906:                fpu_curpcb = 0;
                    907:        }
                    908:        pcb->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32;
                    909:        pcb->pcb_fpregs[1] = 0;
                    910:        pcb->pcb_fpregs[2] = 0;
                    911:        pcb->pcb_fpregs[3] = 0;
                    912:        fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4);
                    913:
                    914:        retval[1] = 0;
                    915: }
                    916:
                    917: /*
                    918:  * Send an interrupt to process.
                    919:  */
                    920: void
                    921: sendsig(catcher, sig, mask, code, type, val)
                    922:        sig_t catcher;
                    923:        int sig, mask;
                    924:        u_long code;
                    925:        int type;
                    926:        union sigval val;
                    927: {
                    928:        extern paddr_t fpu_curpcb;      /* from locore.S */
                    929:        extern u_int fpu_enable;
                    930:        struct proc *p = curproc;
                    931:        struct trapframe *tf = p->p_md.md_regs;
                    932:        struct sigacts *psp = p->p_sigacts;
                    933:        struct sigcontext ksc;
                    934:        siginfo_t ksi;
                    935:        register_t scp, sip, zero;
                    936:        int sss;
                    937:
                    938:        /* TODO sendsig */
                    939:
                    940: #ifdef DEBUG
                    941:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                    942:                printf("sendsig: %s[%d] sig %d catcher %p\n",
                    943:                    p->p_comm, p->p_pid, sig, catcher);
                    944: #endif
                    945:
                    946:        /* flush the FPU ctx first */
                    947:        if (tf->tf_cr30 == fpu_curpcb) {
                    948:                mtctl(fpu_enable, CR_CCR);
                    949:                fpu_save(fpu_curpcb);
                    950:                /* fpu_curpcb = 0; only needed if fpregs are preset */
                    951:                mtctl(0, CR_CCR);
                    952:        }
                    953:
                    954:        ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
                    955:
                    956:        /*
                    957:         * Allocate space for the signal handler context.
                    958:         */
                    959:        if ((psp->ps_flags & SAS_ALTSTACK) && !ksc.sc_onstack &&
                    960:            (psp->ps_sigonstack & sigmask(sig))) {
                    961:                scp = (register_t)psp->ps_sigstk.ss_sp;
                    962:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
                    963:        } else
                    964:                scp = (tf->tf_sp + 63) & ~63;
                    965:
                    966:        sss = (sizeof(ksc) + 63) & ~63;
                    967:        sip = 0;
                    968:        if (psp->ps_siginfo & sigmask(sig)) {
                    969:                sip = scp + sizeof(ksc);
                    970:                sss += (sizeof(ksi) + 63) & ~63;
                    971:        }
                    972:
                    973: #ifdef DEBUG
                    974:        if ((tf->tf_iioq[0] & ~PAGE_MASK) == SYSCALLGATE)
                    975:                printf("sendsig: interrupted syscall at 0x%x:0x%x, flags %b\n",
                    976:                    tf->tf_iioq[0], tf->tf_iioq[1], tf->tf_ipsw, PSL_BITS);
                    977: #endif
                    978:
                    979:        ksc.sc_mask = mask;
                    980:        ksc.sc_fp = scp + sss;
                    981:        ksc.sc_ps = tf->tf_ipsw;
                    982:        ksc.sc_pcoqh = tf->tf_iioq[0];
                    983:        ksc.sc_pcoqt = tf->tf_iioq[1];
                    984:        bcopy(tf, &ksc.sc_regs[0], 32*8);
                    985:        ksc.sc_regs[0] = tf->tf_sar;
                    986:        bcopy(p->p_addr->u_pcb.pcb_fpregs, ksc.sc_fpregs,
                    987:            sizeof(ksc.sc_fpregs));
                    988:
                    989:        sss += HPPA_FRAME_SIZE;
                    990:        tf->tf_args[0] = sig;
                    991:        tf->tf_args[1] = sip;
                    992:        tf->tf_args[2] = tf->tf_r4 = scp;
                    993:        tf->tf_args[3] = (register_t)catcher;
                    994:        tf->tf_sp = scp + sss;
                    995:        tf->tf_ipsw &= ~(PSL_N|PSL_B);
                    996:        tf->tf_iioq[0] = HPPA_PC_PRIV_USER | p->p_sigcode;
                    997:        tf->tf_iioq[1] = tf->tf_iioq[0] + 4;
                    998:        /* disable tracing in the trapframe */
                    999:
                   1000: #ifdef DEBUG
                   1001:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                   1002:                printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n",
                   1003:                    p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss);
                   1004: #endif
                   1005:
                   1006:        if (copyout(&ksc, (void *)scp, sizeof(ksc)))
                   1007:                sigexit(p, SIGILL);
                   1008:
                   1009:        if (sip) {
                   1010:                initsiginfo(&ksi, sig, code, type, val);
                   1011:                if (copyout(&ksi, (void *)sip, sizeof(ksi)))
                   1012:                        sigexit(p, SIGILL);
                   1013:        }
                   1014:
                   1015:        zero = 0;
                   1016:        if (copyout(&zero, (caddr_t)scp + sss - HPPA_FRAME_SIZE,
                   1017:            sizeof(register_t)))
                   1018:                sigexit(p, SIGILL);
                   1019:
                   1020: #ifdef DEBUG
                   1021:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                   1022:                printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid,
                   1023:                    tf->tf_iioq[0], tf->tf_args[3]);
                   1024: #endif
                   1025: }
                   1026:
                   1027: int
                   1028: sys_sigreturn(p, v, retval)
                   1029:        struct proc *p;
                   1030:        void *v;
                   1031:        register_t *retval;
                   1032: {
                   1033:        extern paddr_t fpu_curpcb;      /* from locore.S */
                   1034:        struct sys_sigreturn_args /* {
                   1035:                syscallarg(struct sigcontext *) sigcntxp;
                   1036:        } */ *uap = v;
                   1037:        struct sigcontext *scp, ksc;
                   1038:        struct trapframe *tf = p->p_md.md_regs;
                   1039:        int error;
                   1040:
                   1041:        /* TODO sigreturn */
                   1042:
                   1043:        scp = SCARG(uap, sigcntxp);
                   1044: #ifdef DEBUG
                   1045:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                   1046:                printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
                   1047: #endif
                   1048:
                   1049:        /* flush the FPU ctx first */
                   1050:        if (tf->tf_cr30 == fpu_curpcb) {
                   1051:                fpu_exit();
                   1052:                fpu_curpcb = 0;
                   1053:        }
                   1054:
                   1055:        if ((error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)))
                   1056:                return (error);
                   1057:
                   1058: #define PSL_MBS (PSL_C|PSL_Q|PSL_P|PSL_D|PSL_I)
                   1059: #define PSL_MBZ (PSL_Y|PSL_Z|PSL_S|PSL_X|PSL_M|PSL_R)
                   1060:        if ((ksc.sc_ps & (PSL_MBS|PSL_MBZ)) != PSL_MBS)
                   1061:                return (EINVAL);
                   1062:
                   1063:        if (ksc.sc_onstack)
                   1064:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
                   1065:        else
                   1066:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
                   1067:        p->p_sigmask = ksc.sc_mask &~ sigcantmask;
                   1068:
                   1069:        tf->tf_sar = ksc.sc_regs[0];
                   1070:        ksc.sc_regs[0] = tf->tf_flags;
                   1071:        bcopy(&ksc.sc_regs[0], tf, 32*8);
                   1072:        bcopy(ksc.sc_fpregs, p->p_addr->u_pcb.pcb_fpregs,
                   1073:            sizeof(ksc.sc_fpregs));
                   1074:        fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs,
                   1075:            sizeof(ksc.sc_fpregs));
                   1076:
                   1077:        tf->tf_iioq[0] = ksc.sc_pcoqh;
                   1078:        tf->tf_iioq[1] = ksc.sc_pcoqt;
                   1079:        tf->tf_ipsw = ksc.sc_ps;
                   1080:
                   1081: #ifdef DEBUG
                   1082:        if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
                   1083:                printf("sigreturn(%d): returns\n", p->p_pid);
                   1084: #endif
                   1085:        return (EJUSTRETURN);
                   1086: }
                   1087:
                   1088: /*
                   1089:  * machine dependent system variables.
                   1090:  */
                   1091: int
                   1092: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                   1093:        int *name;
                   1094:        u_int namelen;
                   1095:        void *oldp;
                   1096:        size_t *oldlenp;
                   1097:        void *newp;
                   1098:        size_t newlen;
                   1099:        struct proc *p;
                   1100: {
                   1101:        dev_t consdev;
                   1102:
                   1103:        /* all sysctl names at this level are terminal */
                   1104:        if (namelen != 1)
                   1105:                return (ENOTDIR);       /* overloaded */
                   1106:        switch (name[0]) {
                   1107:        case CPU_CONSDEV:
                   1108:                if (cn_tab != NULL)
                   1109:                        consdev = cn_tab->cn_dev;
                   1110:                else
                   1111:                        consdev = NODEV;
                   1112:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
                   1113:                    sizeof consdev));
                   1114:        default:
                   1115:                return (EOPNOTSUPP);
                   1116:        }
                   1117:        /* NOTREACHED */
                   1118: }
                   1119:
                   1120:
                   1121: /*
                   1122:  * consinit:
                   1123:  * initialize the system console.
                   1124:  */
                   1125: void
                   1126: consinit(void)
                   1127: {
                   1128:        static int initted;
                   1129:
                   1130:        if (!initted) {
                   1131:                initted++;
                   1132:                cninit();
                   1133:        }
                   1134: }
                   1135:
                   1136: #ifdef DIAGNOSTIC
                   1137: void
                   1138: splassert_check(int wantipl, const char *func)
                   1139: {
                   1140:        extern int cpl; /* from locoore.s */
                   1141:
                   1142:        if (cpl < wantipl) {
                   1143:                splassert_fail(wantipl, cpl, func);
                   1144:        }
                   1145: }
                   1146: #endif

CVSweb