base-hw: Support for Raspberry Pi

This commit is contained in:
Norman Feske
2013-04-08 19:05:44 +02:00
parent 65f20262cb
commit 8ac6d8c96c
15 changed files with 570 additions and 1 deletions

View File

@ -123,7 +123,14 @@ Platform::Platform() :
unsigned const psl2 = get_page_size_log2();
init_alloc(&_core_mem_alloc, _ram_regions, _core_only_ram_regions, psl2);
init_alloc(&_irq_alloc, _irq_regions, _core_only_irq_regions);
init_alloc(&_io_mem_alloc, _mmio_regions, _core_only_mmio_regions, psl2);
/*
* Use byte granuarity for MMIO regions because on some platforms, devices
* driven by core share a physical page with devices driven outside of
* core. Using byte granuarlity allows handing out the MMIO page to trusted
* user-level device drivers.
*/
init_alloc(&_io_mem_alloc, _mmio_regions, _core_only_mmio_regions, 0);
/* add boot modules to ROM FS */
Bm_header * header = &_boot_module_headers_begin;

View File

@ -0,0 +1,24 @@
/*
* \brief Board driver for core
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _RPI__BOARD_H_
#define _RPI__BOARD_H_
/* Genode includes */
#include <drivers/board_base.h>
namespace Genode { struct Board; }
struct Genode::Board : Genode::Board_base { static void prepare_kernel() { } };
#endif /* _RPI__BOARD_H_ */

View File

@ -0,0 +1,23 @@
/*
* \brief CPU definition for Raspberry Pi
* \author Norman Feske
* \date 2013-04-11
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _RPI__CPU_H_
#define _RPI__CPU_H_
/* core includes */
#include <cpu/arm_v6.h>
namespace Genode { struct Cpu : Arm_v6::Cpu { }; }
#endif /* _RPI__CPU_H_ */

124
base-hw/src/core/rpi/pic.h Normal file
View File

@ -0,0 +1,124 @@
/*
* \brief Interrupt controller for kernel
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _RPI__PIC_H_
#define _RPI__PIC_H_
/* Genode includes */
#include <util/mmio.h>
#include <base/stdint.h>
/* core includes */
#include <board.h>
namespace Kernel
{
class Pic : Genode::Mmio
{
struct Irq_pending_basic : Register<0x0, 32>
{
struct Timer : Bitfield<0, 1> { };
struct Gpu : Bitfield<8, 2> { };
};
struct Irq_pending_gpu_1 : Register<0x04, 32> { };
struct Irq_pending_gpu_2 : Register<0x08, 32> { };
struct Irq_enable_gpu_1 : Register<0x10, 32> { };
struct Irq_enable_gpu_2 : Register<0x14, 32> { };
struct Irq_enable_basic : Register<0x18, 32> { };
struct Irq_disable_gpu_1 : Register<0x1c, 32> { };
struct Irq_disable_gpu_2 : Register<0x20, 32> { };
struct Irq_disable_basic : Register<0x24, 32> { };
private:
typedef Genode::uint32_t uint32_t;
/**
* Return true if specified interrupt is pending
*/
static bool _is_pending(unsigned i, uint32_t p1, uint32_t p2)
{
return i < 32 ? (p1 & (1 << i)) : (p2 & (1 << (i - 32)));
}
public:
Pic() : Genode::Mmio(Genode::Board::IRQ_CONTROLLER_BASE) { }
bool take_request(unsigned &irq)
{
/* read basic IRQ status mask */
uint32_t const p = read<Irq_pending_basic>();
/* read GPU IRQ status mask */
uint32_t const p1 = read<Irq_pending_gpu_1>(),
p2 = read<Irq_pending_gpu_2>();
if (Irq_pending_basic::Timer::get(p)) {
irq = 0;
return true;
}
/* search for lowest set bit in pending masks */
for (unsigned i = 0; i < 64; i++) {
if (!_is_pending(i, p1, p2))
continue;
irq = Genode::Board_base::GPU_IRQ_BASE + i;
return true;
}
return false;
}
void finish_request() { }
void unmask() { PDBG("not implemented"); }
void mask() { PDBG("not implemented"); }
void unmask(unsigned const i)
{
if (i < 8)
write<Irq_enable_basic>(1 << i);
else if (i < 32 + 8) {
write<Irq_enable_gpu_1>(1 << (i - 8));
write<Irq_enable_basic>(1 << 8);
} else {
write<Irq_enable_gpu_2>(1 << (i - 8 - 32));
write<Irq_enable_basic>(1 << 9);
}
}
void mask(unsigned const i)
{
if (i < 8)
write<Irq_disable_basic>(1 << i);
else if (i < 32 + 8)
write<Irq_disable_gpu_1>(1 << (i - 8));
else
write<Irq_disable_gpu_2>(1 << (i - 8 - 32));
}
};
}
#endif /* _RPI__PIC_H_ */

View File

@ -0,0 +1,81 @@
/*
* \brief Platform implementations specific for base-hw and Raspberry Pi
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* core includes */
#include <platform.h>
#include <board.h>
using namespace Genode;
Native_region * Platform::_ram_regions(unsigned const i)
{
static Native_region _regions[] =
{
{ Board::RAM_0_BASE, Board::RAM_0_SIZE }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_irq_regions(unsigned const i)
{
static Native_region _regions[] =
{
{ 0, 64 }
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_irq_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* system timer */
{ Board::SYSTEM_TIMER_IRQ, 1 },
/* UART */
{ Board::PL011_0_IRQ, 1 },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
{ 0x20000000, 0x22000000 },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
{
static Native_region _regions[] =
{
/* UART */
{ Board::PL011_0_MMIO_BASE, Board::PL011_0_MMIO_SIZE },
/* system timer */
{ Board::SYSTEM_TIMER_MMIO_BASE, Board::SYSTEM_TIMER_MMIO_SIZE },
/* IRQ controller */
{ Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE },
};
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
}

View File

@ -0,0 +1,41 @@
#
# \brief Build config for Genodes core process
# \author Norman Feske
# \date 2013-04-05
#
# declare wich specs must be given to build this target
REQUIRES = platform_rpi
# add include paths
INC_DIR += $(REP_DIR)/src/core/rpi
# add C++ sources
SRC_CC += platform_services.cc \
platform_support.cc
# add assembly sources
SRC_S += mode_transition.s \
boot_modules.s \
crt0.s
# declare source paths
vpath platform_services.cc $(BASE_DIR)/src/core
vpath platform_support.cc $(REP_DIR)/src/core/rpi
vpath mode_transition.s $(REP_DIR)/src/core/arm_v6
vpath crt0.s $(REP_DIR)/src/core/arm
#
# Check if there are other images wich shall be linked to core.
# If not use a dummy boot-modules file wich includes only the symbols.
#
ifeq ($(wildcard $(BUILD_BASE_DIR)/boot_modules.s),)
vpath boot_modules.s $(REP_DIR)/src/core/arm
else
INC_DIR += $(BUILD_BASE_DIR)
vpath boot_modules.s $(BUILD_BASE_DIR)
endif
# include less specific target parts
include $(REP_DIR)/src/core/target.inc

View File

@ -0,0 +1,77 @@
/*
* \brief Timer for kernel
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _RPI__TIMER_H_
#define _RPI__TIMER_H_
/* Genode includes */
#include <util/mmio.h>
#include <base/stdint.h>
#include <base/printf.h>
#include <drivers/board_base.h>
namespace Kernel { class Timer; }
class Kernel::Timer : public Genode::Mmio
{
/*
* The timer channel 0 apparently does not work on the Raspberry Pi.
* So we use channel 1.
*/
struct Cs : Register<0x0, 32>
{
struct Status : Bitfield<1, 1> { };
};
struct Clo : Register<0x4, 32> { };
struct Cmp : Register<0x10, 32> { };
private:
typedef Genode::uint32_t uint32_t;
typedef Genode::Board_base Board_base;
public:
Timer() : Mmio(Board_base::SYSTEM_TIMER_MMIO_BASE) { }
enum { IRQ = Board_base::SYSTEM_TIMER_IRQ };
inline void start_one_shot(uint32_t const tics)
{
write<Clo>(0);
write<Cmp>(read<Clo>() + tics);
write<Cs::Status>(1);
}
static uint32_t ms_to_tics(unsigned const ms)
{
return (Board_base::SYSTEM_TIMER_CLOCK / 1000) * ms;
}
unsigned stop_one_shot()
{
return read<Clo>();
}
void clear_interrupt()
{
write<Cs::Status>(1);
read<Cs>();
}
};
#endif /* _RPI__TIMER_H_ */

View File

@ -0,0 +1,47 @@
/*
* \brief Translation lookaside buffer
* \author Norman Feske
* \author Martin stein
* \date 2012-08-30
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _RPI__TLB_H_
#define _RPI__TLB_H_
/* core includes */
#include <tlb/arm_v6.h>
#include <board.h>
namespace Genode
{
struct Page_flags : Arm::Page_flags { };
class Tlb : public Arm_v6::Section_table { };
/**
* Translation lookaside buffer of core
*/
class Core_tlb : public Tlb
{
public:
/**
* Constructor - ensures that core never gets a pagefault
*/
Core_tlb()
{
map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0);
map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1);
}
};
}
#endif /* _RPI__TLB_H_ */