Index: boot2.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/boot/boot2.c,v retrieving revision 1.57 diff -u -r1.57 boot2.c --- boot2.c 25 Dec 2011 06:09:09 -0000 1.57 +++ boot2.c 26 Jan 2012 12:03:33 -0000 @@ -122,6 +122,12 @@ void command_consdev(char *); void command_modules(char *); void command_multiboot(char *); +#if 1 /* XXX: XXXNONAKA */ +void command_memoryread_4(char *); +void command_memorywrite_4(char *); +void command_dump_pcicfg(char *); +void command_write_pcicfg(char *); +#endif /* XXX: XXXNONAKA */ const struct bootblk_command commands[] = { { "help", command_help }, @@ -138,6 +144,12 @@ { "splash", splash_add }, { "rndseed", rnd_add }, { "userconf", userconf_add }, +#if 1 /* XXX: XXXNONAKA */ + { "mrd", command_memoryread_4 }, + { "mwd", command_memorywrite_4 }, + { "pcicfgr", command_dump_pcicfg }, + { "pcicfgw", command_write_pcicfg }, +#endif /* XXX: XXXNONAKA */ { NULL, NULL }, }; @@ -399,6 +411,12 @@ "multiboot [xdNx:][filename] []\n" "userconf {command}\n" "rndseed {path_to_rndseed_file}\n" +#if 1 /* XXX: XXXNONAKA start */ + "mrd {address} [length]\n" + "mwd {address} {value}\n" + "pcicfgr {bus} {device} {function}\n" + "pcicfgw {bus} {device} {function} {address} {value}\n" +#endif /* XXX: XXXNONAKA start */ "help|?\n" "quit\n"); } @@ -520,3 +538,403 @@ printf("boot returned\n"); } +#if 1 /* XXX: XXXNONAKA start */ +static void +hexstr(char *p, uint32_t value) +{ + int i; + + for (i = 0; i < 8; i++) + p[i] = hexdigits[(value >> (4 * (7 - i))) & 0xf]; + p[8] = '\0'; +} + +static int +decode_4(uint32_t *p, char *buf, size_t len) +{ + uint32_t value = 0; + int hexoffset = 2; + int i, c; + + if (len == 0) + return -1; + + if (len >= 3 && buf[0] == '0' && buf[1] == 'x') { + hex: + if (len > 8 + hexoffset) + goto error; + + for (i = hexoffset; i < len; i++) { + value <<= 4; + c = buf[i]; + if (c >= '0' && c <= '9') { + value += c - '0'; + } else if (c >= 'A' && c <= 'F') { + value += c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + value += c - 'a' + 10; + } else + goto error; + } + } else if (len <= 10) { + for (i = 0; i < len; i++) { + c = buf[i]; + if (c >= '0' && c <= '9') { + value *= 10; + value += c - '0'; + } else if ((c >= 'A' && c <= 'F') || + (c >= 'a' && c <= 'f')) { + /* switch to hex decoding */ + hexoffset = 0; + goto hex; + } else + goto error; + } + } else + goto error; + + *p = value; + return 0; + + error: + return -1; +} + +static int +scan(char **top, char **next, char *p, bool iserror) +{ + + /* skip space and tab */ + for (;; p++) { + if (*p == '\0') + return -1; + if (*p != ' ' && *p != '\t') + break; + } + + *top = p; + for (;; p++) { + if (*p == '\0') { + if (iserror) + return -1; + p = NULL; + break; + } + if (*p == ' ' || *p == '\t') { + *p++ = '\0'; + break; + } + } + if (next != NULL) + *next = p; + return 0; +} + +void +command_memoryread_4(char *arg) +{ + char hex[9]; + char *p = arg; + volatile uint32_t *mem; + char *addressp, *lenp; + uint32_t address, len; + int rv; + int i; + + rv = scan(&addressp, &p, p, false); + if (rv != 0) + goto error; + rv = decode_4(&address, addressp, strlen(addressp)); + if (rv != 0) + goto error; + address = address & ~3; + + if (p != NULL) { + rv = scan(&lenp, NULL, p, false); + if (rv != 0) + goto error; + rv = decode_4(&len, lenp, strlen(lenp)); + if (rv != 0) + goto error; + len = (len + 3) & ~3; + } else + len = 4; + +#if 1 /* XXX: va:0x00000000 <-> pa:0x00010000(SECONDARY_LOAD_ADDRESS) */ + address -= 0x10000; +#endif + mem = (volatile uint32_t *)address; + for (len /= 4, i = 0; len > 0; mem++, len--, i++) { + if ((i % 4) == 0) { + hexstr(hex, (uint32_t)mem); + printf("%s%s:", (i != 0) ? "\n" : "", hex); + } + hexstr(hex, *mem); + printf(" %s", hex); + } + printf("\n"); + return; + + error: + printf("invalid argument:
{length}\n"); + printf(" ex. mrd 0xfe567890 256\n"); +} + +void +command_memorywrite_4(char *arg) +{ + char hex[9]; + char *p = arg; + volatile uint32_t *mem; + char *addressp, *valuep; + uint32_t address, value; + int rv; + + rv = scan(&addressp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&address, addressp, strlen(addressp)); + if (rv != 0) + goto error; + + rv = scan(&valuep, NULL, p, false); + if (rv != 0) + goto error; + rv = decode_4(&value, valuep, strlen(valuep)); + if (rv != 0) + goto error; + +#if 1 /* XXX: va:0x00000000 <-> pa:0x00010000(SECONDARY_LOAD_ADDRESS) */ + address -= 0x10000; +#endif + mem = (volatile uint32_t *)address; + + hexstr(hex, address); + printf("%s: ", hex); + hexstr(hex, *mem); + printf("%s -> ", hex); + + *mem = value; + + hexstr(hex, *mem); + printf("%s\n", hex); + + if (*mem != value) + printf("write failed\n"); + return; + + error: + printf("invalid argument:
\n"); + printf(" ex. mwd 0x01abcdef 1\n"); +} + +#include "cpufunc.h" + +#define PCI_MODE1_ENABLE 0x80000000U +#define PCI_MODE1_ADDRESS_REG 0x0cf8 +#define PCI_MODE1_DATA_REG 0x0cfc + +/* XXX: mode 1 only */ +static int pci_mode = -1; + +static int +pci_mode_detect(void) +{ + uint32_t sav, val; + + if (pci_mode != -1) + return (pci_mode); + + sav = inl(PCI_MODE1_ADDRESS_REG); + + pci_mode = 1; /* assume this for now */ + + outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE); + outb(PCI_MODE1_ADDRESS_REG + 3, 0); + outw(PCI_MODE1_ADDRESS_REG + 2, 0); + val = inl(PCI_MODE1_ADDRESS_REG); + if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) + goto not1; + outl(PCI_MODE1_ADDRESS_REG, 0); + val = inl(PCI_MODE1_ADDRESS_REG); + if ((val & 0x80fffffc) != 0) + goto not1; + return (pci_mode); + + not1: + outl(PCI_MODE1_ADDRESS_REG, sav); + return (pci_mode = 0); +} + +static uint32_t +pci_make_tag(int bus, int device, int function) +{ + uint32_t tag; + + tag = PCI_MODE1_ENABLE; + tag |= bus << 16; + tag |= device << 11; + tag |= function << 8; + + return tag; +} + +void +command_dump_pcicfg(char *arg) +{ + char hex[9]; + char *p = arg; + char *busp, *devp, *funcp; + uint32_t bus, device, function, address; + uint32_t tag, value; + int rv; + + if (pci_mode_detect() != 1) { + printf("pci mode != 1\n"); + return; + } + + /* bus */ + rv = scan(&busp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&bus, busp, strlen(busp)); + if (rv != 0) + goto error; + if (bus < 0 || bus >= 256) + goto error; + + /* device */ + rv = scan(&devp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&device, devp, strlen(devp)); + if (rv != 0) + goto error; + if (device < 0 || device >= 32) + goto error; + + /* function */ + rv = scan(&funcp, NULL, p, false); + if (rv != 0) + goto error; + rv = decode_4(&function, funcp, strlen(funcp)); + if (rv != 0) + goto error; + if (function < 0 || function >= 8) + goto error; + + printf("bus %d, device %d, function %d:", bus, device, function); + for (address = 0; address < 256; address += 4) { + if ((address % 16) == 0) { + hexstr(hex, address); + printf("\n%s:", hex); + } + + tag = pci_make_tag(bus, device, function); + outl(PCI_MODE1_ADDRESS_REG, tag | address); + value = inl(PCI_MODE1_DATA_REG); + outl(PCI_MODE1_ADDRESS_REG, 0); + + hexstr(hex, value); + printf(" %s", hex); + } + printf("\n"); + + return; + + error: + printf("invalid argument: \n"); + printf(" bus: 0-255, device: 0-31, function: 0-7\n"); +} + +void +command_write_pcicfg(char *arg) +{ + char hex[9]; + char *p = arg; + char *busp, *devp, *funcp, *addressp, *valuep; + uint32_t bus, device, function, address; + uint32_t tag, reg, value; + int rv; + + if (pci_mode_detect() != 1) { + printf("pci mode != 1\n"); + return; + } + + /* bus */ + rv = scan(&busp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&bus, busp, strlen(busp)); + if (rv != 0) + goto error; + if (bus < 0 || bus >= 256) + goto error; + + /* device */ + rv = scan(&devp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&device, devp, strlen(devp)); + if (rv != 0) + goto error; + if (device < 0 || device >= 32) + goto error; + + /* function */ + rv = scan(&funcp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&function, funcp, strlen(funcp)); + if (rv != 0) + goto error; + if (function < 0 || function >= 8) + goto error; + + /* address */ + rv = scan(&addressp, &p, p, true); + if (rv != 0) + goto error; + rv = decode_4(&address, addressp, strlen(addressp)); + if (rv != 0) + goto error; + if (address < 0 || address >= 256 || (address & 3) != 0) + goto error; + + /* value */ + rv = scan(&valuep, NULL, p, false); + if (rv != 0) + goto error; + rv = decode_4(&value, valuep, strlen(valuep)); + if (rv != 0) + goto error; + + printf("bus %d, device %d, function %d: ", bus, device, function); + hexstr(hex, address); + printf("%s: ", hex); + + tag = pci_make_tag(bus, device, function); + outl(PCI_MODE1_ADDRESS_REG, tag | address); + reg = inl(PCI_MODE1_DATA_REG); + outl(PCI_MODE1_ADDRESS_REG, 0); + hexstr(hex, reg); + printf("%s -> ", hex); + + outl(PCI_MODE1_ADDRESS_REG, tag | address); + outl(PCI_MODE1_DATA_REG, value); + outl(PCI_MODE1_ADDRESS_REG, 0); + + outl(PCI_MODE1_ADDRESS_REG, tag | address); + reg = inl(PCI_MODE1_DATA_REG); + outl(PCI_MODE1_ADDRESS_REG, 0); + hexstr(hex, reg); + printf("%s\n", hex); + return; + + error: + printf("invalid argument:
\n"); + printf(" bus: 0-255, device: 0-31, function: 0-7, address: 0-255\n"); +} +#endif /* XXX: XXXNONAKA end */