Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

/*
 * caches defined by arm v7 architecture
 */
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "arm.h"

static char *
l1iptype(uint type)
{
        static char *types[] = {
                "reserved",
                "asid-tagged VIVT",
                "VIPT",
                "PIPT",
        };

        if (type >= nelem(types) || types[type] == nil)
                return "GOK";
        return types[type];
}

static char *catype[] = {
        "none,",
        "i,",
        "d,",
        "split i&d,",
        "unified,",
        "gok,",
        "gok,",
        "gok,",
};

void
cacheinfo(int level, Memcache *cp, int ext, int type)
{
        ulong setsways;

        memset(cp, 0, sizeof *cp);
        if (type == Nocache)
                return;
        cp->level = level;
        cp->type = type;
        cp->external = ext;
        if (level == 2) {                       /* external PL310 */
                allcache->info(cp);
                setsways = cp->setsways;
        } else {
                /* select internal cache level */
                cpwrsc(CpIDcssel, CpID, CpIDid, 0, (level - 1) << 1);

                setsways = cprdsc(CpIDcsize, CpID, CpIDid, 0);
                cp->l1ip = cpctget();
                cp->nways = ((setsways >> 3)  & MASK(10)) + 1;
                cp->nsets = ((setsways >> 13) & MASK(15)) + 1;
                cp->log2linelen = (setsways & MASK(2)) + 2 + 2;
        }
        cp->linelen = 1 << cp->log2linelen;
        cp->setsways = setsways;
        cp->setsh = cp->log2linelen;
        cp->waysh = 32 - log2(cp->nways);
}

void
allcacheinfo(Memcache *mc)
{
        int n;
        ulong lvl;

        lvl = cprdsc(CpIDcsize, CpID, CpIDidct, CpIDclvlid);
        n = 1;
        for (lvl &= MASK(21); lvl; lvl >>= 3)
                cacheinfo(n, &mc[n], Intcache, lvl & MASK(3));
//      cacheinfo(2, &mc[2], Extcache, Unified);                /* PL310 */
}

void
prcachecfg(void)
{
        int cache;
        Memcache *mc;

        for (cache = 1; cache < 8 && cachel[cache].type; cache++) {
                mc = &cachel[cache];
                iprint("l%d: %s %-10s %2d ways %4d sets %d bytes/line; can W[",
                        mc->level, mc->external? "ext": "int", catype[mc->type],
                        mc->nways, mc->nsets, mc->linelen);
                if (mc->linelen != CACHELINESZ)
                        iprint(" *should* be %d", CACHELINESZ);
                if (mc->setsways & Cawt)
                        iprint("T");
                if (mc->setsways & Cawb)
                        iprint("B");
                if (mc->setsways & Cawa)
                        iprint("A");
                iprint("]");
                if (cache == 1)
                        iprint("; l1-i %s", l1iptype((mc->l1ip >> 14) & MASK(2)));
                iprint("\n");
        }
}