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/powerpc/powerpc/cpu.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  * Copyright (c) 2001 Matt Thomas.
    3  * Copyright (c) 2001 Tsubai Masanari.
    4  * Copyright (c) 1998, 1999, 2001 Internet Research Institute, Inc.
    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
   18  *      Internet Research Institute, Inc.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 /*-
   34  * Copyright (C) 2003 Benno Rice.
   35  * All rights reserved.
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  *
   46  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   47  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   48  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   49  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   52  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   53  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   54  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   55  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   56  *
   57  * from $NetBSD: cpu_subr.c,v 1.1 2003/02/03 17:10:09 matt Exp $
   58  * $FreeBSD: releng/6.1/sys/powerpc/powerpc/cpu.c 141229 2005-02-04 01:59:48Z grehan $
   59  */
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/bus.h>
   64 #include <sys/conf.h>
   65 #include <sys/kernel.h>
   66 
   67 #include <machine/bus.h>
   68 #include <machine/hid.h>
   69 #include <machine/md_var.h>
   70 #include <machine/spr.h>
   71 
   72 struct cputab {
   73         const char      *name;
   74         uint16_t        version;
   75         uint16_t        revfmt;
   76 };
   77 #define REVFMT_MAJMIN   1       /* %u.%u */
   78 #define REVFMT_HEX      2       /* 0x%04x */
   79 #define REVFMT_DEC      3       /* %u */
   80 static const struct cputab models[] = {
   81         { "Motorola PowerPC 601",       MPC601,         REVFMT_DEC },
   82         { "Motorola PowerPC 602",       MPC602,         REVFMT_DEC },
   83         { "Motorola PowerPC 603",       MPC603,         REVFMT_MAJMIN },
   84         { "Motorola PowerPC 603e",      MPC603e,        REVFMT_MAJMIN },
   85         { "Motorola PowerPC 603ev",     MPC603ev,       REVFMT_MAJMIN },
   86         { "Motorola PowerPC 604",       MPC604,         REVFMT_MAJMIN },
   87         { "Motorola PowerPC 604ev",     MPC604ev,       REVFMT_MAJMIN },
   88         { "Motorola PowerPC 620",       MPC620,         REVFMT_HEX },
   89         { "Motorola PowerPC 750",       MPC750,         REVFMT_MAJMIN },
   90         { "IBM PowerPC 750FX",          IBM750FX,       REVFMT_MAJMIN },
   91         { "Motorola PowerPC 7400",      MPC7400,        REVFMT_MAJMIN },
   92         { "Motorola PowerPC 7410",      MPC7410,        REVFMT_MAJMIN },
   93         { "Motorola PowerPC 7450",      MPC7450,        REVFMT_MAJMIN },
   94         { "Motorola PowerPC 7455",      MPC7455,        REVFMT_MAJMIN },
   95         { "Motorola PowerPC 7457",      MPC7457,        REVFMT_MAJMIN },
   96         { "Motorola PowerPC 7447A",     MPC7447A,       REVFMT_MAJMIN },
   97         { "Motorola PowerPC 7448",      MPC7448,        REVFMT_MAJMIN },
   98         { "Motorola PowerPC 8240",      MPC8240,        REVFMT_MAJMIN },
   99         { "Unknown PowerPC CPU",        0,              REVFMT_HEX }
  100 };
  101 
  102 static register_t       l2cr_config = 0;
  103 
  104 static void     cpu_print_speed(void);
  105 static void     cpu_config_l2cr(u_int, uint16_t);
  106 
  107 void
  108 cpu_setup(u_int cpuid)
  109 {
  110         u_int           pvr, maj, min, hid0;
  111         uint16_t        vers, rev, revfmt;
  112         const struct    cputab *cp;
  113         const char      *name;
  114         char            *bitmask;
  115 
  116         pvr = mfpvr();
  117         vers = pvr >> 16;
  118         rev = pvr;
  119         switch (vers) {
  120         case MPC7410:
  121                 min = (pvr >> 0) & 0xff;
  122                 maj = min <= 4 ? 1 : 2;
  123                 break;
  124         default:
  125                 maj = (pvr >>  8) & 0xf;
  126                 min = (pvr >>  0) & 0xf;
  127         }
  128 
  129         for (cp = models; cp->name[0] != '\0'; cp++) {
  130                 if (cp->version == vers)
  131                         break;
  132         }
  133 
  134         revfmt = cp->revfmt;
  135         name = cp->name;
  136         if (rev == MPC750 && pvr == 15) {
  137                 name = "Motorola MPC755";
  138                 revfmt = REVFMT_HEX;
  139         }
  140 
  141         printf("cpu%d: %s revision ", cpuid, name);
  142 
  143         switch (revfmt) {
  144         case REVFMT_MAJMIN:
  145                 printf("%u.%u", maj, min);
  146                 break;
  147         case REVFMT_HEX:
  148                 printf("0x%04x", rev);
  149                 break;
  150         case REVFMT_DEC:
  151                 printf("%u", rev);
  152                 break;
  153         }
  154 
  155         hid0 = mfspr(SPR_HID0);
  156 
  157         /*
  158          * Configure power-saving mode.
  159          */
  160         switch (vers) {
  161         case MPC603:
  162         case MPC603e:
  163         case MPC603ev:
  164         case MPC604ev:
  165         case MPC750:
  166         case IBM750FX:
  167         case MPC7400:
  168         case MPC7410:
  169         case MPC8240:
  170         case MPC8245:
  171                 /* Select DOZE mode. */
  172                 hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
  173                 hid0 |= HID0_DOZE | HID0_DPM;
  174 #ifdef notyet
  175                 powersave = 1;
  176 #endif
  177                 break;
  178 
  179         case MPC7448:
  180         case MPC7447A:
  181         case MPC7457:
  182         case MPC7455:
  183         case MPC7450:
  184                 /* Enable the 7450 branch caches */
  185                 hid0 |= HID0_SGE | HID0_BTIC;
  186                 hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
  187                 /* Disable BTIC on 7450 Rev 2.0 or earlier and on 7457 */
  188                 if (((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
  189                     || (pvr >> 16) == MPC7457)
  190                         hid0 &= ~HID0_BTIC;
  191                 /* Select NAP mode. */
  192                 hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
  193                 hid0 |= HID0_NAP | HID0_DPM;
  194 #ifdef notyet
  195                 powersave = 0;          /* but don't use it */
  196 #endif
  197                 break;
  198 
  199         default:
  200                 /* No power-saving mode is available. */ ;
  201         }
  202 
  203         switch (vers) {
  204         case IBM750FX:
  205         case MPC750:
  206                 hid0 &= ~HID0_DBP;              /* XXX correct? */
  207                 hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
  208                 break;
  209 
  210         case MPC7400:
  211         case MPC7410:
  212                 hid0 &= ~HID0_SPD;
  213                 hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
  214                 hid0 |= HID0_EIEC;
  215                 break;
  216         }
  217 
  218         mtspr(SPR_HID0, hid0);
  219 
  220         switch (vers) {
  221         case MPC7447A:
  222         case MPC7448:
  223         case MPC7450:
  224         case MPC7455:
  225         case MPC7457:
  226                 bitmask = HID0_7450_BITMASK;
  227                 break;
  228         default:
  229                 bitmask = HID0_BITMASK;
  230                 break;
  231         }
  232 
  233         switch (vers) {
  234         case MPC750:
  235         case IBM750FX:
  236         case MPC7400:
  237         case MPC7410:
  238         case MPC7447A:
  239         case MPC7448:
  240         case MPC7450:
  241         case MPC7455:
  242         case MPC7457:
  243                 cpu_print_speed();
  244                 printf("\n");
  245                 cpu_config_l2cr(cpuid, vers);
  246                 break;
  247 
  248         default:
  249                 printf("\n");
  250                 break;
  251         }
  252 
  253         printf("cpu%d: HID0 %b\n", cpuid, hid0, bitmask);
  254 }
  255 
  256 void
  257 cpu_print_speed(void)
  258 {
  259         uint64_t        cps;
  260 
  261         mtspr(SPR_MMCR0, SPR_MMCR0_FC);
  262         mtspr(SPR_PMC1, 0);
  263         mtspr(SPR_MMCR0, SPR_MMCR0_PMC1SEL(PMCN_CYCLES));
  264         DELAY(100000);
  265         cps = (mfspr(SPR_PMC1) * 10) + 4999;
  266         printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
  267 }
  268 
  269 void
  270 cpu_config_l2cr(u_int cpuid, uint16_t vers)
  271 {
  272         u_int l2cr, x, msr;
  273 
  274         l2cr = mfspr(SPR_L2CR);
  275 
  276         /*
  277          * For MP systems, the firmware may only configure the L2 cache
  278          * on the first CPU.  In this case, assume that the other CPUs
  279          * should use the same value for L2CR.
  280          */
  281         if ((l2cr & L2CR_L2E) != 0 && l2cr_config == 0) {
  282                 l2cr_config = l2cr;
  283         }
  284 
  285         /*
  286          * Configure L2 cache if not enabled.
  287          */
  288         if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) {
  289                 l2cr = l2cr_config;
  290 
  291                 /* Disable interrupts and set the cache config bits. */
  292                 msr = mfmsr();
  293                 mtmsr(msr & ~PSL_EE);
  294 #ifdef ALTIVEC
  295                 if (cpu_altivec)
  296                         __asm __volatile("dssall");
  297 #endif
  298                 __asm __volatile("sync");
  299                 mtspr(SPR_L2CR, l2cr & ~L2CR_L2E);
  300                 __asm __volatile("sync");
  301 
  302                 /* Wait for L2 clock to be stable (640 L2 clocks). */
  303                 DELAY(100);
  304 
  305                 /* Invalidate all L2 contents. */
  306                 mtspr(SPR_L2CR, l2cr | L2CR_L2I);
  307                 do {
  308                         x = mfspr(SPR_L2CR);
  309                 } while (x & L2CR_L2IP);
  310 
  311                 /* Enable L2 cache. */
  312                 l2cr |= L2CR_L2E;
  313                 mtspr(SPR_L2CR, l2cr);
  314                 mtmsr(msr);
  315         }
  316 
  317         if (!bootverbose)
  318                 return;
  319 
  320         printf("cpu%d: ", cpuid);
  321 
  322         if (l2cr & L2CR_L2E) {
  323                 if (vers == MPC7450 || 
  324                     vers == MPC7455 ||
  325                     vers == MPC7457) {
  326                         u_int l3cr;
  327 
  328                         printf("256KB L2 cache");
  329 
  330                         l3cr = mfspr(SPR_L3CR);
  331                         if (l3cr & L3CR_L3E)
  332                                 printf(", %cMB L3 backside cache",
  333                                    l3cr & L3CR_L3SIZ ? '2' : '1');
  334                         printf("\n");
  335                         return;
  336                 }
  337                 if (vers == IBM750FX) {
  338                         printf("512KB L2 cache\n");
  339                         return;
  340                 }
  341                 switch (l2cr & L2CR_L2SIZ) {
  342                 case L2SIZ_256K:
  343                         printf("256KB");
  344                         break;
  345                 case L2SIZ_512K:
  346                         printf("512KB");
  347                         break;
  348                 case L2SIZ_1M:
  349                         printf("1MB");
  350                         break;
  351                 default:
  352                         printf("unknown size");
  353                 }
  354                 if (l2cr & L2CR_L2WT) {
  355                         printf(" write-through");
  356                 } else {
  357                         printf(" write-back");
  358                 }
  359                 switch (l2cr & L2CR_L2RAM) {
  360                 case L2RAM_FLOWTHRU_BURST:
  361                         printf(" flow-through synchronous burst SRAM");
  362                         break;
  363                 case L2RAM_PIPELINE_BURST:
  364                         printf(" pipelined synchronous burst SRAM");
  365                         break;
  366                 case L2RAM_PIPELINE_LATE:
  367                         printf(" pipelined synchronous late-write SRAM");
  368                         break;
  369                 default:
  370                         printf(" unknown type");
  371                 }
  372 
  373                 if (l2cr & L2CR_L2PE)
  374                         printf(" with parity");
  375                 printf(" backside cache");
  376         } else
  377                 printf("L2 cache not enabled");
  378 
  379         printf("\n");
  380 }

Cache object: efc497c34bb2eb4a06533d8eadcea5fc


[ 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.