os/nandboot-R2_0_4/lib/lib.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002 *!
00003 *! FILE NAME  : lib.c
00004 *!
00005 *! DESCRIPTION: Small practical functions for boot loader.
00006 *!              malloc/free
00007 *!              memcpy/memset
00008 *!              writeb/writew/readb/readw
00009 *!              putc/puts/putnybble/putx
00010 *!              error/error2
00011 *!              serial_init
00012 *!
00013 *! ---------------------------------------------------------------------------
00014 *!
00015 *! malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
00016 *! puts by Nick Holloway 1993, better puts by Martin Mares 1995
00017 *! adoptation for Linux/CRIS Axis Communications AB, 1999
00018 *! 
00019 *! Other parts (C) Copyright 2006-2007, Axis Communications AB, LUND, SWEDEN
00020 *!
00021 *! This program is free software; you can redistribute it and/or modify
00022 *! it under the terms of the GNU General Public License as published by
00023 *! the Free Software Foundation; either version 2 of the License, or
00024 *! (at your option) any later version.
00025 *!
00026 *! This program is distributed in the hope that it will be useful,
00027 *! but WITHOUT ANY WARRANTY; without even the implied warranty of
00028 *! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00029 *! GNU General Public License for more details.
00030 *!
00031 *! You should have received a copy of the GNU General Public License
00032 *! along with this program; if not, write to the Free Software
00033 *! Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00034 *!
00035 *!***************************************************************************/
00036 
00037 #include <linux/autoconf.h> /* only for CONFIG_ETRAX_DEBUG_PORT_xxx */
00038 
00039 #include <linux/types.h>
00040 #include <asm/arch/hwregs/reg_rdwr.h>
00041 #include <asm/arch/hwregs/reg_map.h>
00042 #include <asm/arch/hwregs/ser_defs.h>
00043 #include <asm/arch/hwregs/pinmux_defs.h>
00044 
00045 #include "lib.h"
00046 
00047 /* the "heap" is put directly after BSS ends, at _end */
00048   
00049 extern int _end;
00050 static long free_mem_ptr = (long)&_end;
00051  
00052 void *malloc(unsigned int size)
00053 {
00054         void *p;
00055 
00056         free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
00057 
00058         p = (void *)free_mem_ptr;
00059         free_mem_ptr += size;
00060 
00061         return p;
00062 }
00063 
00064 void free(void *where)
00065 {       /* Don't care */
00066 }
00067 
00068 /* I/O */
00069 
00070 unsigned char readb(const volatile void *addr)
00071 {
00072         return *(volatile unsigned char *) addr;
00073 }
00074 
00075 unsigned short readw(const volatile void *addr)
00076 {
00077         return *(volatile unsigned short *) addr;
00078 }
00079 
00080 void writeb(unsigned char b, volatile void *addr)
00081 {
00082         *(volatile unsigned char *) addr = b;
00083 
00084 #if GPIO_SYNC
00085         /* Bus sync: Read from address we just wrote.
00086          * This generates no signal to the NAND flash, since only chip 
00087          * select lines are pulled out to the chip, and read is not 
00088          * gated with chip select for the write  area.
00089          * This should not be necessary with correct wait states, but
00090          * may be necessary (but the wrong way to do it) if too short wait
00091          * states have been set up, or (correctly) if way too long wait states 
00092          * have been set up.
00093          */
00094         (void) readb(addr);
00095 #endif
00096 }
00097 
00098 void writew(unsigned short b, volatile void *addr)
00099 {
00100         *(volatile unsigned short *) addr = b;
00101 }
00102 
00103 /* info and error messages to serial console */
00104 
00105 #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
00106 static inline void
00107 serout(const char c, reg_scope_instances regi_ser)
00108 {
00109         reg_ser_rs_stat_din rs;
00110         reg_ser_rw_dout dout = {.data = c};
00111 
00112         do {
00113                 rs = REG_RD(ser, regi_ser, rs_stat_din);
00114         }
00115         while (!rs.tr_rdy);/* Wait for tranceiver. */
00116         
00117         REG_WR(ser, regi_ser, rw_dout, dout);
00118 }
00119 
00120 #endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
00121 
00122 void
00123 putc(const char c)
00124 {
00125 #ifdef CONFIG_ETRAX_DEBUG_PORT0
00126         serout(c, regi_ser0);
00127 #endif
00128 #ifdef CONFIG_ETRAX_DEBUG_PORT1
00129         serout(c, regi_ser1);
00130 #endif
00131 #ifdef CONFIG_ETRAX_DEBUG_PORT2
00132         serout(c, regi_ser2);
00133 #endif
00134 #ifdef CONFIG_ETRAX_DEBUG_PORT3
00135         serout(c, regi_ser3);
00136 #endif
00137 }
00138 
00139 
00140 void
00141 puts(const char *s)
00142 {
00143         while (*s)
00144                 putc(*s++);
00145 }
00146 
00147 void
00148 putnybble(unsigned int n)
00149 {
00150         putc("0123456789abcdef"[n & 15]);
00151 }
00152 
00153 void
00154 putx(unsigned int x)
00155 {
00156         int i;
00157 
00158         puts("0x");
00159         for (i = 7; i >= 0; i--)
00160                 putnybble(x >> 4*i);
00161 }
00162 
00163 void
00164 putnl(void)
00165 {
00166         puts("\r\n");
00167 }
00168 
00169 void*
00170 memset(void* s, int c, size_t n)
00171 {
00172         int i;
00173         char *ss = (char*)s;
00174 
00175         for (i=0;i<n;i++) ss[i] = c;
00176         return s;
00177 }
00178 
00179 void*
00180 memcpy(void* __dest, __const void* __src,
00181                             size_t __n)
00182 {
00183         int i;
00184         char *d = (char *)__dest, *s = (char *)__src;
00185 
00186         for (i=0;i<__n;i++) d[i] = s[i];
00187         return __dest;
00188 }
00189 
00190 void
00191 error(const char *x)
00192 {
00193         puts("\r\n\n");
00194         puts(x);
00195         puts("\r\n\n -- System halted\n");
00196 
00197         while(1);       /* Halt */
00198 }
00199 
00200 void
00201 error2(const char *x, int y, const char *z)
00202 {
00203         puts("\r\n\n");
00204         puts(x);
00205         putc(':');
00206         putx(y);
00207         putc(':');
00208         puts(z);
00209         puts("\r\n\n -- System halted\n");
00210 
00211         while(1);       /* Halt */
00212 }
00213 
00214 static inline void
00215 serial_setup(reg_scope_instances regi_ser)
00216 {
00217 #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
00218         reg_ser_rw_xoff xoff;
00219         reg_ser_rw_tr_ctrl tr_ctrl;
00220         reg_ser_rw_rec_ctrl rec_ctrl;
00221         reg_ser_rw_tr_baud_div tr_baud;
00222         reg_ser_rw_rec_baud_div rec_baud;
00223         
00224         /* Turn off XOFF. */
00225         xoff = REG_RD(ser, regi_ser, rw_xoff);
00226         
00227         xoff.chr = 0;
00228         xoff.automatic = regk_ser_no;
00229         
00230         REG_WR(ser, regi_ser, rw_xoff, xoff);
00231 
00232         /* Set baudrate and stopbits. */
00233         tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
00234         rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
00235         tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
00236         rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
00237         
00238         tr_ctrl.stop_bits = 1;  /* 2 stop bits. */
00239         tr_ctrl.en = 1; /* enable transmitter */
00240         rec_ctrl.en = 1; /* enabler receiver */
00241         
00242         /* 
00243          * The baudrate setup used to be a bit fishy, but now transmitter and
00244          * receiver are both set to the intended baud rate, 115200.
00245          * The magic value is 29.493 MHz.
00246          */
00247         tr_ctrl.base_freq = regk_ser_f29_493;
00248         rec_ctrl.base_freq = regk_ser_f29_493;
00249         tr_baud.div = (29493000 / 8) / 115200;
00250         rec_baud.div = (29493000 / 8) / 115200;
00251         
00252         REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
00253         REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
00254         REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
00255         REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
00256 #endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
00257 }
00258 
00259 void
00260 serial_init(void)
00261 {
00262 #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
00263         reg_pinmux_rw_hwprot hwprot;
00264         
00265         hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
00266 #ifdef CONFIG_ETRAX_DEBUG_PORT0
00267         serial_setup(regi_ser0);
00268 #endif
00269 #ifdef CONFIG_ETRAX_DEBUG_PORT1
00270         hwprot.ser1 = regk_pinmux_yes;
00271         serial_setup(regi_ser1);
00272 #endif
00273 #ifdef CONFIG_ETRAX_DEBUG_PORT2
00274         hwprot.ser2 = regk_pinmux_yes;
00275         serial_setup(regi_ser2);
00276 #endif
00277 #ifdef CONFIG_ETRAX_DEBUG_PORT3
00278         hwprot.ser3 = regk_pinmux_yes;
00279         serial_setup(regi_ser3);
00280 #endif
00281         REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
00282 #endif /* CONFIG_ETRAX_DEBUG_PORT_NULL */
00283 }

Generated on Fri Nov 28 00:06:24 2008 for elphel by  doxygen 1.5.1