/* * Copyright (C) 2006, Intel Corporation * * This file is part of the Linux-ready Firmware Developer Kit * * This program file is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation;version 2.1 of the License. * * This library 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 Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in a file named COPYING; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "../biostest.h" static void get_config_space(char *device, char *buffer) { char path[PATH_MAX]; char line[4096]; char *lspci_cmd; FILE *file; int first = 1; buffer[0]=0; lspci_cmd = get_relative_command ("lspci", NULL); sprintf(path, "%s -s %s -xxx", lspci_cmd, device); file = popen(path, "r"); if (!file) return; while (!feof(file)) { memset(line, 0, 4096); if (fgets(line, 4095, file)==NULL) break; strcat(buffer, line); if (first) strcat(buffer,"\n"); first = 0; } fclose(file); } static int set_config_space(char *device, int offset, int width, unsigned int value) { char path[PATH_MAX]; char D; D='B'; if (width==16) D='W'; if (width==32) D='L'; sprintf(path, "/sbin/setpci -s %s %x.%c=%x", device, offset, D, value); return system(path); } static void do_pci_poke(char *long_device) { char config_space_buffer[8192]; char device[4096], *c; int myWin; newtComponent myForm; newtComponent myOk; newtComponent resu; newtComponent myAddress, myValue; newtComponent my8Value, my16Value, my32Value; newtComponent write8, write16, write32; const char * address_value, * new_8_value, * new_16_value, * new_32_value; int W,H; newtGetScreenSize(&W,&H); strcpy(device, long_device); c = strchr(device, ' '); if (c) *c = 0; get_config_space(device, config_space_buffer); myWin = newtOpenWindow(1+(W-80)/2,1+(H-22)/2,78,21, "Read/Write PCI Configuration Space"); myForm = newtForm(NULL,NULL,0); myValue = newtTextbox(1,1,53,17, NEWT_FLAG_WRAP); newtFormAddComponent(myForm, myValue); newtTextboxSetText(myValue, config_space_buffer); myOk = newtButton(69,17, "Back"); newtFormAddComponent(myForm, myOk); newtFormAddComponent(myForm, newtLabel(55,3, "Offset")); myAddress = newtEntry(68, 3, "00", 3, &address_value, NEWT_FLAG_RETURNEXIT); newtFormAddComponent(myForm, myAddress); newtFormAddComponent(myForm, newtLabel(55,5, "8 bit")); my8Value = newtEntry(55, 6, "00", 3, &new_8_value, NEWT_FLAG_RETURNEXIT); newtFormAddComponent(myForm, my8Value); write8 = newtButton(65,5,"Write 8 "); newtFormAddComponent(myForm, write8); newtFormAddComponent(myForm, newtLabel(55,9, "16 bit")); my16Value = newtEntry(55, 10, "0000", 5, &new_16_value, NEWT_FLAG_RETURNEXIT); newtFormAddComponent(myForm, my16Value); write16 = newtButton(65,9,"Write 16"); newtFormAddComponent(myForm, write16); newtFormAddComponent(myForm, newtLabel(55,13, "32 bit")); my32Value = newtEntry(55, 14, "00000000", 9, &new_32_value, NEWT_FLAG_RETURNEXIT); newtFormAddComponent(myForm, my32Value); write32 = newtButton(65,13,"Write 32"); newtFormAddComponent(myForm, write32); while (1) { resu = newtRunForm(myForm); if (resu == my8Value) { unsigned int value; unsigned int offset; offset = strtoul(address_value, NULL, 16); value = strtoul(new_8_value, NULL, 16); set_config_space(device, offset, 8, value); get_config_space(device, config_space_buffer); newtTextboxSetText(myValue, config_space_buffer); } else if (resu == my16Value) { unsigned int value; unsigned int offset; offset = strtoul(address_value, NULL, 16); value = strtoul(new_16_value, NULL, 16); set_config_space(device, offset, 16, value); get_config_space(device, config_space_buffer); newtTextboxSetText(myValue, config_space_buffer); } else if (resu == my32Value) { unsigned int value; unsigned int offset; offset = strtoul(address_value, NULL, 16); value = strtoul(new_32_value, NULL, 16); set_config_space(device, offset, 32, value); get_config_space(device, config_space_buffer); newtTextboxSetText(myValue, config_space_buffer); } else break; } newtPopWindow(); } static void pci_hwpoke_call(void) { int win; newtComponent myForm; newtComponent myOkButton; newtComponent myList; newtComponent resu; char *lspci_cmd; FILE *file; int W,H; struct interactive_test *test; newtGetScreenSize(&W,&H); win = newtOpenWindow(1,2,W-3,H-4, "Select PCI device"); myForm = newtForm(NULL, NULL, 0); myList = newtListbox(2,1,H-10, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); newtFormAddComponent(myForm, myList); newtListboxSetWidth(myList, W-6); lspci_cmd = get_relative_command ("lspci", NULL); file = popen(lspci_cmd, "r"); while (!feof(file)) { char buffer[4096]; char *c; memset(buffer, 0, 4096); if (fgets(buffer, 4095, file)==NULL) break; chop_newline(buffer); c = strdup(buffer); newtListboxAppendEntry(myList, c, c); } fclose(file); myOkButton = newtButton(2,H-8, "Back"); newtFormAddComponent(myForm, myOkButton); while (1) { resu = newtRunForm(myForm); if (resu == myList) { test = newtListboxGetCurrent(myList); if (test) do_pci_poke((char *)test); } else break; } newtPopWindow(); } void run_test(void) { register_hw_poke("PCI Configuration Space", pci_hwpoke_call); }