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/5.2/sys/powerpc/powerpc/cpu.c 120460 2003-09-26 09:02:24Z 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 8240",      MPC8240,        REVFMT_MAJMIN },
   96         { "Unknown PowerPC CPU",        0,              REVFMT_HEX }
   97 };
   98 
   99 static register_t       l2cr_config = 0;
  100 
  101 static void     cpu_print_speed(void);
  102 static void     cpu_config_l2cr(u_int, uint16_t);
  103 
  104 void
  105 cpu_setup(u_int cpuid)
  106 {
  107         u_int           pvr, maj, min, hid0;
  108         uint16_t        vers, rev, revfmt;
  109         const struct    cputab *cp;
  110         const char      *name;
  111         char            *bitmask;
  112 
  113         pvr = mfpvr();
  114         vers = pvr >> 16;
  115         rev = pvr;
  116         switch (vers) {
  117         case MPC7410:
  118                 min = (pvr >> 0) & 0xff;
  119                 maj = min <= 4 ? 1 : 2;
  120                 break;
  121         default:
  122                 maj = (pvr >>  8) & 0xf;
  123                 min = (pvr >>  0) & 0xf;
  124         }
  125 
  126         for (cp = models; cp->name[0] != '\0'; cp++) {
  127                 if (cp->version == vers)
  128                         break;
  129         }
  130 
  131         revfmt = cp->revfmt;
  132         name = cp->name;
  133         if (rev == MPC750 && pvr == 15) {
  134                 name = "Motorola MPC755";
  135                 revfmt = REVFMT_HEX;
  136         }
  137 
  138         printf("cpu%d: %s revision ", cpuid, name);
  139 
  140         switch (revfmt) {
  141         case REVFMT_MAJMIN:
  142                 printf("%u.%u", maj, min);
  143                 break;
  144         case REVFMT_HEX:
  145                 printf("0x%04x", rev);
  146                 break;
  147         case REVFMT_DEC:
  148                 printf("%u", rev);
  149                 break;
  150         }
  151 
  152         hid0 = mfspr(SPR_HID0);
  153 
  154         /*
  155          * Configure power-saving mode.
  156          */
  157         switch (vers) {
  158         case MPC603:
  159         case MPC603e:
  160         case MPC603ev:
  161         case MPC604ev:
  162         case MPC750:
  163         case IBM750FX:
  164         case MPC7400:
  165         case MPC7410:
  166         case MPC8240:
  167         case MPC8245:
  168                 /* Select DOZE mode. */
  169                 hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
  170                 hid0 |= HID0_DOZE | HID0_DPM;
  171 #ifdef notyet
  172                 powersave = 1;
  173 #endif
  174                 break;
  175 
  176         case MPC7455:
  177         case MPC7450:
  178                 /* Disable BTIC on 7450 Rev 2.0 or earlier */
  179                 if ((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
  180                         hid0 &= ~HID0_BTIC;
  181                 /* Select NAP mode. */
  182                 hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
  183                 hid0 |= HID0_NAP | HID0_DPM;
  184 #ifdef notyet
  185                 powersave = 0;          /* but don't use it */
  186 #endif
  187                 break;
  188 
  189         default:
  190                 /* No power-saving mode is available. */ ;
  191         }
  192 
  193         switch (vers) {
  194         case IBM750FX:
  195         case MPC750:
  196                 hid0 &= ~HID0_DBP;              /* XXX correct? */
  197                 hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
  198                 break;
  199 
  200         case MPC7400:
  201         case MPC7410:
  202                 hid0 &= ~HID0_SPD;
  203                 hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
  204                 hid0 |= HID0_EIEC;
  205                 break;
  206         }
  207 
  208         mtspr(SPR_HID0, hid0);
  209 
  210         switch (vers) {
  211         case MPC7450:
  212         case MPC7455:
  213                 bitmask = HID0_7450_BITMASK;
  214                 break;
  215         default:
  216                 bitmask = HID0_BITMASK;
  217                 break;
  218         }
  219 
  220         switch (vers) {
  221         case MPC750:
  222         case IBM750FX:
  223         case MPC7400:
  224         case MPC7410:
  225         case MPC7450:
  226         case MPC7455:
  227                 cpu_print_speed();
  228                 printf("\n");
  229                 cpu_config_l2cr(cpuid, vers);
  230                 break;
  231 
  232         default:
  233                 printf("\n");
  234                 break;
  235         }
  236 
  237         printf("cpu%d: HID0 %b\n", cpuid, hid0, bitmask);
  238 }
  239 
  240 void
  241 cpu_print_speed(void)
  242 {
  243         uint64_t        cps;
  244 
  245         mtspr(SPR_MMCR0, SPR_MMCR0_FC);
  246         mtspr(SPR_PMC1, 0);
  247         mtspr(SPR_MMCR0, SPR_MMCR0_PMC1SEL(PMCN_CYCLES));
  248         DELAY(100000);
  249         cps = (mfspr(SPR_PMC1) * 10) + 4999;
  250         printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
  251 }
  252 
  253 void
  254 cpu_config_l2cr(u_int cpuid, uint16_t vers)
  255 {
  256         u_int l2cr, x, msr;
  257 
  258         l2cr = mfspr(SPR_L2CR);
  259 
  260         /*
  261          * For MP systems, the firmware may only configure the L2 cache
  262          * on the first CPU.  In this case, assume that the other CPUs
  263          * should use the same value for L2CR.
  264          */
  265         if ((l2cr & L2CR_L2E) != 0 && l2cr_config == 0) {
  266                 l2cr_config = l2cr;
  267         }
  268 
  269         /*
  270          * Configure L2 cache if not enabled.
  271          */
  272         if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) {
  273                 l2cr = l2cr_config;
  274 
  275                 /* Disable interrupts and set the cache config bits. */
  276                 msr = mfmsr();
  277                 mtmsr(msr & ~PSL_EE);
  278 #ifdef ALTIVEC
  279                 if (cpu_altivec)
  280                         __asm __volatile("dssall");
  281 #endif
  282                 __asm __volatile("sync");
  283                 mtspr(SPR_L2CR, l2cr & ~L2CR_L2E);
  284                 __asm __volatile("sync");
  285 
  286                 /* Wait for L2 clock to be stable (640 L2 clocks). */
  287                 DELAY(100);
  288 
  289                 /* Invalidate all L2 contents. */
  290                 mtspr(SPR_L2CR, l2cr | L2CR_L2I);
  291                 do {
  292                         x = mfspr(SPR_L2CR);
  293                 } while (x & L2CR_L2IP);
  294 
  295                 /* Enable L2 cache. */
  296                 l2cr |= L2CR_L2E;
  297                 mtspr(SPR_L2CR, l2cr);
  298                 mtmsr(msr);
  299         }
  300 
  301         if (!bootverbose)
  302                 return;
  303 
  304         printf("cpu%d: ", cpuid);
  305 
  306         if (l2cr & L2CR_L2E) {
  307                 if (vers == MPC7450 || vers == MPC7455) {
  308                         u_int l3cr;
  309 
  310                         printf("256KB L2 cache");
  311 
  312                         l3cr = mfspr(SPR_L3CR);
  313                         if (l3cr & L3CR_L3E)
  314                                 printf(", %cMB L3 backside cache",
  315                                    l3cr & L3CR_L3SIZ ? '2' : '1');
  316                         printf("\n");
  317                         return;
  318                 }
  319                 if (vers == IBM750FX) {
  320                         printf("512KB L2 cache\n");
  321                         return;
  322                 }
  323                 switch (l2cr & L2CR_L2SIZ) {
  324                 case L2SIZ_256K:
  325                         printf("256KB");
  326                         break;
  327                 case L2SIZ_512K:
  328                         printf("512KB");
  329                         break;
  330                 case L2SIZ_1M:
  331                         printf("1MB");
  332                         break;
  333                 default:
  334                         printf("unknown size");
  335                 }
  336                 if (l2cr & L2CR_L2WT) {
  337                         printf(" write-through");
  338                 } else {
  339                         printf(" write-back");
  340                 }
  341                 switch (l2cr & L2CR_L2RAM) {
  342                 case L2RAM_FLOWTHRU_BURST:
  343                         printf(" flow-through synchronous burst SRAM");
  344                         break;
  345                 case L2RAM_PIPELINE_BURST:
  346                         printf(" pipelined synchronous burst SRAM");
  347                         break;
  348                 case L2RAM_PIPELINE_LATE:
  349                         printf(" pipelined synchronous late-write SRAM");
  350                         break;
  351                 default:
  352                         printf(" unknown type");
  353                 }
  354 
  355                 if (l2cr & L2CR_L2PE)
  356                         printf(" with parity");
  357                 printf(" backside cache");
  358         } else
  359                 printf("L2 cache not enabled");
  360 
  361         printf("\n");
  362 }

Cache object: 147b2bbb0b0e5e041d7f5c64a3fd88b0


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