The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sqt/slic.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1991 Carnegie Mellon University
    4  * Copyright (c) 1991 Sequent Computer Systems
    5  * All Rights Reserved.
    6  * 
    7  * Permission to use, copy, modify and distribute this software and its
    8  * documentation is hereby granted, provided that both the copyright
    9  * notice and this permission notice appear in all copies of the
   10  * software, derivative works or modified versions, and any portions
   11  * thereof, and that both notices appear in supporting documentation.
   12  * 
   13  * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
   14  * THIS SOFTWARE IN ITS "AS IS" CONDITION.  CARNEGIE MELLON AND
   15  * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
   16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   17  * 
   18  * Carnegie Mellon requests users of this software to return to
   19  * 
   20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   21  *  School of Computer Science
   22  *  Carnegie Mellon University
   23  *  Pittsburgh PA 15213-3890
   24  * 
   25  * any improvements or extensions that they make and grant Carnegie Mellon 
   26  * the rights to redistribute these changes.
   27  */
   28 
   29 /*
   30  * HISTORY
   31  * $Log:        slic.c,v $
   32  * Revision 2.3  91/07/31  18:03:48  dbg
   33  *      Changed copyright.
   34  *      [91/07/31            dbg]
   35  * 
   36  * Revision 2.2  91/05/08  12:58:59  dbg
   37  *      Adapted for pure Mach kernel.
   38  *      [90/10/03            dbg]
   39  * 
   40  */
   41 
   42 #ifndef lint
   43 static  char    rcsid[] = "$Header: slic.c,v 2.3 91/07/31 18:03:48 dbg Exp $";
   44 #endif
   45 
   46 #include <sqt/SGSproc.h>
   47 #include <sqt/slic.h>
   48 #include <sqt/intctl.h>
   49 
   50 /*
   51  * slic.c
   52  *      Slic functions.
   53  *
   54  * All routines assume caller arranged mutex of SLIC usage (splhi() or
   55  * disable processor interrupts) -- SLIC registers are not save/restored
   56  * across interrupts.
   57  *
   58  * Conditionals:
   59  *      -DCHECKSLIC     check slic results (parity, etc) for sanity
   60  *
   61  * Gates are handled in gate.c; interrupt acceptence/etc in locore.s
   62  */
   63 
   64 /*
   65  * Revision 1.2  89/07/20  18:05:24  kak
   66  * moved balance includes
   67  * 
   68  * Revision 1.1  89/07/05  13:15:46  kak
   69  * Initial revision
   70  * 
   71  */
   72 
   73 void    wrAddr();               /* forward */
   74 void    wrData();               /* forward */
   75 int     rdData();               /* forward */
   76 spl_t   lock_subslave();        /* forward */
   77 void    unlock_subslave();      /* forward */
   78 /*
   79  * wrslave()
   80  *      Write to a slave port.
   81  *
   82  * Note: this does no mutex on destination; assumes caller handles mutex
   83  * if necessary.  If done to "self" (eg, during initialization), no mutex
   84  * necessary.
   85  *
   86  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
   87  */
   88 
   89 wrslave(destination, reg, data)
   90         unsigned char destination, reg, data;
   91 {
   92         wrAddr(destination, reg);
   93         wrData(destination, data);
   94 }
   95 
   96 /*
   97  * rdslave()
   98  *      Read a slave port.
   99  *
  100  * Note: this does no mutex on destination; assumes caller handles mutex
  101  * if necessary.  If done to "self" (eg, during initialization), no mutex
  102  * necessary.
  103  *
  104  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  105  */
  106 
  107 int
  108 rdslave(destination, reg)
  109         unsigned char destination, reg;
  110 {
  111         wrAddr(destination, reg);
  112         return(rdData(destination));
  113 }
  114 
  115 /*
  116  * wrSubslave()
  117  *      Write a register that responds to SLIC slave sub-register addressing.
  118  *
  119  * Some slic/slave accesses for different resources are done thru the
  120  * same SLIC shared (eg, SGS processor BIC); use a locking protocol
  121  * on relevant slic/slave accesses.
  122  *
  123  * For compatibility with diagnostic usage, if slave==0 don't do the wrAddr().
  124  *
  125  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  126  */
  127 
  128 wrSubslave(slic, slave, subreg, val)
  129         u_char slic, slave, subreg, val;
  130 {
  131         spl_t   s;
  132 
  133         s = lock_subslave(slic, slave);
  134 
  135         if (slave != 0)
  136                 wrAddr(slic, slave);
  137         wrData(slic, subreg);
  138         wrData(slic, val);
  139 
  140         unlock_subslave(slic, slave, s);
  141 }
  142 
  143 /*
  144  * rdSubslave()
  145  *      Read a register that responds to SLIC slave sub-register addressing.
  146  *
  147  * Some slic/slave accesses for different resources are done thru the
  148  * same SLIC shared (eg, SGS processor BIC); use a locking protocol
  149  * on relevant slic/slave accesses.
  150  *
  151  * For compatibility with diagnostic usage, if slave==0 don't do the wrAddr().
  152  *
  153  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  154  */
  155 
  156 int
  157 rdSubslave(slic, slave, subreg)
  158         u_char slic, slave, subreg;
  159 {
  160         int     val;
  161         spl_t   s;
  162 
  163         s = lock_subslave(slic, slave);
  164 
  165         if (slave != 0)
  166                 wrAddr(slic, slave);
  167         wrData(slic, subreg);
  168         val = rdData(slic);
  169 
  170         unlock_subslave(slic, slave, s);
  171 
  172         return (val);
  173 }
  174 
  175 /*
  176  * wrAddr()
  177  *      Write address to slave.
  178  *
  179  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  180  */
  181 void
  182 wrAddr(destination, address)
  183         unsigned char destination, address;
  184 {
  185         register struct cpuslic *sl = va_slic;
  186 
  187         sl->sl_dest = destination;
  188         sl->sl_smessage = address;
  189         sl->sl_cmd_stat = SL_WRADDR;
  190         while (sl->sl_cmd_stat & SL_BUSY)
  191                 continue;
  192 #ifdef  CHECKSLIC
  193         check_slic("wrAddr");
  194 #endif  CHECKSLIC
  195 }
  196 
  197 /*
  198  * wrData()
  199  *      Write data to previously addressed slave register.
  200  *
  201  * Internal interface.
  202  *
  203  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  204  */
  205 void
  206 wrData(destination, data)
  207         unsigned char destination, data;
  208 {
  209         register struct cpuslic *sl = va_slic;
  210 
  211         sl->sl_dest = destination;
  212         sl->sl_smessage = data;
  213         sl->sl_cmd_stat = SL_WRDATA;
  214         while (sl->sl_cmd_stat & SL_BUSY)
  215                 continue;
  216 #ifdef  CHECKSLIC
  217         check_slic("wrData");
  218 #endif  CHECKSLIC
  219 }
  220 
  221 /*
  222  * rdData()
  223  *      Read data from previously addressed slave register.
  224  *
  225  * Internal interface.
  226  *
  227  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  228  */
  229 
  230 int
  231 rdData(destination)
  232         unsigned char destination;
  233 {
  234         register struct cpuslic *sl = va_slic;
  235 
  236         sl->sl_dest = destination;
  237         sl->sl_cmd_stat = SL_RDDATA;
  238         while (sl->sl_cmd_stat & SL_BUSY)
  239                 continue;
  240 #ifdef  CHECKSLIC
  241         check_slic("rdData");
  242 #endif  CHECKSLIC
  243         return(sl->sl_sdr & 0xff);
  244 }
  245 
  246 /*
  247  * sendsoft()
  248  *      Post SW interrupt to somebody.
  249  *
  250  * Used to post resched "nudge", net handler interrupts, pff calc, softclock.
  251  *
  252  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  253  */
  254 
  255 sendsoft(dest, bitmask)
  256         unsigned char dest;
  257         unsigned char bitmask;
  258 {
  259         register struct cpuslic *sl = va_slic;
  260 
  261         sl->sl_dest = dest;
  262         sl->sl_smessage = bitmask;
  263 
  264         sl->sl_cmd_stat = SL_MINTR | 0;         /* 0 ==> bin 0 */
  265         while (sl->sl_cmd_stat & SL_BUSY)
  266                 continue;
  267 
  268 #ifdef  CHECKSLIC
  269         check_slic("sendsoft");
  270 #endif  CHECKSLIC
  271 }
  272 
  273 /*
  274  * nmIntr()
  275  *      Post NMI interrupt to somebody.
  276  *
  277  * Used to post send NMI to a processor to have it shut down.
  278  *
  279  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  280  */
  281 
  282 nmIntr(dest, message)
  283         unsigned char dest;
  284         unsigned char message;
  285 {
  286         register struct cpuslic *sl = va_slic;
  287 
  288         sl->sl_dest = dest;
  289         sl->sl_smessage = message;
  290 
  291         do {
  292                 sl->sl_cmd_stat = SL_NMINTR;
  293                 while (sl->sl_cmd_stat & SL_BUSY)
  294                         continue;
  295         } while ((sl->sl_cmd_stat & SL_OK) == 0);
  296 #ifdef  CHECKSLIC
  297         check_slic("nmIntr");
  298 #endif  CHECKSLIC
  299 }
  300 
  301 /*
  302  * mIntr()
  303  *      Post HW interrupt to somebody.
  304  *
  305  * Used to send commands to MBAd's.
  306  *
  307  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  308  *
  309  * Implementation acquires gate before sending message, to avoid SLIC bus
  310  * saturation.
  311  */
  312 
  313 #ifdef  PERFSTAT
  314 #define MINTR_MAXHIST   65
  315 int     mintr_hist[MINTR_MAXHIST];
  316 #endif  PERFSTAT
  317 
  318 mIntr(dest, bin, data)
  319         unsigned char dest;
  320         unsigned char bin;
  321         unsigned char data;
  322 {
  323         register struct cpuslic *sl = va_slic;
  324         register unsigned stat;
  325 #ifdef  PERFSTAT
  326         register int mintr_cnt = 0;
  327 #endif  PERFSTAT
  328 
  329         /*
  330          * Send message.  Spin forever until sent.
  331          */
  332 
  333         sl->sl_dest = dest;
  334         sl->sl_smessage = data;
  335 
  336         do {
  337 #ifdef  PERFSTAT
  338                 ++mintr_cnt;
  339 #endif  PERFSTAT
  340                 sl->sl_cmd_stat = SL_MINTR | bin;
  341                 while ((stat = sl->sl_cmd_stat) & SL_BUSY)
  342                         continue;
  343         } while ((stat & SL_OK) == 0);
  344 
  345 #ifdef  PERFSTAT
  346         if (mintr_cnt > MINTR_MAXHIST)
  347                 mintr_cnt = MINTR_MAXHIST;
  348         ++mintr_hist[mintr_cnt-1];
  349 #endif  PERFSTAT
  350 
  351 #ifdef  CHECKSLIC
  352         check_slic("mIntr");
  353 #endif  CHECKSLIC
  354 
  355         /*
  356          * Release mIntr gate.
  357          */
  358 
  359 }
  360 
  361 /*
  362  * setgm()
  363  *      Set group mask in destination slic.
  364  *
  365  * Caller assures mutex of SLIC usage (splhi() or holding gate is sufficient).
  366  */
  367 
  368 setgm(dest, mask)
  369         unsigned char dest;
  370         unsigned char mask;
  371 {
  372         register struct cpuslic *sl = va_slic;
  373 
  374         sl->sl_dest = dest;                     /* set this guy's... */
  375         sl->sl_smessage = mask;                 /* group mask to "mask" */
  376         sl->sl_cmd_stat = SL_SETGM;             /* set the group-mask */
  377         while (sl->sl_cmd_stat & SL_BUSY)       /* and wait for cmd done */
  378                 continue;
  379 
  380 #ifdef  CHECKSLIC
  381         check_slic("setgm");
  382 #endif  CHECKSLIC
  383 }
  384 
  385 /*
  386  * lock_subslave(), unlock_subslave()
  387  *      Mutex access to certain slic/sub-slave combinations which
  388  *      may be shared (eg, processor BIC -- both processors access
  389  *      the BIC via only one of their slic id's).
  390  *
  391  * Other uses of slic slave addressing is mutually excluded at higher levels;
  392  * upper level code only online/offline's one processor at a time, memory
  393  * error polling guaranteed single-thread, etc.
  394  */
  395 
  396 spl_t
  397 lock_subslave(slic, slave)
  398         unsigned char slic, slave;
  399 {
  400         return 0;
  401 }
  402 
  403 void
  404 unlock_subslave(slic, slave, s)
  405         unsigned char slic, slave;
  406         spl_t   s;
  407 {
  408 }
  409 
  410 #ifdef  CHECKSLIC
  411 /* 
  412  * check_slic()
  413  *      Check status from SLIC for parity, exists, and ok bits.
  414  */
  415 
  416 check_slic(procname)
  417         char    *procname;
  418 {
  419         register unsigned stat;
  420 
  421         stat = va_slic->sl_cmd_stat;
  422 
  423         if ((stat & SL_PARITY) == 0) {
  424                 printf("%s: slic parity error\n", procname);
  425                 panic("slic");
  426                 /*NOTREACHED*/
  427         }
  428         if ((stat & SL_EXISTS) == 0) {
  429                 printf("%s: slic(s) don't exist\n", procname);
  430                 panic("slic");
  431                 /*NOTREACHED*/
  432         }
  433         if ((stat & SL_OK) == 0) {
  434                 printf("%s: slic not ok\n", procname);
  435                 panic("slic");
  436                 /*NOTREACHED*/
  437         }
  438 }
  439 #endif  CHECKSLIC

Cache object: f4e08ec5e57df313af1b2852c9d93bb6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.