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

Annotation of sys/arch/m88k/m88k/m88k_machdep.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: m88k_machdep.c,v 1.21 2007/05/29 18:10:42 miod Exp $  */
        !             2: /*
        !             3:  * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
        !             4:  * Copyright (c) 1996 Nivas Madhur
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *      This product includes software developed by Nivas Madhur.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  *
        !            32:  */
        !            33: /*
        !            34:  * Mach Operating System
        !            35:  * Copyright (c) 1993-1991 Carnegie Mellon University
        !            36:  * Copyright (c) 1991 OMRON Corporation
        !            37:  * All Rights Reserved.
        !            38:  *
        !            39:  * Permission to use, copy, modify and distribute this software and its
        !            40:  * documentation is hereby granted, provided that both the copyright
        !            41:  * notice and this permission notice appear in all copies of the
        !            42:  * software, derivative works or modified versions, and any portions
        !            43:  * thereof, and that both notices appear in supporting documentation.
        !            44:  *
        !            45:  */
        !            46:
        !            47: #include <sys/param.h>
        !            48: #include <sys/systm.h>
        !            49: #include <sys/kernel.h>
        !            50: #include <sys/proc.h>
        !            51: #include <sys/user.h>
        !            52: #include <sys/msgbuf.h>
        !            53: #include <sys/exec.h>
        !            54: #include <sys/errno.h>
        !            55: #include <sys/lock.h>
        !            56: #ifdef MULTIPROCESSOR
        !            57: #include <sys/mplock.h>
        !            58: #endif
        !            59:
        !            60: #include <machine/asm.h>
        !            61: #include <machine/asm_macro.h>
        !            62: #include <machine/atomic.h>
        !            63: #include <machine/cmmu.h>
        !            64: #include <machine/cpu.h>
        !            65: #include <machine/reg.h>
        !            66: #ifdef M88100
        !            67: #include <machine/m88100.h>
        !            68: #endif
        !            69:
        !            70: #include <uvm/uvm_extern.h>
        !            71:
        !            72: #include <net/netisr.h>
        !            73:
        !            74: #ifdef DDB
        !            75: #include <machine/db_machdep.h>
        !            76: #include <ddb/db_extern.h>
        !            77: #include <ddb/db_interface.h>
        !            78: #endif /* DDB */
        !            79:
        !            80: typedef struct {
        !            81:        u_int32_t word_one, word_two;
        !            82: } m88k_exception_vector_area;
        !            83:
        !            84: void   dosoftint(void);
        !            85: void   dumpconf(void);
        !            86: void   dumpsys(void);
        !            87: void   regdump(struct trapframe *f);
        !            88: void   vector_init(m88k_exception_vector_area *, u_int32_t *);
        !            89:
        !            90: /*
        !            91:  * CMMU and CPU variables
        !            92:  */
        !            93:
        !            94: #ifdef MULTIPROCESSOR
        !            95: __cpu_simple_lock_t cmmu_cpu_lock = __SIMPLELOCK_UNLOCKED;
        !            96: cpuid_t        master_cpu;
        !            97: struct __mp_lock sir_lock;
        !            98: #endif
        !            99:
        !           100: struct cpu_info m88k_cpus[MAX_CPUS];
        !           101: u_int  max_cpus;
        !           102:
        !           103: struct cmmu_p *cmmu;
        !           104:
        !           105: /*
        !           106:  * safepri is a safe priority for sleep to set for a spin-wait
        !           107:  * during autoconfiguration or after a panic.
        !           108:  */
        !           109: int   safepri = IPL_NONE;
        !           110:
        !           111: /*
        !           112:  * Set registers on exec.
        !           113:  * Clear all except sp and pc.
        !           114:  */
        !           115: void
        !           116: setregs(p, pack, stack, retval)
        !           117:        struct proc *p;
        !           118:        struct exec_package *pack;
        !           119:        u_long stack;
        !           120:        int retval[2];
        !           121: {
        !           122:        struct trapframe *tf = (struct trapframe *)USER_REGS(p);
        !           123:
        !           124:        /*
        !           125:         * The syscall will ``return'' to snip; set it.
        !           126:         * argc, argv, envp are placed on the stack by copyregs.
        !           127:         * Point r2 to the stack. crt0 should extract envp from
        !           128:         * argc & argv before calling user's main.
        !           129:         */
        !           130:
        !           131:        bzero((caddr_t)tf, sizeof *tf);
        !           132:
        !           133: #ifdef M88110
        !           134:        if (CPU_IS88110) {
        !           135:                /*
        !           136:                 * user mode, serialize mem, interrupts enabled,
        !           137:                 * graphics unit, fp enabled
        !           138:                 */
        !           139:                tf->tf_epsr = PSR_SRM | PSR_SFD;
        !           140:                /*
        !           141:                 * XXX disable OoO for now...
        !           142:                 */
        !           143:                tf->tf_epsr |= PSR_SER;
        !           144:        }
        !           145: #endif
        !           146: #ifdef M88100
        !           147:        if (CPU_IS88100) {
        !           148:                /*
        !           149:                 * user mode, interrupts enabled,
        !           150:                 * no graphics unit, fp enabled
        !           151:                 */
        !           152:                tf->tf_epsr = PSR_SFD | PSR_SFD2;
        !           153:        }
        !           154: #endif
        !           155:
        !           156:        /*
        !           157:         * We want to start executing at pack->ep_entry. The way to
        !           158:         * do this is force the processor to fetch from ep_entry. Set
        !           159:         * NIP to something bogus and invalid so that it will be a NOOP.
        !           160:         * And set sfip to ep_entry with valid bit on so that it will be
        !           161:         * fetched.  mc88110 - just set exip to pack->ep_entry.
        !           162:         */
        !           163: #ifdef M88110
        !           164:        if (CPU_IS88110) {
        !           165:                tf->tf_exip = pack->ep_entry & XIP_ADDR;
        !           166:        }
        !           167: #endif
        !           168: #ifdef M88100
        !           169:        if (CPU_IS88100) {
        !           170:                tf->tf_snip = pack->ep_entry & NIP_ADDR;
        !           171:                tf->tf_sfip = (pack->ep_entry & FIP_ADDR) | FIP_V;
        !           172:        }
        !           173: #endif
        !           174:        tf->tf_r[2] = stack;
        !           175:        tf->tf_r[31] = stack;
        !           176:        retval[1] = 0;
        !           177: }
        !           178:
        !           179: int
        !           180: copystr(fromaddr, toaddr, maxlength, lencopied)
        !           181:        const void *fromaddr;
        !           182:        void *toaddr;
        !           183:        size_t maxlength;
        !           184:        size_t *lencopied;
        !           185: {
        !           186:        u_int tally;
        !           187:
        !           188:        tally = 0;
        !           189:
        !           190:        while (maxlength--) {
        !           191:                *(u_char *)toaddr = *(u_char *)fromaddr++;
        !           192:                tally++;
        !           193:                if (*(u_char *)toaddr++ == 0) {
        !           194:                        if (lencopied) *lencopied = tally;
        !           195:                        return (0);
        !           196:                }
        !           197:        }
        !           198:
        !           199:        if (lencopied)
        !           200:                *lencopied = tally;
        !           201:
        !           202:        return (ENAMETOOLONG);
        !           203: }
        !           204:
        !           205: void
        !           206: setrunqueue(p)
        !           207:        struct proc *p;
        !           208: {
        !           209:        struct prochd *q;
        !           210:        struct proc *oldlast;
        !           211:        int which = p->p_priority >> 2;
        !           212:
        !           213: #ifdef DIAGNOSTIC
        !           214:        if (p->p_back != NULL)
        !           215:                panic("setrunqueue %p", p);
        !           216: #endif
        !           217:        q = &qs[which];
        !           218:        whichqs |= 1 << which;
        !           219:        p->p_forw = (struct proc *)q;
        !           220:        p->p_back = oldlast = q->ph_rlink;
        !           221:        q->ph_rlink = p;
        !           222:        oldlast->p_forw = p;
        !           223: }
        !           224:
        !           225: /*
        !           226:  * Remove process p from its run queue, which should be the one
        !           227:  * indicated by its priority.  Calls should be made at splstatclock().
        !           228:  */
        !           229: void
        !           230: remrunqueue(vp)
        !           231:        struct proc *vp;
        !           232: {
        !           233:        struct proc *p = vp;
        !           234:        int which = p->p_priority >> 2;
        !           235:        struct prochd *q;
        !           236:
        !           237: #ifdef DIAGNOSTIC
        !           238:        if ((whichqs & (1 << which)) == 0)
        !           239:                panic("remrq %p", p);
        !           240: #endif
        !           241:        p->p_forw->p_back = p->p_back;
        !           242:        p->p_back->p_forw = p->p_forw;
        !           243:        p->p_back = NULL;
        !           244:        q = &qs[which];
        !           245:        if (q->ph_link == (struct proc *)q)
        !           246:                whichqs &= ~(1 << which);
        !           247: }
        !           248:
        !           249: #ifdef DDB
        !           250: int longformat = 1;
        !           251: void
        !           252: regdump(struct trapframe *f)
        !           253: {
        !           254: #define R(i) f->tf_r[i]
        !           255:        printf("R00-05: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           256:               R(0),R(1),R(2),R(3),R(4),R(5));
        !           257:        printf("R06-11: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           258:               R(6),R(7),R(8),R(9),R(10),R(11));
        !           259:        printf("R12-17: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           260:               R(12),R(13),R(14),R(15),R(16),R(17));
        !           261:        printf("R18-23: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           262:               R(18),R(19),R(20),R(21),R(22),R(23));
        !           263:        printf("R24-29: 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
        !           264:               R(24),R(25),R(26),R(27),R(28),R(29));
        !           265:        printf("R30-31: 0x%08x  0x%08x\n",R(30),R(31));
        !           266: #ifdef M88110
        !           267:        if (CPU_IS88110) {
        !           268:                printf("exip %x enip %x\n", f->tf_exip, f->tf_enip);
        !           269:        }
        !           270: #endif
        !           271: #ifdef M88100
        !           272:        if (CPU_IS88100) {
        !           273:                printf("sxip %x snip %x sfip %x\n",
        !           274:                    f->tf_sxip, f->tf_snip, f->tf_sfip);
        !           275:        }
        !           276:        if (CPU_IS88100 && f->tf_vector == 0x3) {
        !           277:                /* print dmt stuff for data access fault */
        !           278:                printf("dmt0 %x dmd0 %x dma0 %x\n",
        !           279:                    f->tf_dmt0, f->tf_dmd0, f->tf_dma0);
        !           280:                printf("dmt1 %x dmd1 %x dma1 %x\n",
        !           281:                    f->tf_dmt1, f->tf_dmd1, f->tf_dma1);
        !           282:                printf("dmt2 %x dmd2 %x dma2 %x\n",
        !           283:                    f->tf_dmt2, f->tf_dmd2, f->tf_dma2);
        !           284:                printf("fault type %d\n", (f->tf_dpfsr >> 16) & 0x7);
        !           285:                dae_print((unsigned *)f);
        !           286:        }
        !           287:        if (CPU_IS88100 && longformat != 0) {
        !           288:                printf("fpsr %x fpcr %x epsr %x ssbr %x\n",
        !           289:                    f->tf_fpsr, f->tf_fpcr, f->tf_epsr, f->tf_ssbr);
        !           290:                printf("fpecr %x fphs1 %x fpls1 %x fphs2 %x fpls2 %x\n",
        !           291:                    f->tf_fpecr, f->tf_fphs1, f->tf_fpls1,
        !           292:                    f->tf_fphs2, f->tf_fpls2);
        !           293:                printf("fppt %x fprh %x fprl %x fpit %x\n",
        !           294:                    f->tf_fppt, f->tf_fprh, f->tf_fprl, f->tf_fpit);
        !           295:                printf("vector %d mask %x mode %x scratch1 %x cpu %p\n",
        !           296:                    f->tf_vector, f->tf_mask, f->tf_mode,
        !           297:                    f->tf_scratch1, f->tf_cpu);
        !           298:        }
        !           299: #endif
        !           300: #ifdef M88110
        !           301:        if (CPU_IS88110 && longformat != 0) {
        !           302:                printf("fpsr %x fpcr %x fpecr %x epsr %x\n",
        !           303:                    f->tf_fpsr, f->tf_fpcr, f->tf_fpecr, f->tf_epsr);
        !           304:                printf("dsap %x duap %x dsr %x dlar %x dpar %x\n",
        !           305:                    f->tf_dsap, f->tf_duap, f->tf_dsr, f->tf_dlar, f->tf_dpar);
        !           306:                printf("isap %x iuap %x isr %x ilar %x ipar %x\n",
        !           307:                    f->tf_isap, f->tf_iuap, f->tf_isr, f->tf_ilar, f->tf_ipar);
        !           308:                printf("vector %d mask %x mode %x scratch1 %x cpu %p\n",
        !           309:                    f->tf_vector, f->tf_mask, f->tf_mode,
        !           310:                    f->tf_scratch1, f->tf_cpu);
        !           311:        }
        !           312: #endif
        !           313: }
        !           314: #endif /* DDB */
        !           315:
        !           316: /*
        !           317:  * Set up the cpu_info pointer and the cpu number for the current processor.
        !           318:  */
        !           319: void
        !           320: set_cpu_number(cpuid_t number)
        !           321: {
        !           322:        struct cpu_info *ci;
        !           323:        extern struct pcb idle_u;
        !           324:
        !           325: #ifdef MULTIPROCESSOR
        !           326:        ci = &m88k_cpus[number];
        !           327: #else
        !           328:        ci = &m88k_cpus[0];
        !           329: #endif
        !           330:        ci->ci_cpuid = number;
        !           331:
        !           332:        __asm__ __volatile__ ("stcr %0, cr17" :: "r" (ci));
        !           333:        flush_pipeline();
        !           334:
        !           335: #ifdef MULTIPROCESSOR
        !           336:        if (number == master_cpu)
        !           337: #endif
        !           338:        {
        !           339:                ci->ci_primary = 1;
        !           340:                ci->ci_idle_pcb = &idle_u;
        !           341:
        !           342: #ifdef MULTIPROCESSOR
        !           343:                /*
        !           344:                 * Specific initialization for the master processor.
        !           345:                 */
        !           346:                __mp_lock_init(&sir_lock);
        !           347: #endif
        !           348:        }
        !           349:
        !           350:        ci->ci_alive = 1;
        !           351: }
        !           352:
        !           353: /*
        !           354:  * Notify the current process (p) that it has a signal pending,
        !           355:  * process as soon as possible.
        !           356:  */
        !           357: void
        !           358: signotify(struct proc *p)
        !           359: {
        !           360:        aston(p);
        !           361: #ifdef MULTIPROCESSOR
        !           362:        if (p->p_cpu != curcpu() && p->p_cpu != NULL)
        !           363:                m88k_send_ipi(CI_IPI_NOTIFY, p->p_cpu->ci_cpuid);
        !           364: #endif
        !           365: }
        !           366:
        !           367: /*
        !           368:  * Soft interrupt interface
        !           369:  */
        !           370:
        !           371: unsigned int ssir;
        !           372: int netisr;
        !           373:
        !           374: void
        !           375: dosoftint()
        !           376: {
        !           377:        int sir, n;
        !           378:
        !           379:        if ((sir = ssir) == 0)
        !           380:                return;
        !           381:
        !           382:        atomic_clearbits_int(&ssir, sir);
        !           383:        uvmexp.softs++;
        !           384:
        !           385:        if (ISSET(sir, SIR_NET)) {
        !           386:                while ((n = netisr) != 0) {
        !           387:                        atomic_clearbits_int(&netisr, n);
        !           388:
        !           389: #define DONETISR(bit, fn)                                              \
        !           390:                        do {                                            \
        !           391:                                if (n & (1 << bit))                     \
        !           392:                                        fn();                           \
        !           393:                        } while (0)
        !           394:
        !           395: #include <net/netisr_dispatch.h>
        !           396:
        !           397: #undef DONETISR
        !           398:                }
        !           399:        }
        !           400:
        !           401:        if (ISSET(sir, SIR_CLOCK))
        !           402:                softclock();
        !           403: }
        !           404:
        !           405: int
        !           406: spl0()
        !           407: {
        !           408:        int s;
        !           409:
        !           410:        s = setipl(IPL_SOFTCLOCK);
        !           411:
        !           412:        dosoftint();
        !           413:
        !           414:        setipl(IPL_NONE);
        !           415:        return (s);
        !           416: }
        !           417:
        !           418: #define EMPTY_BR       0xc0000000      /* empty "br" instruction */
        !           419: #define NO_OP          0xf4005800      /* "or r0, r0, r0" */
        !           420:
        !           421: #define BRANCH(FROM, TO) \
        !           422:        (EMPTY_BR | ((vaddr_t)(TO) - (vaddr_t)(FROM)) >> 2)
        !           423:
        !           424: #define SET_VECTOR(NUM, VALUE) \
        !           425:        do { \
        !           426:                vbr[NUM].word_one = NO_OP; \
        !           427:                vbr[NUM].word_two = BRANCH(&vbr[NUM].word_two, VALUE); \
        !           428:        } while (0)
        !           429:
        !           430: /*
        !           431:  * vector_init(vector, vector_init_list)
        !           432:  *
        !           433:  * This routine sets up the m88k vector table for the running processor.
        !           434:  * This is the first C code to run, before anything is initialized.
        !           435:  *
        !           436:  * It fills the exception vectors page. I would add an extra four bytes
        !           437:  * to the page pointed to by the vbr, since the 88100 may execute the
        !           438:  * first instruction of the next trap handler, as documented in its
        !           439:  * Errata. Processing trap #511 would then fall into the next page,
        !           440:  * unless the address computation wraps, or software traps can not trigger
        !           441:  * the issue - the Errata does not provide more detail. And since the
        !           442:  * MVME BUG does not add an extra NOP after their VBR page, I'll assume this
        !           443:  * is safe for now -- miod
        !           444:  */
        !           445: void
        !           446: vector_init(m88k_exception_vector_area *vbr, u_int32_t *vector_init_list)
        !           447: {
        !           448:        u_int num;
        !           449:        u_int32_t vec;
        !           450:
        !           451:        for (num = 0; (vec = vector_init_list[num]) != 0; num++)
        !           452:                SET_VECTOR(num, vec);
        !           453:
        !           454:        switch (cputyp) {
        !           455:        default:
        !           456: #ifdef M88110
        !           457:        case CPU_88110:
        !           458:            {
        !           459:                extern void m88110_sigsys(void);
        !           460:                extern void m88110_syscall_handler(void);
        !           461:                extern void m88110_cache_flush_handler(void);
        !           462:                extern void m88110_stepbpt(void);
        !           463:                extern void m88110_userbpt(void);
        !           464:
        !           465:                for (; num < 512; num++)
        !           466:                        SET_VECTOR(num, m88110_sigsys);
        !           467:
        !           468:                SET_VECTOR(450, m88110_syscall_handler);
        !           469:                SET_VECTOR(451, m88110_cache_flush_handler);
        !           470:                SET_VECTOR(504, m88110_stepbpt);
        !           471:                SET_VECTOR(511, m88110_userbpt);
        !           472:            }
        !           473:                break;
        !           474: #endif
        !           475: #ifdef M88100
        !           476:        case CPU_88100:
        !           477:            {
        !           478:                extern void sigsys(void);
        !           479:                extern void syscall_handler(void);
        !           480:                extern void cache_flush_handler(void);
        !           481:                extern void stepbpt(void);
        !           482:                extern void userbpt(void);
        !           483:
        !           484:                for (; num < 512; num++)
        !           485:                        SET_VECTOR(num, sigsys);
        !           486:
        !           487:                SET_VECTOR(450, syscall_handler);
        !           488:                SET_VECTOR(451, cache_flush_handler);
        !           489:                SET_VECTOR(504, stepbpt);
        !           490:                SET_VECTOR(511, userbpt);
        !           491:            }
        !           492:                break;
        !           493: #endif
        !           494:        }
        !           495:
        !           496:        /* GCC will by default produce explicit trap 503 for division by zero */
        !           497:        SET_VECTOR(503, vector_init_list[8]);
        !           498: }

CVSweb