----- Original Message ----- From: "Carl-Daniel Hailfinger" <[EMAIL PROTECTED]>
To: "todthgie" <[EMAIL PROTECTED]>
Cc: "LinuxBIOS Mailing List" <linuxbios@linuxbios.org>
Sent: Friday, August 31, 2007 23:55
Subject: Re: [LinuxBIOS] LinuxBIOS panic room


Hi,

On 30.08.2007 21:59, todthgie wrote:
for some time now i have a bootloader in my howbrew rom emulator that can
read / write to memory in on a byte basis and on a block basis using iHex
for the block ones
i have adapted it it to run on the pc in porting LB to right now. it can
erase flash sectors or the whole chip.

Nice. Can you send a patch/tarball?

i will make a website for the romemulator.
the lb version is to big a hacke to pubish atm and im having stabilty problems with it... if you are realy interested panic.c is attached if i figure out how to make a V3 target for my board and how to enable CAR on a IBM/Cyrix 6X86MX i will port it to V3.


im thinking about extending it with IO read/write and pci read/write for the
larger version ( i only have 8Kbyte atm and that is thight for romcc
compiled code:-( )

So you use romcc?
yes and im having LOADS of trouble


i use single letters in the range G-Z for commands and ignore 0-9 and A-F
that way if a hex download is aborted it just ignores the rest of the input

a nice addition would be to emit the welcome message over and over again
with some delay in between (so the reciever is not stressed to much) until
the first command

Yeah, a delay between messages in wait mode would be nice.

Regards,
Carl-Daniel


/*
* This file is part of the LinuxBIOS project.
*
* Copyright (C) 2007 Reinder E.N. de Haan nospam-at-mveas-dot-com>
*
* 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 <avr/io.h>
//#include <avr/pgmspace.h>
//#include <avr/interrupt.h>

//void hw_init(void);


/*
unsigned char uart_rx_1byte(void)
{
        unsigned tmp;
        __asm__ __volatile__(
                "  \nuart_dorx_1byte_wait: \n"
                "  mov  $1021 , %%dx\n"
                "  inb %%dx, %%al\n"
                "  test $1, %%al\n"
                "  jz uart_dorx_1byte_wait\n"
                "  mov  $1016 , %%dx\n"
                "  inb %%dx, %%al\n" : "=a" (tmp): : "esp", "edx");
        return(tmp);
}
*/

void delay_ms(unsigned short ms)
{
        //unsigned short delay;
        while(ms)
        {
        //      for(delay=0x780;delay;)
        //      {
        //              asm("nop");
        //              delay--;
        //      }
                ms--;
        }
}
//void delay_us(unsigned short us)
//{
//      unsigned short delay;
//      while(us)
//      {
//              for(delay=2;delay;)
//              {
//                      //asm("nop");
//                      delay--;
//              }
//              us--;
//      }
//}



unsigned char uart_do_rx_byte(void)
{
        unsigned char tmp;
// al = tmp     
// dx = port
        __asm__ __volatile__(
                "  movl $uart_dorx_byte_ret,%%esi;\n"
                "uart_dorx_byte: \n"
                "  mov  %%dx , %%ax\n"
                "  shl $10, %%eax\n"
                "uart_dorx_byte_wait: \n"
                "  mov  $1021 , %%dx\n"
                "  inb %%dx, %%al\n"
                "  test $1,%%al\n"
                "  jz uart_dorx_byte_wait\n"
                "  mov  $1016 , %%dx\n"
                "  inb %%dx, %%al\n"
                "  mov %%ax,%%dx\n"
                "  shr $10, %%eax\n"
                "  xchg %%ax,%%dx\n"
                "  jmp %%cs:(%%esi)\n"
                "uart_dorx_byte_ret: .long +4\n"
                : "=a" (tmp): : "esi");
                //print_emerg_hex8(tmp);
                return(tmp);
}
unsigned char uart_rx_byte(void)
{
        unsigned char tmp;
        asm("      movl $.+0xa,%%esi;\n"
                "  jmp uart_dorx_byte\n"
                "  .long   .+4\n"
                : "=a" (tmp): : "esi");
        return(tmp);
}
unsigned char uart_do_rx_2hex(void)
{
        unsigned short tmp;
//      unsigned long retesp;
//      __asm__ __volatile__("\nuart_dorx_2hex: \n" :"=S" (retesp)::);
// al = tmp     
// dx = port
// ebx = ret
// ecx = digits
        __asm__ __volatile__(
                "  movl $uart_dorx_2hex_ret,%%esi;\n"
                "uart_dorx_2hex: \n"
                "  mov  $2 , %%ecx\n"
                "  mov  $0 , %%ebx\n"
                "uart_dorx_hex:\n"
                "  mov  %%dx , %%ax\n"
                "  shl $10, %%eax\n"
                " dorx_hex_wait:\n"
                "  mov  $1021 , %%dx\n"
                "  inb %%dx, %%al\n"
                "  test $1,%%al\n"
                "  jz dorx_hex_wait\n"
                "  mov  $1016 , %%dx\n"
                "  inb %%dx, %%al\n"
                "  cmp  $48 , %%al\n"         //<'0'
                "  jl dorx_hex_wait\n"
                "  cmp  $102 , %%al\n"                //>'f'
                "  jg dorx_hex_wait\n"
                "  cmp  $57 , %%al\n"         //<='9'      OK
                "  jng dorxh_09\n"
                "  cmp  $65 , %%al\n"         //<'A'
                "  jl dorx_hex_wait\n"
                "  cmp  $70 , %%al\n"         //<='F'      OK
                "  jng dorxh_af\n"
                "  cmp  $97 , %%al\n"         //<'a'
                "  jl dorx_hex_wait\n"
                "dorxh_af:\n"
                "  add  $9 , %%al\n"
                "dorxh_09:\n"
                "  and  $15 , %%al\n"
                "  shl  $4 , %%ebx\n"
                "  or %%al, %%bl\n"
                "  loop dorx_hex_wait\n"
                "  shr $10, %%eax\n"
                "  mov  %%ax,%%dx\n"
                "  movl %%ebx, %%eax\n"
                "  jmp %%cs:(%%esi)\n"
                "uart_dorx_2hex_ret: .long +4\n"
                : "=a" (tmp): : "esi","ebx","ecx");
                //print_emerg_hex8(tmp);
                return(tmp);
}

unsigned char uart_rx_2hex(void)
{
        unsigned char tmp;
        asm("      movl $.+0xa,%%esi;\n"
                "  jmp uart_dorx_2hex\n"
                "  .long   .+4\n"
                : "=a" (tmp): : "esi","ebx","ecx");
        return(tmp);
}
unsigned short uart_rx_4hex(void)
{
        unsigned short tmp;
        asm("      mov  $4 , %%ecx\n"
                "  mov  $0 , %%ebx\n"
                "  movl $.+0xa,%%esi;\n"
                "  jmp uart_dorx_hex\n"
                "  .long   .+4\n"
                : "=a" (tmp): : "esi","ebx","ecx");
        return(tmp);
}
unsigned long uart_rx_8hex(void)
{
        unsigned long tmp;
        asm("      mov  $8 , %%ecx\n"
                "  mov  $0 , %%ebx\n"
                "  movl $.+0xa,%%esi;\n"
                "  jmp uart_dorx_hex\n"
                "  .long   .+4\n"
                : "=a" (tmp): : "esi","ebx","ecx");
        return(tmp);
}

unsigned char read(unsigned long address)
{
        return(*((unsigned char *) address));
}
void mem_write(unsigned long address,unsigned char value)
{
        __asm__ __volatile__(
                        "  movb %%al,(%%edi)\n"
                        : : "D" (address), "a" (value));
}

unsigned int flash_write(unsigned long address,unsigned char value)
{
        unsigned short tmp;
        unsigned short timeout;
//      if(address > 0xF0000)
//      {
//              print_emerg("Error Prohibited address !!!! \r");
//              return;
//      }
//      timeout=0xFF;
        __asm__ __volatile__(
                "movb $0x2e,(0xD5000)\n"
                "movb $0xF0,(0xE0000)\n"
                "movb $0xAA,(0xE0555)\n"
                "movb $0x55,(0xE02AA)\n"
                "movb $0xA0,(0xE0555)\n"
                "movb %%al,(%%esi)\n"
                "nop\nnop\nnop\nnop\n"
//              "movl %%ecx,%%eax\n"
//              "movl $0xF,%%ecx\n"
//              "loop .\n"
//              "movl %%eax,%%ecx\n"
                "movb (%%esi),%%al\n"
                "movb (%%esi),%%ah\n"
                :"=a"(tmp) :"a"(value),"S"(address));
//      mem_write((address & ~0x7FFF)|0x0555,0xAA);
//      mem_write((address & ~0x7FFF)|0x02AA,0x55);
//      mem_write((address & ~0x7FFF)|0x0555,0xA0);
//      mem_write( address,value);
//      __asm__ __volatile__(
//              "movl $0xF,%%ecx\nloop .\n"
//              "movb (0xE0000),%%al\n"
//              "movb (0xE0000),%%ah\n"
//              :"=a"(tmp) : :"ecx");
        timeout=0xff;
        while((((tmp & 0xFF) != ((tmp >>8) & 0xFF)) || ((tmp & 0xFF) != value)) 
&& (--timeout != 0))
        {
                //tmp = timeout; tmp--; timeout=tmp;
//              timeout--;
                //print_emerg_char('.');
                __asm__ __volatile__(
                "nop\nnop\nnop\nnop\n"
                "movb (%%esi),%%al\n"
                "movb (%%esi),%%ah\n"
                :"=a"(tmp):"S"(address));
        }
        __asm__ __volatile__("movb $0x2c,(0xD5000)\n");
        __asm__ __volatile__("movb $0xF0,(0xE0000)\n");
        if(timeout)
        {
        //      print_emerg_char('-');
                return 0;
        }else{
                //print_emerg_char('-');
                __asm__ __volatile__("movb $0x2d,(0xD5000)\n");
                print_emerg_hex32(address);
                print_emerg(":FPE\r");
                return 1;
        }
}
void erase(unsigned long address)
{
        unsigned char tmp1,tmp2;
        unsigned short tmp,timeout=0x1000;
        print_emerg_char('[');
//      __asm__ __volatile__("movb $0x5e,(0xD5000)\n");
//      mem_write((address & ~0x7FFF)|0x0555,0xF0);//       mem_write((address 
& ~0x7FFF)|0x0555,0xAA);
//      mem_write((address & ~0x7FFF)|0x02AA,0x55);//       mem_write((address 
& ~0x7FFF)|0x0555,0x80);
//      mem_write((address & ~0x7FFF)|0x0555,0xAA);//       mem_write((address 
& ~0x7FFF)|0x02AA,0x55);
//      mem_write((address ),0x30);
        __asm__ __volatile__(
                "movb $0x5D,(0xD5000)\n"
                "movb $0xF0,(0xE0000)\n"
                "movb $0xAA,(0xE0555)\n"
                "movb $0x55,(0xE02AA)\n"
                "movb $0x80,(0xE0555)\n"
                "movb $0xAA,(0xE0555)\n"
                "movb $0x55,(0xE02AA)\n"
                "movb $0x30,(0xE0000)\n"
                "movl $0xFFFF,%%ecx\n"
                "loop .\n"
                "movb $0xA5,(0xD5000)\n"
                "movb (0xE0000),%%al\n"
                "movb (0xE0000),%%ah\n"
                :"=a"(tmp) : :"ecx");
        tmp1 = (tmp>>8) & 0xff;               // *((unsigned char *) address);
        tmp2 = tmp & 0xFF; //*((unsigned char *) address);
        while(((tmp1 != tmp2) || (tmp1 !=0xff)) && (timeout))
        {
        __asm__ __volatile__(
                "movb (0xE0000),%%al\n"
                "movb (0xE0000),%%ah\n"
                :"=a"(tmp));
                tmp1 = tmp>>8;            // *((unsigned char *) address);
                tmp2 = tmp & 0xFF; //*((unsigned char *) address);
                timeout--;
                if(timeout==0)
                {
                        __asm__ __volatile__("movb $0x5B,(0xD5000)\n");
                        __asm__ __volatile__("movb $0xF0,(0xE0000)\n");
                        //print_emerg_hex32(address);
                        print_emerg(":EE\r");
//                      return;
                }
        }
        __asm__ __volatile__("movb $0x57,(0xD5000)\n");
        __asm__ __volatile__("movb $0xF0,(0xE0000)\n"
                "movl $0xF,%%ecx\n"
                "loop .\n"
                        : : :"ecx");
//      print_emerg_char('}');
        print_emerg_char(']');
        return; 
}
unsigned char download(unsigned char mode)
{
        unsigned char len;
        unsigned char cmd;
        unsigned long offset=0;
        unsigned long haddress=0;
        unsigned long addr=0;
        unsigned char tmp;
        unsigned char tmp2;
        print_emerg("\rHex\r");
        while(1)
        {
//              print_emerg_hex32(haddress);
                tmp='\r';//uart_rx_1byte();
                print_emerg_char('<');
                while((tmp & 0xFF) !=':')
                        {
                                if((tmp & 0xFF) !='\r')
                                        print_emerg_char(tmp);
                                tmp=uart_rx_byte();
                        }
                print_emerg_char(';');
                len=uart_rx_2hex();
                offset=uart_rx_4hex();
        //      offset=uart_rx_2hex()<<8;
        //      offset|=uart_rx_2hex();
                cmd=uart_rx_2hex();
        //      print_emerg_hex32(haddress);
//              print_emerg_hex8(len);
//              print_emerg_hex16(offset);
//              print_emerg_hex8(cmd);
                        
                if((len == 0) && (cmd==0x01))
                {
                        if (mode==0)
                                print_emerg("DlOk\r");
                        else
                                print_emerg("V.Ok\r");
                        return(0);
                }else if(cmd==0)
                {
                        while(len)
                        {
                                addr=haddress+offset;
                                //print_emerg_char('.');
//                              print_emerg_hex32(addr);
//                              print_emerg_hex8(len);
                                tmp=uart_rx_2hex();
                                if(mode==0)
                                {
                                        if(flash_write(addr, tmp)!=0);
                                        {
//                                              print_emerg("FWF");
                                                //return(1);
//                                              goto fwf;
                                        }
                                }
                                tmp2=read(addr);
//                              delay_ms(100);
                                if( (tmp2 != tmp) ||
                                        (tmp2 !=read(addr)) ||
                                        (tmp  !=read(addr)))
                                {
                                        print_emerg("PE@");
//fwf:
                                        print_emerg_hex32(addr);
                                        print_emerg_hex8(tmp);
//                                      print_emerg_char('=');
//                                      print_emerg_hex8(tmp2);
                                        print_emerg_hex8(read(addr));
//                                      print_emerg_char('!');
//                                      print_emerg_char('=');
                                        print_emerg_char('\r');
                                        return(1);
                                }
                                offset++;
//                              if (offset==0)
//                              {
//                                      haddress += 0x10000;
//                              }
                                addr=haddress+offset;
                                len--;
                        }
#if 1
                }else if((cmd==4) && (len ==2))
                {
                        haddress=uart_rx_4hex();
                        haddress <<=16;
                        addr=haddress+offset;
//                      print_emerg_hex32(haddress);
                        print_emerg_char('+');
#endif
                }else
                {
                        print_emerg("E inv rec\r"); // cmd==0x");
                        return(1);
//                      print_emerg_hex8(cmd);
                }
//                      uart_rx_2hex();
                print_emerg_char('!');
//              print_emerg_hex32(haddress);
        
        }
}

#if 0
//const char LF[] = "\r";
const char version[] = \
        "LinuxBios panicroom bootloader\r";
const char usage_txt[]  =       \
        "I: Init\r"                                           \
        "H: Help\r"                                           \
        "R: Read: R AAAA\r"                           \
        "U: Read Block: B AAAA LLLL\r"        \
        "W: Write: W AAAA VVVV\r"             \
        "P: Download Hex file\r"              \
        "V: verify\r"                                 \
//      "E: Erase sector\r"                           
        "X: Erase flash\r";
//      "T: Take Bus\r"
//      "G: Give Bus\r"
#endif

void panic (void)
{
        register unsigned char tmp=0;
        register unsigned char cmd=0;
        register unsigned long addr;
        
//      print_emerg(version);
//      print_emerg(usage_txt);
        __asm__ __volatile__("movb $0xFF,(0xD5000)\n");

        while(1)
        {
                print_emerg_char('>');
                tmp=uart_rx_byte();
                cmd=tmp & 0x0DF;
//              print_emerg_hex8(cmd);
                switch(cmd)
                {
//                      case 'I':
//                              __vectors(); //reset
//                              break;
                        case 'H':
                                //print_emerg(usage_txt);
                                print_emerg("hi");
                                break;
                        case 'I':
                                __asm__ __volatile__(
                                        "movb $0xF0,(0xF0000)\n"
                                        "movb $0xAA,(0xF0555)\n"
                                        "movb $0x55,(0xF02AA)\n"
                                        "movb $0x90,(0xF0555)\n"
                                        "movb (0xF0000),%%al\n"
                                        "movb $0xF0,(0xF0000)\n"
                                        :"=a"(tmp));
                                print_emerg_hex8(tmp);
                                __asm__ __volatile__(
                                        "movb $0xF0,(0xF0000)\n"
                                        "movb $0xAA,(0xF0555)\n"
                                        "movb $0x55,(0xF02AA)\n"
                                        "movb $0x90,(0xF0555)\n"
                                        "movb (0xF0001),%%al\n"
                                        "movb $0xF0,(0xF0000)\n"
                                        :"=a"(tmp));
                                print_emerg_hex8(tmp);
                                break;
                        case 'T':
//                              tmp=uart_rx_2hex();
//                              __asm__ __volatile__(
//                                      "  movb %%al,(0xD5000)\n"
//                              : : "a" (tmp):);
                                break;
                        case 'R':
                                addr=uart_rx_8hex();
//                              print_emerg_hex32(addr);
                                print_emerg_hex8(read(addr));
                                break;
//                      case 'Y':
//                              for(tmp=0;tmp<0xff;tmp++)
//                              {
//                                      if((tmp & 0xf)==0)
//                                      {
//                                              print_emerg_char('\r');
//                                              print_emerg_hex8(tmp);
//                                              print_emerg_char(':');
//                                      }
//                                      print_emerg_char(' ');
//                                      print_emerg_hex8(read(tmp));
//
//                              }
//                              break;
                        case 'Q':
                                addr=uart_rx_8hex();
                                flash_write(addr,uart_rx_2hex());
                                //print_emerg_hex8(read(addr));
                                break;
                        case 'W':
                                addr=uart_rx_8hex();
                                mem_write(addr,uart_rx_2hex());
                                print_emerg_hex8(read(addr));
                                break;
                        case 'P':
                        case 'V':
                                //print_emerg("P/V");
                                //download(0);
#define FBS 0
#if !FBS
                                tmp=((cmd & 0x0DF)=='V')?1:0;
                                print_emerg_char('A'+tmp);
                                download(tmp);
#endif
                                break;
//                              download(1);
//                              break;
                        case 'X':
//                              erase(0x80000);
//                              erase(0x90000);
//                              erase(0xA0000);
//                              erase(0xB0000);
//                              erase(0xC0000);
//                              erase(0xD0000);
                                erase(0xE0000);
//                              erase(0xF0000);
                                break;
                        case 'Z':
#if FBS
                                __asm__ __volatile__(
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0x80,(0xF0555)\n"
                                "movb $0xAA,(0xF0555)\n    movb $0x55,(0xF02AA)\n  
movb $0x30,(0xF0000)\n  movl $0x7FFFF,%%ecx\n   loop .\n"
                
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0xea,(0xFFFFFFF0)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                        
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0x00,(0xFFFFFFF1)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                        
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0x00,(0xFFFFFFF2)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                        
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0x00,(0xFFFFFFF3)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                        
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0xD4,(0xFFFFFFF4)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                        
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0x00,(0xFFFFFFF5)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                                
                                "movb $0xF0,(0xF0000)\n    movb $0xAA,(0xF0555)\n  
movb $0x55,(0xF02AA)\n  movb $0xA0,(0xF0555)\n"
                                "movb $0x00,(0xFFFFFFF6)\n movl $0xFFF,%%ecx\n       
      loop .\n"
                                : : :"ecx");
                                print_emerg("boot jump done");
#endif
                                break;
                        case 'q':
                                tmp=uart_do_rx_byte();
                                tmp=uart_do_rx_2hex();                  // use 
this one only once
                                break;
//                      case 'T':
//                      case 'G':
//                              break;
                        default:
//                              print_emerg_hex8(cmd);
//                              print_emerg_char('?');
                                print_emerg_char(cmd & 0xdf);
                                break;
                }
        }
        return;
}
-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to