Here is the code in C.

This code is simple enough to put into stage 2.

I will look at that next. People can check me on this code.

ron
/* Copyright (C) 2008 Vincent Legoll <[EMAIL PROTECTED]>
  * Convert to c (C) 2008 Ronald G. Minnich <[EMAIL PROTECTED]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <stdio.h>

typedef unsigned char u8;
typedef unsigned long u32;

#define BITS(r, shift, mask) (((r>>shift)&mask))

char *re(u32 i)
{
        if (i & 1) 
                return "R";
        else
                return "";
}

char *we(u32 i)
{
        if (i & 1) 
                return "W";
        else
                return "";
}

char *ileave(u32 base)
{
        switch((base >> 8) & 7) {
                case 0: return "No interleave";
                case 1: return "2 nodes";
                case 3: return "4 nodes";
                case 7: return "8 nodes";
                default: return "Reserved";
        }
}

/* nbote that these are not right in all cases. If we don't use them we 
probably were not 
 * supposed to 
 */
int node(u32 reg)
{
        return BITS(reg, 0, 7);
}

int link(u32 reg)
{
        return BITS(reg, 4, 3);
}

/* these, arguably, should take a struct like the msr struct */
void dram(char *out, u8 which, u32 base, u32 lim)
{
        sprintf(out, "%08x-%08x, ->(%d), %s, %s, %s, %d", 
((base&0xfff0000)<<8), ((lim&0xffff0000<<8))+0xffffff, node(lim), re(base), 
we(base), ileave(base), (lim>>8)&3);
}

void config(char *out, u8 which, u32 reg)
{
        /* don't use node() and link() here */
        sprintf(out, "Base %02x Lim %02x %s %s CE %d %d %d\n", BITS(reg, 24, 
0xff), BITS(reg, 16, 0xff),        
                        re(reg), we(reg), BITS(reg, 0, 4), BITS(reg, 4, 7), 
BITS(reg, 8, 3));
}
                        
void pciio(char *out, u8 which, u32 base, u32 lim)
{
        sprintf(out, "%08x-%08x, ->(%d,%d), %s, %s,VGA %d ISA %d", 
                        BITS(base, 12, 0x3fff), BITS(lim, 12, 0x3fff), 
node(lim), link(lim),
                        re(base), we(base), BITS(base, 4, 1), BITS(base, 5, 1));
}

void mmio(char *out, u8 which, u32 base, u32 lim)
{
        sprintf(out, "%08x-%08x, ->(%d,%d), %s, %s, CPU disable %d, Lock %d, 
Non posted %d", 
                        BITS(base, 0, 0xffffff00)<<8, (BITS(lim, 0, 
0xffffff00)<<8)+0xffff, 
                        node(lim), link(lim), re(base), we(base), BITS(base, 4, 
1), 
                        BITS(base, 7, 1), BITS(lim, 7, 1));

}

#define RANGE(l, low, high) ((l >= low) && (l <= high))

main(int argc, char *argv[])
{
        /* args are taken as triples: reg #, base, lim */
        /* except config, which are not base, limit */
        static char out[128];

        argc--, argv++;
        while (argc > 0) {
                u32 reg = strtoul(argv[0], 0, 0);
                if (RANGE(reg, 0x40, 0x7c)) {
                        dram(out, reg, strtoul(argv[1], 0, 0), strtoul(argv[2], 
0, 0));
                        argv += 3, argc -= 3;
                } else if (RANGE(reg, 0x80, 0xbc)) {
                        mmio(out, reg, strtoul(argv[1], 0, 0), strtoul(argv[2], 
0, 0));
                        argv += 3, argc -= 3;
                } else if (RANGE(reg, 0xc0, 0xdc)) {
                        pciio(out, reg, strtoul(argv[1], 0, 0), 
strtoul(argv[2], 0, 0));
                        argv += 3, argc -= 3;
                } else if (RANGE(reg, 0xe0, 0xec)) {
                        config(out, reg, strtoul(argv[1], 0, 0));
                        argv += 2, argc -= 2;
                } else errx(1, "Bad register 0x%x", reg);
                printf("%02x: %s\n", reg, out);
        }
}
/* make reg */
/* sample runs
[EMAIL PROTECTED] tmp]# /sbin/setpci -s 0:18.1 90.l
00f00003
[EMAIL PROTECTED] tmp]# /sbin/setpci -s 0:18.1 94.l
00f7fe80
[EMAIL PROTECTED] tmp]# ./reg 0x90 0xf0003 0xf7fe80
90: 0f000000-f7feffff, ->(0,0), R, W, CPU disable 0, Lock 0, Non posted 1

[EMAIL PROTECTED] tmp]# /sbin/setpci -s 0:18.1 c0.l
00001013
[EMAIL PROTECTED] tmp]# /sbin/setpci -s 0:18.1 c4.l
00fff000
[EMAIL PROTECTED] tmp]# ./reg 0xc0 0x1013 0xfff000
c0: 00000001-00000fff, ->(0,0), R, W,VGA 1 ISA 0
[EMAIL PROTECTED] tmp]# 

[EMAIL PROTECTED] tmp]# /sbin/setpci -s 0:18.1 40.l
00000003
[EMAIL PROTECTED] tmp]# /sbin/setpci -s 0:18.1 44.l
003f0000
[EMAIL PROTECTED] tmp]# ./reg  0x40 3 0x3f0000
40: 00000000-00ffffff, ->(0), R, W, No interleave, 0
[EMAIL PROTECTED] tmp]# 

*/
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to