2011-12-15 Konrad Eisele <konrad@gaisler.com>
* configure.in: Add SPARC LEON support. * configure: Regenerated. * sparc_leon/asm-leon/amba.h, sparc_leon/asm-leon/asmmacro.h, sparc_leon/asm-leon/clock.h, sparc_leon/asm-leon/contextswitch.h, sparc_leon/asm-leon/elfmacro.h, sparc_leon/asm-leon/head.h, sparc_leon/asm-leon/irq.h, sparc_leon/asm-leon/jiffies.h, sparc_leon/asm-leon/lambapp.h, sparc_leon/asm-leon/lambapp_devs.h, sparc_leon/asm-leon/leon.h, sparc_leon/asm-leon/leon3.h, sparc_leon/asm-leon/leonbare_debug.h, sparc_leon/asm-leon/leonbare_kernel.h, sparc_leon/asm-leon/leonbare_kernel_queue.h, sparc_leon/asm-leon/leoncompat.h, sparc_leon/asm-leon/leondbg.h, sparc_leon/asm-leon/leonstack.h, sparc_leon/asm-leon/liblocks.h, sparc_leon/asm-leon/linkage.h, sparc_leon/asm-leon/param.h, sparc_leon/asm-leon/queue.h, sparc_leon/asm-leon/spinlock.h, sparc_leon/asm-leon/stack.h, sparc_leon/asm-leon/time.h, sparc_leon/asm-leon/timer.h, sparc_leon/asm-leon/types.h, sparc_leon/asm-leon/winmacros.h: New file. * sparc_leon/Makefile.in, sparc_leon/_exit.c, sparc_leon/amba.c, sparc_leon/amba_dbg.c, sparc_leon/amba_driver.c, sparc_leon/amba_scan.c, sparc_leon/asm-leon, sparc_leon/bdinit.S, sparc_leon/busscan.S, sparc_leon/cacheA.S, sparc_leon/catch_interrupt.c, sparc_leon/catch_interrupt_mvt.c, sparc_leon/catch_interrupt_pending.c, sparc_leon/catch_interrupt_svt.c, sparc_leon/configure.in, sparc_leon/console.c, sparc_leon/console_dbg.c, sparc_leon/console_init.c, sparc_leon/contextswitch.c, sparc_leon/contextswitch_asm.S, sparc_leon/crt0.S, sparc_leon/crti.S, sparc_leon/crtn.S, sparc_leon/etrap.S, sparc_leon/etrap_fast.S, sparc_leon/fpu.S, sparc_leon/gettimeofday.c, sparc_leon/initcalls.c, sparc_leon/io.c, sparc_leon/irqinstall.S, sparc_leon/irqtrap.S, sparc_leon/irqtrap_fast.S, sparc_leon/jiffies.c, sparc_leon/kernel.c, sparc_leon/kernel_context.S, sparc_leon/kernel_debug.c, sparc_leon/kernel_debug_var.c, sparc_leon/kernel_mm.c, sparc_leon/kernel_mutex.c, sparc_leon/kernel_queue.c, sparc_leon/kernel_sched.c, sparc_leon/kernel_thread.c, sparc_leon/lcpuinit.S, sparc_leon/locore.S, sparc_leon/locore_atexit.c, sparc_leon/locore_clean.S, sparc_leon/locore_mvt.S, sparc_leon/locore_mvt_reset.S, sparc_leon/locore_svt.S, sparc_leon/locore_svt_reset.S, sparc_leon/locore_svtdisp.S, sparc_leon/locore_var.S, sparc_leon/locore_var_svt.S, sparc_leon/mmu_asm.S, sparc_leon/mutex.c, sparc_leon/nocache.S, sparc_leon/pnpinit.c, sparc_leon/pnpinit_malloc.c, sparc_leon/pnpinit_simple.c, sparc_leon/regwin.S, sparc_leon/regwin_patch.c, sparc_leon/regwin_slow.S, sparc_leon/regwinflush.S, sparc_leon/rtc.c, sparc_leon/rtrap.S, sparc_leon/rtrap_fast.S, sparc_leon/stop.S, sparc_leon/timer.c, sparc_leon/times.c: New file * sparc_leon/configure: Regenerate
This commit is contained in:
354
libgloss/sparc_leon/console_dbg.c
Normal file
354
libgloss/sparc_leon/console_dbg.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Aeroflex Gaisler
|
||||
*
|
||||
* BSD license:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef _HAVE_STDC
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <asm-leon/leoncompat.h>
|
||||
#include <asm-leon/leon.h>
|
||||
|
||||
static size_t
|
||||
lo_strnlen (const char *s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */ ;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
static int
|
||||
lo_vsnprintf (char *buf, size_t size, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
unsigned long long num;
|
||||
int i, j, n;
|
||||
char *str, *end, c;
|
||||
const char *s;
|
||||
int flags;
|
||||
int field_width;
|
||||
int precision;
|
||||
int qualifier;
|
||||
int filler;
|
||||
|
||||
str = buf;
|
||||
end = buf + size - 1;
|
||||
|
||||
if (end < buf - 1)
|
||||
{
|
||||
end = ((void *) -1);
|
||||
size = end - buf + 1;
|
||||
}
|
||||
|
||||
for (; *fmt; ++fmt)
|
||||
{
|
||||
if (*fmt != '%')
|
||||
{
|
||||
if (*fmt == '\n')
|
||||
{
|
||||
if (str <= end)
|
||||
{
|
||||
*str = '\r';
|
||||
}
|
||||
str++;
|
||||
}
|
||||
if (str <= end)
|
||||
*str = *fmt;
|
||||
++str;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
/* get field width */
|
||||
field_width = 0;
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
/* get the conversion qualifier */
|
||||
qualifier = 'l';
|
||||
filler = ' ';
|
||||
|
||||
++fmt;
|
||||
|
||||
if (*fmt == '0')
|
||||
{
|
||||
filler = '0';
|
||||
++fmt;
|
||||
}
|
||||
|
||||
while (isdigit (*fmt))
|
||||
{
|
||||
field_width = field_width * 10 + ((*fmt) - '0');
|
||||
++fmt;
|
||||
}
|
||||
|
||||
/* default base */
|
||||
switch (*fmt)
|
||||
{
|
||||
case 'c':
|
||||
c = (unsigned char) va_arg (args, int);
|
||||
if (str <= end)
|
||||
*str = c;
|
||||
++str;
|
||||
while (--field_width > 0)
|
||||
{
|
||||
if (str <= end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg (args, char *);
|
||||
if (!s)
|
||||
s = "<NULL>";
|
||||
|
||||
len = lo_strnlen (s, precision);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
if (str <= end)
|
||||
*str = *s;
|
||||
++str;
|
||||
++s;
|
||||
}
|
||||
while (len < field_width--)
|
||||
{
|
||||
if (str <= end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
continue;
|
||||
|
||||
|
||||
case '%':
|
||||
if (str <= end)
|
||||
*str = '%';
|
||||
++str;
|
||||
continue;
|
||||
|
||||
case 'x':
|
||||
break;
|
||||
case 'd':
|
||||
break;
|
||||
|
||||
default:
|
||||
if (str <= end)
|
||||
*str = '%';
|
||||
++str;
|
||||
if (*fmt)
|
||||
{
|
||||
if (str <= end)
|
||||
*str = *fmt;
|
||||
++str;
|
||||
}
|
||||
else
|
||||
{
|
||||
--fmt;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
num = va_arg (args, unsigned long);
|
||||
if (*fmt == 'd')
|
||||
{
|
||||
j = 0;
|
||||
while (num && str <= end)
|
||||
{
|
||||
*str = (num % 10) + '0';
|
||||
num = num / 10;
|
||||
++str;
|
||||
j++;
|
||||
}
|
||||
/* flip */
|
||||
for (i = 0; i < (j / 2); i++)
|
||||
{
|
||||
n = str[(-j) + i];
|
||||
str[(-j) + i] = str[-(i + 1)];
|
||||
str[-(i + 1)] = n;
|
||||
}
|
||||
/* shift */
|
||||
if (field_width > j)
|
||||
{
|
||||
i = field_width - j;
|
||||
for (n = 1; n <= j; n++)
|
||||
{
|
||||
if (str + i - n <= end)
|
||||
{
|
||||
str[i - n] = str[-n];
|
||||
}
|
||||
}
|
||||
for (i--; i >= 0; i--)
|
||||
{
|
||||
str[i - j] = filler;
|
||||
}
|
||||
str += field_width - j;
|
||||
j = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0, i = 0; i < 8 && str <= end; i++)
|
||||
{
|
||||
if ((n =
|
||||
((unsigned long) (num & (0xf0000000ul >> (i * 4)))) >>
|
||||
((7 - i) * 4)) || j != 0)
|
||||
{
|
||||
if (n >= 10)
|
||||
n += 'a' - 10;
|
||||
else
|
||||
n += '0';
|
||||
*str = n;
|
||||
++str;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
/* shift */
|
||||
if (field_width > j)
|
||||
{
|
||||
i = field_width - j;
|
||||
for (n = 1; n <= j; n++)
|
||||
{
|
||||
if (str + i - n <= end)
|
||||
{
|
||||
str[i - n] = str[-n];
|
||||
}
|
||||
}
|
||||
for (i--; i >= 0; i--)
|
||||
{
|
||||
str[i - j] = filler;
|
||||
}
|
||||
str += field_width - j;
|
||||
j = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (j == 0 && str <= end)
|
||||
{
|
||||
*str = '0';
|
||||
++str;
|
||||
}
|
||||
}
|
||||
if (str <= end)
|
||||
*str = '\0';
|
||||
else if (size > 0)
|
||||
/* don't write out a null byte if the buf size is zero */
|
||||
*end = '\0';
|
||||
/* the trailing null byte doesn't count towards the total
|
||||
* ++str;
|
||||
*/
|
||||
return str - buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* lo_vsprintf - Format a string and place it in a buffer
|
||||
* @buf: The buffer to place the result into
|
||||
* @fmt: The format string to use
|
||||
* @args: Arguments for the format string
|
||||
*
|
||||
* Call this function if you are already dealing with a va_list.
|
||||
* You probably want lo_sprintf instead.
|
||||
*/
|
||||
static int
|
||||
lo_vsprintf (char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
return lo_vsnprintf (buf, 0xFFFFFFFFUL, fmt, args);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dbgleon_sprintf (char *buf, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int printed_len;
|
||||
|
||||
va_start (args, fmt);
|
||||
printed_len = lo_vsnprintf (buf, size, fmt, args);
|
||||
va_end (args);
|
||||
return printed_len;
|
||||
}
|
||||
|
||||
#define UART_TIMEOUT 100000
|
||||
static LEON23_APBUART_Regs_Map *uart_regs = 0;
|
||||
int
|
||||
dbgleon_printf (const char *fmt, ...)
|
||||
{
|
||||
unsigned int i, loops, ch;
|
||||
amba_apb_device apbdevs[1];
|
||||
va_list args;
|
||||
int printed_len;
|
||||
char printk_buf[1024];
|
||||
char *p = printk_buf;
|
||||
|
||||
/* Emit the output into the temporary buffer */
|
||||
va_start (args, fmt);
|
||||
printed_len = lo_vsnprintf (printk_buf, sizeof (printk_buf), fmt, args);
|
||||
va_end (args);
|
||||
|
||||
//---------------------
|
||||
switch (LEONCOMPAT_VERSION)
|
||||
{
|
||||
case 3:
|
||||
default:
|
||||
{
|
||||
if (!uart_regs)
|
||||
{
|
||||
if (i =
|
||||
leon3_getapbbase (VENDOR_GAISLER, GAISLER_APBUART, apbdevs,
|
||||
1))
|
||||
{
|
||||
uart_regs = (LEON23_APBUART_Regs_Map *) apbdevs[0].start;
|
||||
}
|
||||
}
|
||||
if (uart_regs)
|
||||
{
|
||||
while (printed_len-- != 0)
|
||||
{
|
||||
ch = *p++;
|
||||
if (uart_regs)
|
||||
{
|
||||
loops = 0;
|
||||
while (!(uart_regs->status & LEON_REG_UART_STATUS_THE)
|
||||
&& (loops < UART_TIMEOUT))
|
||||
loops++;
|
||||
uart_regs->data = ch;
|
||||
loops = 0;
|
||||
while (!(uart_regs->status & LEON_REG_UART_STATUS_TSE)
|
||||
&& (loops < UART_TIMEOUT))
|
||||
loops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
//---------------------
|
||||
}
|
Reference in New Issue
Block a user