-PPC: implement uart discovery at user-level

This commit is contained in:
Jan Stoess 2010-07-06 19:43:10 +02:00
parent a26b69835c
commit 3ae8f026c3
11 changed files with 99 additions and 44 deletions

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: apps/bench/pingpong/pingpong.cc
* File path: bench/pingpong/pingpong.cc
* Description:
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2003, 2007, Karlsruhe University
* Copyright (C) 2003, 2007, 2010, Karlsruhe University
*
* File path: l4test/ipc-smp.cc
* Description: Simple SMP IPC tests

View File

@ -91,16 +91,17 @@ L4_INLINE L4_Fpage_t L4_Sigma0_GetAny (L4_ThreadId_t s0,
/**
* L4_Sigma0_GetSpecial(L4_Word_t type)
*
* Searches the KIP's memory descriptors for special memory segment. If address
* is zero. requests sigma0 to map the relevant pages into the current address space
* 1:1, and returns a pointer to the segment
* Searches the KIP's memory descriptors for special memory segment. Requests
* sigma0 to map the relevant pages into the current address space, (1:1 if
* address equals zero)
*
*/
L4_INLINE void * L4_Sigma0_GetSpecial(L4_Word_t type, L4_Word_t address, L4_Word_t pagesize)
L4_INLINE void *L4_Sigma0_GetSpecial(L4_Word_t type, void* address, L4_Word_t pagesize)
{
void *kip = L4_GetKernelInterface();
L4_ThreadId_t sigma0 = L4_GlobalId(L4_ThreadIdUserBase(kip), 1);
// Search for the memory descriptor for the 1275 tree.
// Search for the memory descriptor for the type.
for( L4_Word_t i = 0; i < L4_NumMemoryDescriptors(kip); i++ )
{
L4_MemoryDesc_t *mdesc = L4_MemoryDesc( kip, i );
@ -108,34 +109,37 @@ L4_INLINE void * L4_Sigma0_GetSpecial(L4_Word_t type, L4_Word_t address, L4_Word
{
L4_Word_t start = L4_MemoryDescLow(mdesc);
L4_Word_t end = L4_MemoryDescHigh(mdesc) + 1;
void *ret;
L4_Word_t rcvstart = (L4_Word_t) address;
if (!rcvstart)
{
rcvstart = start;
address = (void *) start;
}
if ( L4_Myself() == sigma0 )
return 0;
if( L4_Myself() == sigma0 )
return (void *)start;
if (address == 0)
address = start;
ret = (void *)address;
// Request mappings for the pages.
while( start < end )
{
L4_Fpage_t fpage = L4_Fpage( start, pagesize );
L4_Fpage_t rcvfpage = L4_Fpage( address, pagesize );
L4_Fpage_t rcvfpage = L4_Fpage( rcvstart, pagesize );
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage( sigma0, fpage, rcvfpage );
if( L4_IsNilFpage(fpage) )
return 0;
return address;
start += pagesize;
rcvstart += pagesize;
}
return ret;
return address;
}
}
return 0;
}
#endif /* !__L4__SIGMA0_H__ */

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2001-2004, 2007, Karlsruhe University
* Copyright (C) 2001-2004, 2007, 2010, Karlsruhe University
*
* File path: l4/types.h
* Description: Commonly used L4 types

View File

@ -37,11 +37,6 @@
#include <l4/kip.h>
#include <l4/sigma0.h>
#define OF1275_KIP_MAJOR_TYPE 0xe
#define OF1275_KIP_MINOR_TYPE 0xf
#define OF1275_KIP_TYPE (OF1275_KIP_MAJOR_TYPE + (OF1275_KIP_MINOR_TYPE << 4))
L4_INLINE L4_Word_t of1275_align( L4_Word_t val )
{
L4_Word_t size = sizeof(L4_Word_t);
@ -94,8 +89,9 @@ public:
bool get_prop( const char *prop_name, L4_Word_t *data )
{
L4_Word_t *ptr, prop_len;
if( !this->get_prop(prop_name, (char **)&ptr, &prop_len) )
L4_Word_t prop_len;
char *ptr;
if( !this->get_prop(prop_name, &ptr, &prop_len) )
return false;
if( prop_len != sizeof(*data) )
return false;

View File

@ -32,7 +32,7 @@
#include <l4/types.h>
#include <l4/types.h>
#include <l4/powerpc/kdebug.h>
#include <l4/space.h>
extern "C" int __l4_getc( void );
extern "C" int getc( void ) __attribute__ ((weak, alias("__l4_getc")));
@ -55,7 +55,14 @@ extern "C" void putc( int c ) __attribute__ ((weak, alias("__l4_putc")));
static volatile L4_Word8_t *comport = CONFIG_COMPORT;
static bool io_initialized = false;
fdt_t *__l4_fdt_ptr = 0;
#define DTREE_KIP_SUBTYPE 0xf
#define DTREE_KIP_SUBTYPE 0xf
#define DTREE_KIP_TYPE (L4_BootLoaderSpecificMemoryType + (DTREE_KIP_SUBTYPE << 4))
#define SIGMA0_DEVICE_RELOC 0xf0000000
void *__l4_dtree = 0;
static L4_Word8_t __attribute__((aligned(4096))) comport_page[4096];
#define IER (comport+1)
#define EIR (comport+2)
@ -66,6 +73,7 @@ fdt_t *__l4_fdt_ptr = 0;
#define DLLO (comport+0)
#define DLHI (comport+1)
extern "C" int printf (const char *fmt, ...);
static void io_init( void )
{
@ -80,9 +88,8 @@ static void io_init( void )
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);
of1275_tree_t *of1275_tree = (of1275_tree_t *) L4_Sigma0_GetSpecial(DTREE_KIP_TYPE, 0, 4096);
if( of1275_tree == 0 )
return;
@ -123,12 +130,24 @@ static void io_init( void )
#else
#if CONFIG_COMPORT == 0
/* FDT */
fdt_property_t *prop;
fdt_node_t *node;
fdt_t *fdt;
bool io_direct = true;
if (!(__l4_dtree))
{
__l4_dtree = L4_Sigma0_GetSpecial(DTREE_KIP_TYPE, 0, 4096);
io_direct = false;
}
if (!(fdt = __l4_fdt_ptr))
if (!(fdt = (fdt_t *) __l4_dtree))
return;
if (!(fdt->is_valid()))
return;
if (!(node = fdt->find_subtree("/aliases")))
@ -140,12 +159,50 @@ static void io_init( void )
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);
if (io_direct)
{
comport = (volatile L4_Word8_t *) prop->get_word(0);
}
else
{
if (! (prop = fdt->find_property_node(node, "reg")) )
return;
L4_Word_t comport_ofs = prop->get_word(0) & 4095;
L4_Word_t comport_phys = SIGMA0_DEVICE_RELOC + comport_ofs;
comport = comport_page + comport_ofs;
L4_Flush(L4_Fpage( (L4_Word_t) comport, 4096) + L4_FullyAccessible);
/*
* Request the device page from sigma0.
*/
L4_ThreadId_t sigma0 = L4_GlobalId( L4_ThreadIdUserBase(L4_GetKernelInterface()), 1);
if( sigma0 == L4_Myself() )
return;
// Hopefully it is free!
L4_Fpage_t target = L4_Fpage( (L4_Word_t) comport, 4096 );
L4_Fpage_t fpage = L4_Fpage( comport_phys, 4096 );
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage( sigma0, fpage, target );
if( L4_IsNilFpage(fpage) )
return;
}
#endif /* CONFIG_COMPORT == 0 */
if (comport)
{
outb(LCR, 0x80); /* select bank 1 */
@ -161,9 +218,6 @@ static void io_init( void )
inb(MCR);
inb(LSR);
inb(MSR);
//extern "C" int printf (const char *fmt, ...);
//printf("Serial port %x initialized\n", comport);
}
#endif
@ -206,7 +260,6 @@ extern "C" void __l4_putc( int c )
}
#else /* CONFIG_COMPORT */
extern "C" int __l4_getc()
{
return L4_KDB_ReadChar_Blocked();

View File

@ -83,7 +83,7 @@ PROGRAM_DEPS_amd64= $(top_builddir)/util/kickstart/libio32.a
## PowerPC specifics
##
SRCS_powerpc= $(SRCS_FDT)
LIBS_powerpc= -lio
LIBS_powerpc= -lio -ll4
LDFLAGS_powerpc=
CFLAGS_kickstart_powerpc:= $(CFLAGS)
MKIMAGE= mkimage

View File

@ -131,6 +131,8 @@ L4_Word_t fdt_init (void)
kip.install_root_task(modules[2].start, modules[2].end,
modules[2].entry, modules[2].type);
kip.dedicate_memory((L4_Word64_t) fdt, (L4_Word64_t) fdt + fdt->size, L4_BootLoaderSpecificMemoryType, 0xf );
// MUST BE LAST: store the fdt in the bootinfo field and update
// all descriptors
kip.update_kip((L4_Word_t)fdt);

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2003-2004, 2006, 2008, Karlsruhe University
* Copyright (C) 2003-2004, 2006, 2008, 2010, Karlsruhe University
*
* File path: mbi-amd64.cc
* Description:

View File

@ -191,8 +191,8 @@ 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;
extern void *__l4_dtree;
__l4_dtree = fdt_ptr;
bgp_cons.init(fdt_ptr);
loader();

View File

@ -223,9 +223,9 @@ extern "C" void loader_main( L4_Word_t r3, L4_Word_t r4, L4_Word_t of1275_entry)
kip_manager.dedicate_memory( devtree_start, devtree_end,
L4_BootLoaderSpecificMemoryType, 0xf );
kip_manager.update_kip(); // Do this last!
kip_manager.update_kip(of1275_entry); // Do this last!
start_kernel( r3, r4, of1275_entry );
start_kernel(r3, r4, of1275_entry);
}
extern word_t call_addr;