00001 /* checker.c -- Check the memory and return the target board memory layout 00002 Copyright 2000, 2001, 2002 Free Software Foundation, Inc. 00003 Written by Stephane Carrez (stcarrez@nerim.fr) 00004 00005 This file is part of GTAM. 00006 00007 GTAM is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2, or (at your option) 00010 any later version. 00011 00012 GTAM is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with GTAM; see the file COPYING. If not, write to 00019 the Free Software Foundation, 59 Temple Place - Suite 330, 00020 Boston, MA 02111-1307, USA. */ 00021 00091 #include <sys/ports.h> 00092 00093 static void put_addr(unsigned short value); 00094 static void put_char(unsigned char c); 00095 void _start (void); 00096 00097 static inline void 00098 reboot() 00099 { 00100 #ifndef NO_REBOOT 00101 /* The 'func' type is marked as 'noreturn' to optimize the 00102 generated code. */ 00103 typedef void __attribute__ ((noreturn)) (* func)(); 00104 00105 func handler; 00106 00107 set_bus_single_chip (); 00108 00109 /* To reboot, get the reset vector and go to the start of the ROM. */ 00110 handler = *((func*) 0xbffe); 00111 handler (); 00112 #endif 00113 } 00114 00115 void 00116 _start() 00117 { 00118 unsigned char c; 00119 volatile unsigned char* addr; 00120 unsigned char nok = 1; 00121 00122 set_bus_expanded (); 00123 00124 /* Start at end of the RAM. The algorithm is basic and destructive. 00125 We can't apply it to the RAM where this program is mapped. */ 00126 addr = (volatile unsigned char*) 0x0ff; 00127 while (1) 00128 { 00129 addr++; 00130 00131 /* If we reached the end of memory space, flush the SCI by writing 00132 spurious characters and go back to the ROM. If we don't print 00133 some characters, the BREAK generated by the ROM can eat the 00134 last byte. */ 00135 if (addr == (unsigned char*) 0) 00136 { 00137 for (c = 5; --c != 0; ) 00138 put_char ('\n'); 00139 00140 reboot (); 00141 00142 /* Skip the .page0 if reboot() is not supported. 00143 Otherwise, this code is not reached and not generated. */ 00144 addr += 0xff; 00145 continue; 00146 } 00147 00148 /* Skip the IO registers. */ 00149 if (addr == _io_ports) 00150 { 00151 addr += M6811_IO_SIZE; 00152 continue; 00153 } 00154 00155 /* Check the memory by inverting its content. 00156 If this succeeds, we have some kind of RAM. */ 00157 c = ~*addr; 00158 *addr = c; 00159 if (c != *addr) 00160 { 00161 if (nok) 00162 continue; 00163 00164 /* Beginning of non-RAM bank. */ 00165 nok = 1; 00166 put_char ('-'); 00167 put_addr ((unsigned short) addr); 00168 } 00169 else 00170 { 00171 if (nok == 0) 00172 continue; 00173 00174 /* Beginning of RAM bank. */ 00175 nok = 0; 00176 put_char ('+'); 00177 put_addr ((unsigned short) addr); 00178 } 00179 } 00180 } 00181 00182 00183 /* Translate and print the 8-bit value in hexadecimal on the serial line. */ 00184 static void 00185 put_hex(unsigned short value) 00186 { 00187 put_char ("0123456789ABCDEF"[(value >> 4) & 0x0F]); 00188 put_char ("0123456789ABCDEF"[value & 0x0F]); 00189 } 00190 00191 00192 /* Translate and print the address on the serial line. */ 00193 static void 00194 put_addr(unsigned short value) 00195 { 00196 put_hex (value >> 8); 00197 put_hex (value); 00198 put_char ('\n'); 00199 } 00200 00201 00202 /* Write a character on the serial line. */ 00203 static void 00204 put_char(unsigned char c) 00205 { 00206 while (!(_io_ports[M6811_SCSR] & M6811_TDRE)) 00207 continue; 00208 00209 _io_ports[M6811_SCDR] = c; 00210 _io_ports[M6811_SCCR2] |= M6811_TE; 00211 }