Hello, last week a had time to run devbios on my sis735 based motherboard but there are some questions/problems:
In sis_activate it seems that address 0x51 of the virtual kernel address space is accessed.
// sis_activate(): .. pci_dummy[1]=readb(0x51); .. writeb(pci_dummy[1] & 0x7f, 0x51); ..
// sis deactivate(): .. writeb(pci_dummy[1], 0x51); ..
This leads to an segmantation fault in my case. Can someone explain me what this code should do? The comment says: /* disable cache */
static void sis_activate(void) { char b; hostbridge = pci_find_class(PCI_CLASS_BRIDGE_HOST<<8,NULL); if (!hostbridge) return;
pci_dummy[0]=pci_read(hostbridge, 0x76); --> pci_dummy[1]=readb(0x51); pci_dummy[2]=pci_read(CURRENT, 0x40); pci_dummy[3]=pci_read(CURRENT, 0x45);
/* disable shadow */ pci_write(hostbridge, 0x76, 0x00); /* disable cache */ --> writeb(pci_dummy[1] & 0x7f, 0x51);
/* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */ pci_write(CURRENT, 0x40, pci_dummy[2]|0x0b); /* Flash write enable on SiS 540/630 */ pci_write(CURRENT, 0x45, pci_dummy[3]|0x40);
/* The same thing on SiS 950 SuperIO side */ outb(0x87, 0x2e); outb(0x01, 0x2e); outb(0x55, 0x2e); outb(0x55, 0x2e); if (inb(0x2f) != 0x87) { /* printf("Can not access SiS 950\n"); */ return; }
outb(0x24, 0x2e); b = inb(0x2f) | 0xfc; outb(0x24, 0x2e); outb(b, 0x2f); outb(0x02, 0x2e); outb(0x02, 0x2f); }
The next thing I noticed is that the ATMEL29C010A doesn't like the flash_program_atmel() code. When I use the flash_program -code everything is fine.
void flash_program (void) { flash_command(0xa0); }
void flash_program_atmel (void) { flash_command(0x80); flash_command(0x20); }
The AT29C010A data sheet says that: the code in flash_program() is used: 1. to activate data protection 2. ac "program"-command when data protection is activated
the flash_program_atmel() code does switch of the data protection.
I dont know why the flash_program_atmel() code doesn't work for me since it agrees with the data sheet.
Then there is another problem. (Since the ?? cache disable code ?? (see above) was commented out I switched off all cache options in BIOS setup: BIOS ROM cachable, L1 + L2 Cache of processor.)
When loading the devbios module the flashrom is detected correct and I can read it with dd if=/dev/bios | hex|less. I also can write to the flash with dd if=/dev/zero of=/dev/bios bs=128 count=1. After this write access the flashrom can be read with dd to verify that the data is written properly. The problem is that after the write access no more flash commands can be executed. That means that every other write to the bios does fail and when I rmmod bios insmod bios.o then the kernel module doesn't detect the flashrom until next reboot (the identification command does not work).
I tried this with the EON29F002NT-flashrom which belongs to the board, but did not write on that, and the ATMEL. Since both flashroms are not detected this cannot be a flashrom problem.
I modified bios_write-function to use flash_ready_toggle() instead of flash_ready_poll() and printk timeout variable (the number of toggles+1) to see if the flash accepted my write commands.
After rebooting an loading the bios.o module I did a dd if=/dev/zero of=/dev/bios bs=1024 count=1
for the first 128k sector flash_ready_toggle reported timeout=ca. 4000 for all other sectors flash_ready_toggle reported timeout=1 (0 toggles). This means that the first sector write succeeds, but all following fail. I don't understand this becaus in the programming loop of bios_write no strange things are done:
while (size>0) { // atmel-specific code commented out - reasons described above: //if ((flashchips[fn].flags & f_manuf_compl) != f_atmel_compl) { flash_program(); //} else { // flash_program_atmel(); //} for (i=0;i<flashchips[fn].pagesize;i++) { flash_writeb(offset+writeoffs+i,clipboard[writeoffs+i]); } if ((flashchips[fn].flags & f_manuf_compl) == f_atmel_compl) { udelay(750); } else { if (flashchips[fn].pagesize==1) udelay(30); else udelay(300); }
if (flash_ready_poll(offset+writeoffs+flashchips[fn].pagesize-1, clipboard[writeoffs+flashchips[fn].pagesize-1])) { printk (KERN_ERR "BIOS: Error occured, please repeat write operation.\n"); } flash_command(0xf0);
writeoffs += flashchips[fn].pagesize; size -= flashchips[fn].pagesize; }
I hope that someone can help me to fix the problems.
Regards, Peter Kögel
- To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message http://www.freiburg.linux.de/OpenBIOS/ - free your system..
On Fri, 20 Dec 2002, Peter Kögel wrote:
In sis_activate it seems that address 0x51 of the virtual kernel address space is accessed.
no, this is an i/o address.
I'm a bit lost; are you running this code as a user or in the kernel or ...
if as user, you have to be root, and there ought to be an iopl() call somewhere in the code, else you will get SEGV.
ron
- To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message http://www.freiburg.linux.de/OpenBIOS/ - free your system..
* Ronald G. Minnich rminnich@lanl.gov [021220 16:02]:
no, this is an i/o address.
I'm a bit lost; are you running this code as a user or in the kernel or ...
if as user, you have to be root, and there ought to be an iopl() call somewhere in the code, else you will get SEGV.
It's kernel code, the /dev/bios driver available in OpenBIOS cvs.
Stefan
* Peter Kögel peter.koegel@web.de [021220 11:40]:
In sis_activate it seems that address 0x51 of the virtual kernel address space is accessed.
pci_dummy[1]=readb(0x51); .. writeb(pci_dummy[1] & 0x7f, 0x51); ..
// sis deactivate(): .. writeb(pci_dummy[1], 0x51); ..
This leads to an segmantation fault in my case. Can someone explain me what this code should do? The comment says: /* disable cache */
It should probably either read from the physical address or rather do an inb/outb. I don't have the specs available and I cannot recall exactly where this code comes from.
The next thing I noticed is that the ATMEL29C010A doesn't like the flash_program_atmel() code. When I use the flash_program -code everything is fine.
void flash_program (void) { flash_command(0xa0); }
void flash_program_atmel (void) { flash_command(0x80); flash_command(0x20); }
The AT29C010A data sheet says that: the code in flash_program() is used: 1. to activate data protection 2. ac "program"-command when data protection is activated
the flash_program_atmel() code does switch of the data protection.
I dont know why the flash_program_atmel() code doesn't work for me since it agrees with the data sheet.
The problem is that after the write access no more flash commands can be executed. That means that every other write to the bios does fail and when I rmmod bios insmod bios.o then the kernel module doesn't detect the flashrom until next reboot (the identification command does not work).
so we probably have to reset to data protection after every write by calling command 0xa0?
I tried this with the EON29F002NT-flashrom which belongs to the board, but did not write on that, and the ATMEL.
have you tried CVS or 0.3.2? CVS should support some EON chips. What does /proc/bios say?
Best regards, Stefan