mirror of https://github.com/l4ka/pistachio.git
More ebony stuff; added a working UART console to -lio, used e.g. by
kickstart
This commit is contained in:
parent
45cb8292de
commit
0da678c21f
|
@ -34,41 +34,8 @@
|
|||
#include <config.h>
|
||||
|
||||
#if defined(CONFIG_COMPORT)
|
||||
|
||||
#include "powerpc-io.h"
|
||||
|
||||
static int of1275_strcmp( const char *s1, const char *s2 )
|
||||
{
|
||||
while( 1 )
|
||||
{
|
||||
if( !*s1 && !*s2 )
|
||||
return 0;
|
||||
if( (!*s1 && *s2) || (*s1 < *s2) )
|
||||
return -1;
|
||||
if( (*s1 && !*s2) || (*s1 > *s2) )
|
||||
return 1;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
}
|
||||
|
||||
static int of1275_strncmp( const char *s1, const char *s2, L4_Word_t len )
|
||||
{
|
||||
while( len > 0 )
|
||||
{
|
||||
if( !*s1 && !*s2 )
|
||||
return 0;
|
||||
if( (!*s1 && *s2) || (*s1 < *s2) )
|
||||
return -1;
|
||||
if( (*s1 && !*s2) || (*s1 > *s2) )
|
||||
return 1;
|
||||
s1++;
|
||||
s2++;
|
||||
len--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "1275tree.h"
|
||||
#include "lib.h"
|
||||
|
||||
int of1275_device_t::get_depth()
|
||||
{
|
||||
|
@ -93,7 +60,7 @@ bool of1275_device_t::get_prop( const char *prop_name, char **data, L4_Word_t *d
|
|||
|
||||
for( L4_Word_t i = 0; i < this->get_prop_count(); i++ )
|
||||
{
|
||||
if( !of1275_strcmp(item_name->data, prop_name) )
|
||||
if( !strcmp(item_name->data, prop_name) )
|
||||
{
|
||||
*data = item_data->data;
|
||||
*data_len = item_data->len;
|
||||
|
@ -137,7 +104,7 @@ of1275_device_t * of1275_tree_t::find( const char *name )
|
|||
|
||||
while( dev->is_valid() )
|
||||
{
|
||||
if( !of1275_strcmp(dev->get_name(), name) )
|
||||
if( !strcmp(dev->get_name(), name) )
|
||||
return dev;
|
||||
dev = dev->next();
|
||||
}
|
||||
|
@ -190,7 +157,7 @@ of1275_device_t * of1275_tree_t::get_parent( of1275_device_t *dev )
|
|||
of1275_device_t *parent = this->first();
|
||||
while( parent->is_valid() )
|
||||
{
|
||||
if( !of1275_strncmp(parent->get_name(), dev->get_name(), cnt) )
|
||||
if( !strncmp(parent->get_name(), dev->get_name(), cnt) )
|
||||
if( parent->get_depth() == (depth-1) )
|
||||
return parent;
|
||||
parent = parent->next();
|
||||
|
@ -212,7 +179,7 @@ of1275_device_t * of1275_tree_t::find_device_type( const char *device_type )
|
|||
while( dev->is_valid() )
|
||||
{
|
||||
if( dev->get_prop("device_type", &type, &len) )
|
||||
if( !of1275_strcmp(type, device_type) )
|
||||
if( !strcmp(type, device_type) )
|
||||
return dev;
|
||||
dev = dev->next();
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ SRCS= get_hex.cc print.cc $($(ARCH)_SRCS)
|
|||
|
||||
include $(top_srcdir)/Mk/l4.lib.mk
|
||||
|
||||
|
||||
test:
|
||||
@echo SRCS=${SRCS}
|
||||
@echo OBJS=${OBJS}
|
||||
|
|
|
@ -36,46 +36,6 @@
|
|||
|
||||
static const char *indent = " ";
|
||||
|
||||
void fdt_t::dump()
|
||||
{
|
||||
if (!is_valid())
|
||||
printf("Invalid FDT\n");
|
||||
|
||||
int ilen = strlen(indent);
|
||||
|
||||
int level = 0;
|
||||
fdt_node_t *node = get_root_node();
|
||||
|
||||
do {
|
||||
if (node->is_begin_node())
|
||||
{
|
||||
fdt_header_t* hdr = (fdt_header_t*)node;
|
||||
printf("%s%s {\n", &indent[ilen - level * 2],
|
||||
level == 0 ? "/" : hdr->name);
|
||||
level++;
|
||||
node = get_next_node(hdr);
|
||||
}
|
||||
else if (node->is_property_node())
|
||||
{
|
||||
fdt_property_t* prop = (fdt_property_t*)node;
|
||||
printf("%s%s\n", &indent[ilen - level * 2], prop->get_name(this));
|
||||
node = get_next_node(prop);
|
||||
}
|
||||
else if (node->is_end_node())
|
||||
{
|
||||
level--;
|
||||
printf("%s}\n", &indent[ilen - level * 2]);
|
||||
node++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unknown node type %d\n", node->tag);
|
||||
break;
|
||||
}
|
||||
} while(level > 0);
|
||||
}
|
||||
|
||||
|
||||
fdt_header_t *fdt_t::find_subtree_node(fdt_node_t *node, char *name)
|
||||
{
|
||||
int level = 0;
|
||||
|
@ -100,7 +60,6 @@ fdt_header_t *fdt_t::find_subtree_node(fdt_node_t *node, char *name)
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("unknown node type %d\n", node->tag);
|
||||
break;
|
||||
}
|
||||
} while(level > 0);
|
||||
|
@ -131,7 +90,6 @@ fdt_property_t *fdt_t::find_property_node(fdt_node_t *node, char *name)
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("unknown node type %d\n", node->tag);
|
||||
break;
|
||||
}
|
||||
} while(level > 0);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001-2004, Karlsruhe University
|
||||
* Copyright (C) 2001-2004, 2010, Karlsruhe University
|
||||
*
|
||||
* File path: pistachio.current/user/lib/io/ia32-getc.cc
|
||||
* File path: ia32-getc.cc
|
||||
* Description: getc() for x86-based PCs
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, Karlsruhe University
|
||||
*
|
||||
* File path: mini-print.cc
|
||||
* Description: tiny version of printf
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mini-print.cc,v 1.5 2003/09/24 19:06:28 skoglund Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
#include <l4io.h>
|
||||
#include <l4/types.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
void print_hex(L4_Word_t val);
|
||||
void print_string(char* s);
|
||||
void print_dec(L4_Word_t val);
|
||||
|
||||
|
||||
extern "C" int puts (const char * str)
|
||||
{
|
||||
return printf ("%s\n", str);
|
||||
}
|
||||
|
||||
extern "C" int putchar (int c)
|
||||
{
|
||||
printf ("%c", c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static const char hexchars[] = "0123456789ABCDEF";
|
||||
|
||||
void print_hex(L4_Word_t val)
|
||||
{
|
||||
signed int i; /* becomes negative */
|
||||
for (i=sizeof(L4_Word_t)*8-4; i >= 0; i -= 4)
|
||||
putc(hexchars[(val >> i) & 0xF]);
|
||||
}
|
||||
|
||||
void print_string(char* s)
|
||||
{
|
||||
while (*s)
|
||||
putc(*s++);
|
||||
}
|
||||
|
||||
|
||||
void print_dec(L4_Word_t val)
|
||||
{
|
||||
char buff[16];
|
||||
L4_Word_t i = 14;
|
||||
|
||||
buff[15] = '\0';
|
||||
do
|
||||
{
|
||||
buff[i] = (val % 10) + '0';
|
||||
val = val / 10;
|
||||
i--;
|
||||
} while(val);
|
||||
|
||||
|
||||
print_string(&buff[i+1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int printf(const char* format, ...)
|
||||
{
|
||||
L4_Word_t ret = 1;
|
||||
L4_Word_t i = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, format);
|
||||
|
||||
//#define arg(x) (((L4_Word_t *) &format)[(x)+1])
|
||||
#define arg(x) va_arg (ap, L4_Word_t)
|
||||
|
||||
/* sanity check */
|
||||
if (format == NULL)
|
||||
return 0;
|
||||
|
||||
while (*format)
|
||||
{
|
||||
switch (*(format))
|
||||
{
|
||||
case '%':
|
||||
next_fmt:
|
||||
switch (*(++format))
|
||||
{
|
||||
case 'l': case '-':
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
goto next_fmt;
|
||||
|
||||
case 'c':
|
||||
putc (arg (i));
|
||||
break;
|
||||
case 'd':
|
||||
print_dec (arg (i));
|
||||
break;
|
||||
case 'p':
|
||||
case 'x':
|
||||
print_hex ((L4_Word_t) arg (i));
|
||||
break;
|
||||
case 's':
|
||||
print_string ((char*) arg (i));
|
||||
break;
|
||||
default:
|
||||
print_string ("?");
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
|
||||
default:
|
||||
putc (*format);
|
||||
if (*format == '\n')
|
||||
putc('\r');
|
||||
break;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -30,8 +30,6 @@
|
|||
********************************************************************/
|
||||
#include <config.h>
|
||||
#include <l4/types.h>
|
||||
#include <l4/sigma0.h>
|
||||
#include <l4/kip.h>
|
||||
#include <l4/types.h>
|
||||
#include <l4/powerpc/kdebug.h>
|
||||
|
||||
|
@ -42,99 +40,170 @@ extern "C" int getc( void ) __attribute__ ((weak, alias("__l4_getc")));
|
|||
extern "C" void __l4_putc( int c );
|
||||
extern "C" void putc( int c ) __attribute__ ((weak, alias("__l4_putc")));
|
||||
|
||||
#if defined CONFIG_HAVE_DEVICE_TREE
|
||||
/****************************************************************************
|
||||
*
|
||||
* Use this switch to avoid the lib go fishing for device trees (FDT/1275)
|
||||
* Instead, declare a variable.
|
||||
*
|
||||
***************************************************************************/
|
||||
void *__l4_powerpc_device_tree = NULL;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Console I/O using UART or PSIM interface.
|
||||
*
|
||||
***************************************************************************/
|
||||
#if defined(CONFIG_COMPORT)
|
||||
static int io_init( void )
|
||||
|
||||
#include <l4/sigma0.h>
|
||||
#include "powerpc-port.h"
|
||||
#include "fdt.h"
|
||||
#include "1275tree.h"
|
||||
|
||||
static volatile L4_Word8_t *comport = CONFIG_COMPORT;
|
||||
static bool io_initialized = false;
|
||||
|
||||
fdt_t *__l4_fdt_ptr = 0;
|
||||
|
||||
#define IER (comport+1)
|
||||
#define EIR (comport+2)
|
||||
#define LCR (comport+3)
|
||||
#define MCR (comport+4)
|
||||
#define LSR (comport+5)
|
||||
#define MSR (comport+6)
|
||||
#define DLLO (comport+0)
|
||||
#define DLHI (comport+1)
|
||||
|
||||
|
||||
static void io_init( void )
|
||||
{
|
||||
of1275_device_t *dev;
|
||||
|
||||
if (io_initialized)
|
||||
return;
|
||||
|
||||
io_initialized = true;
|
||||
|
||||
#if CONFIG_COMPORT == 1
|
||||
/* PSIM via 1275 tree */
|
||||
char *alias;
|
||||
L4_Word_t *reg, len;
|
||||
of1275_device_t *dev;
|
||||
of1275_tree_t *of1275_tree = (of1275_tree_t *) L4_Sigma0_GetSpecial(OF1275_KIP_TYPE, 0, 4096);
|
||||
|
||||
|
||||
/* 1275 tree */
|
||||
of1275_tree_t *of1275_tree = L4_Sigma0_GetSpecial(OF1275_KIP_TYPE, NULL, 4096);
|
||||
|
||||
if( of1275_tree == 0 )
|
||||
return 0;
|
||||
return;
|
||||
|
||||
dev = of1275_tree->find( "/aliases" );
|
||||
if( dev == 0 )
|
||||
return 0;
|
||||
return;
|
||||
if( !dev->get_prop("com", &alias, &len) )
|
||||
return 0;
|
||||
return;
|
||||
|
||||
dev = of1275_tree->find( alias );
|
||||
if( dev == 0 )
|
||||
return 0;
|
||||
return;
|
||||
if( !dev->get_prop("reg", (char **)®, &len) )
|
||||
return 0;
|
||||
return;
|
||||
|
||||
if( (len != 3*sizeof(L4_Word_t)) || !reg[1] )
|
||||
return 0;
|
||||
return;
|
||||
|
||||
/* Request the device page from sigma0.
|
||||
/*
|
||||
* Request the device page from sigma0.
|
||||
*/
|
||||
|
||||
L4_ThreadId_t sigma0 = L4_GlobalId( L4_ThreadIdUserBase(L4_GetKernelInterface()), 1);
|
||||
if( sigma0 == L4_Myself() )
|
||||
return 0;
|
||||
return;
|
||||
|
||||
// Install it as the 2nd page in our address space.
|
||||
// Hopefully it is free!
|
||||
L4_Fpage_t target = L4_Fpage( 4096, 4096 );
|
||||
|
||||
L4_Fpage_t fpage = L4_Fpage( reg[1], 4096 );
|
||||
fpage.X.rwx = L4_ReadWriteOnly;
|
||||
fpage = L4_Sigma0_GetPage( sigma0, fpage, target );
|
||||
if( L4_IsNilFpage(fpage) )
|
||||
return 0;
|
||||
return;
|
||||
|
||||
__l4_com_registers = (char *)L4_Address(target);
|
||||
__l4_com_registers[3] = 0; // Some initialization ...
|
||||
comport = (volatile L4_Word8_t *)L4_Address(target);
|
||||
comport[3] = 0; // Some initialization ...
|
||||
|
||||
return 1;
|
||||
#else
|
||||
|
||||
#if CONFIG_COMPORT == 0
|
||||
/* FDT */
|
||||
fdt_property_t *prop;
|
||||
fdt_node_t *node;
|
||||
fdt_t *fdt;
|
||||
|
||||
if (!(fdt = __l4_fdt_ptr))
|
||||
return;
|
||||
|
||||
if (!(node = fdt->find_subtree("/aliases")))
|
||||
return;
|
||||
|
||||
if (! (prop = fdt->find_property_node(node, "serial0")) )
|
||||
return;
|
||||
|
||||
|
||||
if (!(node = fdt->find_subtree(prop->get_string())))
|
||||
return;
|
||||
|
||||
if (! (prop = fdt->find_property_node(node, "virtual-reg")) )
|
||||
return;
|
||||
|
||||
comport = (volatile L4_Word8_t *) prop->get_word(0);
|
||||
#endif /* CONFIG_COMPORT == 0 */
|
||||
if (comport)
|
||||
{
|
||||
outb(LCR, 0x80); /* select bank 1 */
|
||||
for (volatile int i = 10000000; i--; );
|
||||
outb(DLLO, (((115200/CONFIG_COMSPEED) >> 0) & 0x00FF));
|
||||
outb(DLHI, (((115200/CONFIG_COMSPEED) >> 8) & 0x00FF));
|
||||
outb(LCR, 0x03); /* set 8,N,1 */
|
||||
outb(IER, 0x00); /* disable interrupts */
|
||||
outb(EIR, 0x07); /* enable FIFOs */
|
||||
inb(IER);
|
||||
inb(EIR);
|
||||
inb(LCR);
|
||||
inb(MCR);
|
||||
inb(LSR);
|
||||
inb(MSR);
|
||||
|
||||
//extern "C" int printf (const char *fmt, ...);
|
||||
//printf("Serial port %x initialized\n", comport);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
extern "C" int __l4_getc( void )
|
||||
{
|
||||
if( __l4_com_registers == 0 )
|
||||
io_init();
|
||||
|
||||
if ( comport )
|
||||
{
|
||||
if( __l4_io_enabled )
|
||||
return 0;
|
||||
if( !__l4_io_init() )
|
||||
return 0;
|
||||
#if CONFIG_COMPORT == 1
|
||||
return comport[0];
|
||||
#else
|
||||
while ((inb(comport+5) & 0x01) == 0);
|
||||
return inb(comport);
|
||||
}
|
||||
|
||||
return __l4_com_registers[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void __l4_putc( int c )
|
||||
{
|
||||
if( __l4_com_registers == 0 )
|
||||
io_init();
|
||||
|
||||
if ( comport )
|
||||
{
|
||||
if( __l4_io_enabled )
|
||||
return;
|
||||
if( !__l4_io_init() )
|
||||
return;
|
||||
#if CONFIG_COMPORT == 1
|
||||
comport[0] = c;
|
||||
#else
|
||||
while (!(inb(comport+5) & 0x20));
|
||||
outb(comport,c);
|
||||
while (!(inb(comport+5) & 0x40));
|
||||
if (c == '\n')
|
||||
__l4_putc('\r');
|
||||
#endif
|
||||
}
|
||||
|
||||
__l4_com_registers[0] = c;
|
||||
}
|
||||
|
||||
#else /* CONFIG_COMPORT */
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2010, Karlsruhe Institute of Technology
|
||||
*
|
||||
* Filename: powerpc-port.h
|
||||
* Author: Jan Stoess <stoess@kit.edu>
|
||||
* Description:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
********************************************************************/
|
||||
#ifndef __USER__LIB__IO__POWERPC_PORT_H__
|
||||
#define __USER__LIB__IO__POWERPC_PORT_H__
|
||||
|
||||
L4_INLINE void outb(volatile L4_Word8_t *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
|
||||
}
|
||||
|
||||
L4_INLINE int inb(const volatile L4_Word8_t *addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"sync; lbz%U1%X1 %0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) : "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !__USER__LIB__IO__POWERPC_PORT_H__ */
|
|
@ -59,7 +59,6 @@ extern "C" int __l4_putchar (int c);
|
|||
extern "C" int putchar (int c)
|
||||
__attribute__ ((weak, alias ("__l4_putchar")));
|
||||
|
||||
|
||||
static void print_string (const char * s);
|
||||
|
||||
int __l4_puts (const char * str)
|
||||
|
|
|
@ -1,262 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2000-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This source code is dual-licensed. You may use it under the terms of the
|
||||
* GNU General Public License version 2, or under the license below.
|
||||
*
|
||||
* This source code has been made available to you by IBM on an AS-IS
|
||||
* basis. Anyone receiving this source is licensed under IBM
|
||||
* copyrights to use it in any way he or she deems fit, including
|
||||
* copying it, modifying it, compiling it, and redistributing it either
|
||||
* with or without modifications. No license under IBM patents or
|
||||
* patent applications is to be implied by the copyright license.
|
||||
*
|
||||
* Any user of this software should understand that IBM cannot provide
|
||||
* technical support for this software and will not be responsible for
|
||||
* any consequences resulting from the use of this software.
|
||||
*
|
||||
* Any person who transfers this source code or any derivative work
|
||||
* must include the IBM copyright notice, this paragraph, and the
|
||||
* preceding two paragraphs in the transferred software.
|
||||
*
|
||||
* COPYRIGHT I B M CORPORATION 1995
|
||||
* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
|
||||
*/
|
||||
|
||||
#include "fdt.h"
|
||||
#include "powerpc.h"
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* High Level Configuration Options
|
||||
*----------------------------------------------------------------------*/
|
||||
#define CONFIG_EBONY 1 /* Board is ebony */
|
||||
#define CONFIG_440GP 1 /* Specifc GP support */
|
||||
#define CONFIG_440 1 /* ... PPC440 family */
|
||||
#define CONFIG_4xx 1 /* ... PPC4xx family */
|
||||
#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
|
||||
/*-----------------------------------------------------------------------
|
||||
* Base addresses -- Note these are effective addresses where the
|
||||
* actual resources get mapped (not physical addresses)
|
||||
*----------------------------------------------------------------------*/
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x00000000 /* _must_ be 0 */
|
||||
#define CONFIG_SYS_FLASH_BASE 0xff800000 /* start of FLASH */
|
||||
#define CONFIG_SYS_PCI_MEMBASE 0x80000000 /* mapped pci memory */
|
||||
#define CONFIG_SYS_PERIPHERAL_BASE 0xe0000000 /* internal peripherals */
|
||||
#define CONFIG_SYS_ISRAM_BASE 0xc0000000 /* internal SRAM */
|
||||
#define CONFIG_SYS_PCI_BASE 0xd0000000 /* internal PCI regs */
|
||||
|
||||
#define CONFIG_SYS_NVRAM_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x08000000)
|
||||
#define CONFIG_SYS_FPGA_BASE (CONFIG_SYS_PERIPHERAL_BASE + 0x08300000)
|
||||
/*-----------------------------------------------------------------------
|
||||
* Serial Port
|
||||
*----------------------------------------------------------------------*/
|
||||
#undef CONFIG_SERIAL_SOFTWARE_FIFO
|
||||
#define CONFIG_SYS_EXT_SERIAL_CLOCK (1843200 * 6) /* Ext clk @ 11.059 MHz */
|
||||
#define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
#define CONFIG_SERIAL_MULTI
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE \
|
||||
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
|
||||
|
||||
//#include "ppc4xx.h"
|
||||
#define CNTRL_DCR_BASE 0x0b0
|
||||
#define CPC0_CR0 (CNTRL_DCR_BASE+0x3b) /* Control 0 register */
|
||||
#define CPC0_CR1 (CNTRL_DCR_BASE+0x3a) /* Control 1 register */
|
||||
|
||||
|
||||
#define UART0_BASE (CONFIG_SYS_PERIPHERAL_BASE + 0x00000200)
|
||||
#define UART1_BASE (CONFIG_SYS_PERIPHERAL_BASE + 0x00000300)
|
||||
|
||||
#define CR0_MASK 0x3fff0000
|
||||
#define CR0_EXTCLK_ENA 0x00600000
|
||||
#define CR0_UDIV_POS 16
|
||||
#define UDIV_SUBTRACT 1
|
||||
#define UART0_SDR CPC0_CR0
|
||||
#define MFREG(a, d) d = mfdcr(a)
|
||||
#define MTREG(a, d) mtdcr(a, d)
|
||||
|
||||
|
||||
|
||||
#define UART_RBR 0x00
|
||||
#define UART_THR 0x00
|
||||
#define UART_IER 0x01
|
||||
#define UART_IIR 0x02
|
||||
#define UART_FCR 0x02
|
||||
#define UART_LCR 0x03
|
||||
#define UART_MCR 0x04
|
||||
#define UART_LSR 0x05
|
||||
#define UART_MSR 0x06
|
||||
#define UART_SCR 0x07
|
||||
#define UART_DLL 0x00
|
||||
#define UART_DLM 0x01
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Line Status Register.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
#define asyncLSRDataReady1 0x01
|
||||
#define asyncLSROverrunError1 0x02
|
||||
#define asyncLSRParityError1 0x04
|
||||
#define asyncLSRFramingError1 0x08
|
||||
#define asyncLSRBreakInterrupt1 0x10
|
||||
#define asyncLSRTxHoldEmpty1 0x20
|
||||
#define asyncLSRTxShiftEmpty1 0x40
|
||||
#define asyncLSRRxFifoError1 0x80
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the SMC ports
|
||||
* as serial console interface.
|
||||
*/
|
||||
|
||||
int serial_init_dev(unsigned long base)
|
||||
{
|
||||
unsigned long reg;
|
||||
unsigned long udiv;
|
||||
unsigned short bdiv;
|
||||
unsigned long tmp;
|
||||
L4_Word8_t val;
|
||||
|
||||
MFREG(UART0_SDR, reg);
|
||||
reg &= ~CR0_MASK;
|
||||
|
||||
reg |= CR0_EXTCLK_ENA;
|
||||
udiv = 1;
|
||||
tmp = CONFIG_BAUDRATE * 16;
|
||||
bdiv = (CONFIG_SYS_EXT_SERIAL_CLOCK + tmp / 2) / tmp;
|
||||
|
||||
reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS; /* set the UART divisor */
|
||||
|
||||
/*
|
||||
* Configure input clock to baudrate generator for all
|
||||
* available serial ports here
|
||||
*/
|
||||
MTREG(UART0_SDR, reg);
|
||||
|
||||
|
||||
out_8((L4_Word8_t *)base + UART_LCR, 0x80); /* set DLAB bit */
|
||||
out_8((L4_Word8_t *)base + UART_DLL, bdiv); /* set baudrate divisor */
|
||||
out_8((L4_Word8_t *)base + UART_DLM, bdiv >> 8); /* set baudrate divisor */
|
||||
out_8((L4_Word8_t *)base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
|
||||
out_8((L4_Word8_t *)base + UART_FCR, 0x00); /* disable FIFO */
|
||||
out_8((L4_Word8_t *)base + UART_MCR, 0x00); /* no modem control DTR RTS */
|
||||
val = in_8((L4_Word8_t *)base + UART_LSR); /* clear line status */
|
||||
val = in_8((L4_Word8_t *)base + UART_RBR); /* read receive buffer */
|
||||
out_8((L4_Word8_t *)base + UART_SCR, 0x00); /* set scratchpad */
|
||||
out_8((L4_Word8_t *)base + UART_IER, 0x00); /* set interrupt enable reg */
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void serial_putc_dev(unsigned long base, const char c)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (c == '\n')
|
||||
serial_putc_dev(base, '\r');
|
||||
|
||||
/* check THRE bit, wait for transmiter available */
|
||||
for (i = 1; i < 3500; i++) {
|
||||
if ((in_8((L4_Word8_t *)base + UART_LSR) & 0x20) == 0x20)
|
||||
break;
|
||||
//udelay (100);
|
||||
}
|
||||
|
||||
out_8((L4_Word8_t *)base + UART_THR, c); /* put character out */
|
||||
}
|
||||
|
||||
void serial_puts_dev (unsigned long base, const char *s)
|
||||
{
|
||||
while (*s)
|
||||
serial_putc_dev (base, *s++);
|
||||
}
|
||||
|
||||
int serial_getc_dev (unsigned long base)
|
||||
{
|
||||
unsigned char status = 0;
|
||||
|
||||
while (1) {
|
||||
status = in_8((L4_Word8_t *)base + UART_LSR);
|
||||
if ((status & asyncLSRDataReady1) != 0x0)
|
||||
break;
|
||||
|
||||
if ((status & ( asyncLSRFramingError1 |
|
||||
asyncLSROverrunError1 |
|
||||
asyncLSRParityError1 |
|
||||
asyncLSRBreakInterrupt1 )) != 0) {
|
||||
out_8((L4_Word8_t *)base + UART_LSR,
|
||||
asyncLSRFramingError1 |
|
||||
asyncLSROverrunError1 |
|
||||
asyncLSRParityError1 |
|
||||
asyncLSRBreakInterrupt1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0x000000ff & (int) in_8((L4_Word8_t *)base));
|
||||
}
|
||||
|
||||
class cons_t {
|
||||
public:
|
||||
bool verbose;
|
||||
|
||||
|
||||
bool init()
|
||||
{
|
||||
serial_init_dev(UART0_BASE);
|
||||
serial_init_dev(UART1_BASE);
|
||||
return true;
|
||||
}
|
||||
|
||||
void putc(int c)
|
||||
{
|
||||
serial_putc_dev(UART0_BASE,c);
|
||||
serial_putc_dev(UART1_BASE,c);
|
||||
}
|
||||
};
|
||||
|
||||
cons_t cons;
|
||||
|
||||
extern "C" void putc(int c)
|
||||
{
|
||||
cons.putc(c);
|
||||
}
|
||||
|
||||
|
||||
bool initialize_console(fdt_t *fdt)
|
||||
{
|
||||
cons.init();
|
||||
|
||||
fdt_property_t *prop;
|
||||
fdt_node_t *node = fdt->find_subtree("/aliases");
|
||||
|
||||
if (! (prop = fdt->find_property_node(node, "serial0")) )
|
||||
putc('1');
|
||||
|
||||
putc('2');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -132,14 +132,11 @@ bgp_cons_t bgp_cons;
|
|||
|
||||
extern "C" void putc(int c)
|
||||
{
|
||||
static bool do_init = true;
|
||||
|
||||
if( do_init )
|
||||
{
|
||||
do_init = false;
|
||||
bgp_cons.init(get_fdt_ptr());
|
||||
}
|
||||
bgp_cons.putc(c);
|
||||
#if defined(CONFIG_COMPORT)
|
||||
extern void __l4_putc(int c);
|
||||
__l4_putc(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,6 +192,9 @@ extern "C" void __loader(L4_Word_t r3, L4_Word_t r4, L4_Word_t r5,
|
|||
L4_Word_t r6, L4_Word_t r7)
|
||||
{
|
||||
fdt_ptr = (fdt_t*)r3;
|
||||
|
||||
extern fdt_t *__l4_fdt_ptr;
|
||||
__l4_fdt_ptr = fdt_ptr;
|
||||
|
||||
bgp_cons.init(fdt_ptr);
|
||||
loader();
|
||||
}
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2010, Karlsruhe University
|
||||
*
|
||||
* File path: powerpc.h
|
||||
* Description:
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id:$
|
||||
*
|
||||
********************************************************************/
|
||||
#include <l4/types.h>
|
||||
#define stringify(s) tostring(s)
|
||||
#define tostring(s) #s
|
||||
|
||||
#define mfdcr(rn) ({unsigned int rval; \
|
||||
asm volatile("mfdcr %0," stringify(rn) \
|
||||
: "=r" (rval)); rval;})
|
||||
#define mtdcr(rn, v) asm volatile("mtdcr " stringify(rn) ",%0" : : "r" (v))
|
||||
|
||||
#define mfmsr() ({unsigned int rval; \
|
||||
asm volatile("mfmsr %0" : "=r" (rval)); rval;})
|
||||
#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v))
|
||||
|
||||
#define mfspr(rn) ({unsigned int rval; \
|
||||
asm volatile("mfspr %0," stringify(rn) \
|
||||
: "=r" (rval)); rval;})
|
||||
#define mtspr(rn, v) asm volatile("mtspr " stringify(rn) ",%0" : : "r" (v))
|
||||
|
||||
#define tlbie(v) asm volatile("tlbie %0 \n sync" : : "r" (v))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
|
||||
*
|
||||
* Read operations have additional twi & isync to make sure the read
|
||||
* is actually performed (i.e. the data has come back) before we start
|
||||
* executing any following instructions.
|
||||
*/
|
||||
L4_INLINE int in_8(const volatile unsigned char *addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"sync; lbz%U1%X1 %0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) : "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
L4_INLINE void out_8(volatile unsigned char *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
|
||||
}
|
||||
|
||||
L4_INLINE int in_le16(const volatile unsigned short *addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__asm__ __volatile__("sync; lhbrx %0,0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) :
|
||||
"r" (addr), "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
L4_INLINE int in_be16(const volatile unsigned short *addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
__asm__ __volatile__("sync; lhz%U1%X1 %0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) : "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
L4_INLINE void out_le16(volatile unsigned short *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) :
|
||||
"r" (val), "r" (addr));
|
||||
}
|
||||
|
||||
L4_INLINE void out_be16(volatile unsigned short *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
|
||||
}
|
||||
|
||||
L4_INLINE unsigned in_le32(const volatile unsigned *addr)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
__asm__ __volatile__("sync; lwbrx %0,0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) :
|
||||
"r" (addr), "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
L4_INLINE unsigned in_be32(const volatile unsigned *addr)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
__asm__ __volatile__("sync; lwz%U1%X1 %0,%1;\n"
|
||||
"twi 0,%0,0;\n"
|
||||
"isync" : "=r" (ret) : "m" (*addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
L4_INLINE void out_le32(volatile unsigned *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) :
|
||||
"r" (val), "r" (addr));
|
||||
}
|
||||
|
||||
L4_INLINE void out_be32(volatile unsigned *addr, int val)
|
||||
{
|
||||
__asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue