mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
hw: skeleton for building on x86_64
This patch contains the initial code needed to build and bootstrap the base-hw kernel on x86 64-bit platforms. It gets stuck earlier because the binary contains 64-bit instructions, but it is started in 32-bit mode. The initial setup of page tables and switch to long mode is still missing from the crt0 code.
This commit is contained in:
parent
cc00af85bf
commit
a974726e26
50
repos/base-hw/include/x86_64/kernel/interface_support.h
Normal file
50
repos/base-hw/include/x86_64/kernel/interface_support.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* \brief Interface between kernel and userland
|
||||
* \author Martin Stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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 _KERNEL__INTERFACE_SUPPORT_H_
|
||||
#define _KERNEL__INTERFACE_SUPPORT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
typedef Genode::uint64_t Call_arg;
|
||||
typedef Genode::uint64_t Call_ret;
|
||||
|
||||
/**
|
||||
* Registers that are provided by a kernel thread-object for user access
|
||||
*/
|
||||
struct Thread_reg_id
|
||||
{
|
||||
enum {
|
||||
SP = 13, /* XXX numbers are arbitrary, taken from ARM version */
|
||||
IP = 15,
|
||||
FAULT_TLB = 18,
|
||||
FAULT_ADDR = 19,
|
||||
FAULT_WRITES = 20,
|
||||
FAULT_SIGNAL = 21,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Events that are provided by a kernel thread-object for user handling
|
||||
*/
|
||||
struct Thread_event_id
|
||||
{
|
||||
enum { FAULT = 0 };
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _KERNEL__INTERFACE_SUPPORT_H_ */
|
||||
|
19
repos/base-hw/lib/mk/x86/core.inc
Normal file
19
repos/base-hw/lib/mk/x86/core.inc
Normal file
@ -0,0 +1,19 @@
|
||||
#
|
||||
# \brief Build config for Genodes core process
|
||||
# \author Stefan Kalkowski
|
||||
# \author Martin Stein
|
||||
# \date 2012-10-04
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/x86
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += platform_services.cc
|
||||
SRC_CC += spec/x86/platform_support.cc
|
||||
SRC_CC += spec/x86/kernel/thread.cc
|
||||
SRC_CC += spec/x86/kernel/cpu.cc
|
||||
SRC_CC += kernel/vm_thread.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/core.inc
|
3
repos/base-hw/lib/mk/x86_64/base-common.mk
Normal file
3
repos/base-hw/lib/mk/x86_64/base-common.mk
Normal file
@ -0,0 +1,3 @@
|
||||
include $(REP_DIR)/lib/mk/base-common.inc
|
||||
|
||||
vpath kernel/interface.cc $(REP_DIR)/src/base/x86_64
|
20
repos/base-hw/lib/mk/x86_64/core.mk
Normal file
20
repos/base-hw/lib/mk/x86_64/core.mk
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# \brief Build config for Genodes core process
|
||||
# \author Stefan Kalkowski
|
||||
# \author Martin Stein
|
||||
# \date 2012-10-04
|
||||
#
|
||||
|
||||
# add include paths
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/x86_64
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += spec/x86_64/mode_transition.s
|
||||
SRC_S += spec/x86_64/kernel/crt0.s
|
||||
SRC_S += spec/x86_64/crt0.s
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += spec/x86_64/kernel/thread_base.cc
|
||||
|
||||
# include less specific configuration
|
||||
include $(REP_DIR)/lib/mk/x86/core.inc
|
18
repos/base-hw/mk/spec-hw_x86_64.mk
Normal file
18
repos/base-hw/mk/spec-hw_x86_64.mk
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# \brief Offer build configurations that are specific to base-hw and x86_64
|
||||
# \author Martin Stein
|
||||
# \date 2011-12-20
|
||||
#
|
||||
|
||||
# denote wich specs are also fullfilled by this spec
|
||||
SPECS += hw x86_64
|
||||
|
||||
# configure multiprocessor mode
|
||||
NR_OF_CPUS = 1
|
||||
|
||||
# set address where to link text segment at
|
||||
LD_TEXT_ADDR ?= 0x200000
|
||||
|
||||
# include implied specs
|
||||
include $(call select_from_repositories,mk/spec-hw.mk)
|
||||
include $(call select_from_repositories,mk/spec-x86_64.mk)
|
85
repos/base-hw/src/base/x86_64/kernel/interface.cc
Normal file
85
repos/base-hw/src/base/x86_64/kernel/interface.cc
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief Interface between kernel and userland
|
||||
* \author Martin Stein
|
||||
* \date 2011-11-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <kernel/interface.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
/******************
|
||||
** Kernel calls **
|
||||
******************/
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0)
|
||||
{
|
||||
PDBG("syscall binding not implemented");
|
||||
for (;;);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1)
|
||||
{
|
||||
PDBG("syscall binding not implemented");
|
||||
for (;;);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1,
|
||||
Call_arg arg_2)
|
||||
{
|
||||
PDBG("syscall binding not implemented");
|
||||
for (;;);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1,
|
||||
Call_arg arg_2,
|
||||
Call_arg arg_3)
|
||||
{
|
||||
PDBG("syscall binding not implemented");
|
||||
for (;;);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1,
|
||||
Call_arg arg_2,
|
||||
Call_arg arg_3,
|
||||
Call_arg arg_4)
|
||||
{
|
||||
PDBG("syscall binding not implemented");
|
||||
for (;;);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Call_ret Kernel::call(Call_arg arg_0,
|
||||
Call_arg arg_1,
|
||||
Call_arg arg_2,
|
||||
Call_arg arg_3,
|
||||
Call_arg arg_4,
|
||||
Call_arg arg_5)
|
||||
{
|
||||
PDBG("syscall binding not implemented");
|
||||
for (;;);
|
||||
return 0;
|
||||
}
|
233
repos/base-hw/src/core/include/spec/x86/cpu.h
Normal file
233
repos/base-hw/src/core/include/spec/x86/cpu.h
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* \brief CPU driver for core
|
||||
* \author Martin stein
|
||||
* \date 2011-11-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2012 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 _CPU_H_
|
||||
#define _CPU_H_
|
||||
|
||||
#include <util/register.h>
|
||||
#include <kernel/interface_support.h>
|
||||
#include <cpu/cpu_state.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Part of CPU state that is not switched on every mode transition
|
||||
*/
|
||||
class Cpu_lazy_state { };
|
||||
|
||||
/**
|
||||
* CPU driver for core
|
||||
*/
|
||||
class Cpu;
|
||||
}
|
||||
|
||||
namespace Kernel { using Genode::Cpu_lazy_state; }
|
||||
|
||||
class Genode::Cpu
|
||||
{
|
||||
public:
|
||||
|
||||
static constexpr addr_t exception_entry = 0x0; /* XXX */
|
||||
static constexpr addr_t mtc_size = 1 << 13;
|
||||
|
||||
/**
|
||||
* Extend basic CPU state by members relevant for 'base-hw' only
|
||||
*/
|
||||
struct Context : Cpu_state
|
||||
{
|
||||
/**
|
||||
* Return base of assigned translation table
|
||||
*/
|
||||
addr_t translation_table() const { return 0UL; }
|
||||
|
||||
/**
|
||||
* Assign translation-table base 'table'
|
||||
*/
|
||||
void translation_table(addr_t const table) { }
|
||||
|
||||
/**
|
||||
* Assign protection domain
|
||||
*/
|
||||
void protection_domain(unsigned const id) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* An usermode execution state
|
||||
*/
|
||||
struct User_context : Context
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
User_context();
|
||||
|
||||
/**
|
||||
* Support for kernel calls
|
||||
*/
|
||||
void user_arg_0(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_1(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_2(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_3(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_4(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_5(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_6(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
void user_arg_7(Kernel::Call_arg const arg) { /* XXX */ }
|
||||
Kernel::Call_arg user_arg_0() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_1() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_2() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_3() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_4() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_5() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_6() const { return 0UL; }
|
||||
Kernel::Call_arg user_arg_7() const { return 0UL; }
|
||||
|
||||
/**
|
||||
* Initialize thread context
|
||||
*
|
||||
* \param table physical base of appropriate translation table
|
||||
* \param pd_id kernel name of appropriate protection domain
|
||||
*/
|
||||
void init_thread(addr_t const table, unsigned const pd_id)
|
||||
{
|
||||
protection_domain(pd_id);
|
||||
translation_table(table);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if current execution context is running in user mode
|
||||
*/
|
||||
static bool is_user()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate all entries of all instruction caches
|
||||
*/
|
||||
__attribute__((always_inline)) static void invalidate_instr_caches() { }
|
||||
|
||||
/**
|
||||
* Flush all entries of all data caches
|
||||
*/
|
||||
inline static void flush_data_caches() { }
|
||||
|
||||
/**
|
||||
* Invalidate all entries of all data caches
|
||||
*/
|
||||
inline static void invalidate_data_caches() { }
|
||||
|
||||
/**
|
||||
* Flush all caches
|
||||
*/
|
||||
static void flush_caches()
|
||||
{
|
||||
flush_data_caches();
|
||||
invalidate_instr_caches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate all TLB entries of the address space named 'pid'
|
||||
*/
|
||||
static void flush_tlb_by_pid(unsigned const pid)
|
||||
{
|
||||
flush_caches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate all TLB entries
|
||||
*/
|
||||
static void flush_tlb()
|
||||
{
|
||||
flush_caches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush data-cache entries for virtual region ['base', 'base + size')
|
||||
*/
|
||||
static void
|
||||
flush_data_caches_by_virt_region(addr_t base, size_t const size)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Bin instr.-cache entries for virtual region ['base', 'base + size')
|
||||
*/
|
||||
static void
|
||||
invalidate_instr_caches_by_virt_region(addr_t base, size_t const size)
|
||||
{ }
|
||||
|
||||
static void inval_branch_predicts() { };
|
||||
|
||||
/**
|
||||
* Switch to the virtual mode in kernel
|
||||
*
|
||||
* \param table base of targeted translation table
|
||||
* \param process_id process ID of the kernel address-space
|
||||
*/
|
||||
static void
|
||||
init_virt_kernel(addr_t const table, unsigned const process_id)
|
||||
{ }
|
||||
|
||||
inline static void finish_init_phys_kernel()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Configure this module appropriately for the first kernel run
|
||||
*/
|
||||
static void init_phys_kernel()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Finish all previous data transfers
|
||||
*/
|
||||
static void data_synchronization_barrier()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Enable secondary CPUs with instr. pointer 'ip'
|
||||
*/
|
||||
static void start_secondary_cpus(void * const ip)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Wait for the next interrupt as cheap as possible
|
||||
*/
|
||||
static void wait_for_interrupt() { }
|
||||
|
||||
/**
|
||||
* Return wether to retry an undefined user instruction after this call
|
||||
*/
|
||||
bool retry_undefined_instr(Cpu_lazy_state *) { return false; }
|
||||
|
||||
/**
|
||||
* Return kernel name of the executing CPU
|
||||
*/
|
||||
static unsigned executing_id() { return 0; }
|
||||
|
||||
/**
|
||||
* Return kernel name of the primary CPU
|
||||
*/
|
||||
static unsigned primary_id() { return 0; }
|
||||
|
||||
/*************
|
||||
** Dummies **
|
||||
*************/
|
||||
|
||||
static void tlb_insertions() { inval_branch_predicts(); }
|
||||
static void translation_added(addr_t, size_t) { }
|
||||
static void prepare_proceeding(Cpu_lazy_state *, Cpu_lazy_state *) { }
|
||||
|
||||
};
|
||||
|
||||
#endif /* _CPU_H_ */
|
46
repos/base-hw/src/core/include/spec/x86/kernel/thread_base.h
Normal file
46
repos/base-hw/src/core/include/spec/x86/kernel/thread_base.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Hardware specific base of kernel thread-objects
|
||||
* \author Martin Stein
|
||||
* \date 2013-11-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _KERNEL__THREAD_BASE_H_
|
||||
#define _KERNEL__THREAD_BASE_H_
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/thread_event.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* Hardware specific base of kernel thread-objects
|
||||
*/
|
||||
class Thread_base;
|
||||
}
|
||||
|
||||
class Kernel::Thread_base
|
||||
{
|
||||
protected:
|
||||
|
||||
Thread_event _fault;
|
||||
addr_t _fault_pd;
|
||||
addr_t _fault_addr;
|
||||
addr_t _fault_writes;
|
||||
addr_t _fault_signal;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param t generic part of kernel thread-object
|
||||
*/
|
||||
Thread_base(Thread * const t);
|
||||
};
|
||||
|
||||
#endif /* _KERNEL__THREAD_BASE_H_ */
|
25
repos/base-hw/src/core/include/spec/x86/kernel/vm_state.h
Normal file
25
repos/base-hw/src/core/include/spec/x86/kernel/vm_state.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* \brief CPU context of a virtual machine
|
||||
* \author Martin Stein
|
||||
* \date 2013-10-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _KERNEL__VM_STATE_H_
|
||||
#define _KERNEL__VM_STATE_H_
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
/**
|
||||
* Dummy
|
||||
*/
|
||||
struct Vm_state { };
|
||||
}
|
||||
|
||||
#endif /* _KERNEL__VM_STATE_H_ */
|
16
repos/base-hw/src/core/include/spec/x86/macros.s
Normal file
16
repos/base-hw/src/core/include/spec/x86/macros.s
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* \brief Macros that are used by multiple assembly files
|
||||
* \author Martin Stein
|
||||
* \date 2014-01-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 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 "spec/x86/macros_support.s"
|
||||
|
20
repos/base-hw/src/core/include/spec/x86/macros_support.s
Normal file
20
repos/base-hw/src/core/include/spec/x86/macros_support.s
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* \brief Macros that are used by multiple assembly files
|
||||
* \author Martin Stein
|
||||
* \date 2014-01-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
/***************************************************
|
||||
** Constant values that are pretty commonly used **
|
||||
***************************************************/
|
||||
|
||||
/* alignment constraints */
|
||||
.set MIN_PAGE_SIZE_LOG2, 12
|
||||
.set DATA_ACCESS_ALIGNM_LOG2, 2
|
67
repos/base-hw/src/core/include/spec/x86/pic.h
Normal file
67
repos/base-hw/src/core/include/spec/x86/pic.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* \brief Programmable interrupt controller 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 _PIC_H_
|
||||
#define _PIC_H_
|
||||
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Programmable interrupt controller for core
|
||||
*/
|
||||
class Pic;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Pic
|
||||
{
|
||||
public:
|
||||
|
||||
enum {
|
||||
/*
|
||||
* FIXME: dummy ipi value on non-SMP platform, should be removed
|
||||
* when SMP is an aspect of CPUs only compiled where necessary
|
||||
*/
|
||||
IPI = 255,
|
||||
NR_OF_IRQ = 256,
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Pic() { }
|
||||
|
||||
void init_cpu_local() { }
|
||||
|
||||
bool take_request(unsigned &irq) { return false; }
|
||||
|
||||
void finish_request() { }
|
||||
|
||||
void mask() { }
|
||||
|
||||
void unmask(unsigned const i, unsigned) { }
|
||||
|
||||
void mask(unsigned const i) { }
|
||||
|
||||
/*
|
||||
* Dummies
|
||||
*/
|
||||
|
||||
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
||||
void trigger_ip_interrupt(unsigned) { }
|
||||
};
|
||||
|
||||
namespace Kernel { class Pic : public Genode::Pic { }; }
|
||||
|
||||
#endif /* _PIC_H_ */
|
148
repos/base-hw/src/core/include/spec/x86/serial.h
Normal file
148
repos/base-hw/src/core/include/spec/x86/serial.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* \brief Serial output driver for core
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-10-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _SERIAL_H_
|
||||
#define _SERIAL_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/**
|
||||
* Read byte from I/O port
|
||||
*/
|
||||
inline Genode::uint8_t inb(Genode::uint16_t port)
|
||||
{
|
||||
Genode::uint8_t res;
|
||||
asm volatile ("inb %%dx, %0" :"=a"(res) :"Nd"(port));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write byte to I/O port
|
||||
*/
|
||||
inline void outb(Genode::uint16_t port, Genode::uint8_t val)
|
||||
{
|
||||
asm volatile ("outb %b0, %w1" : : "a" (val), "Nd" (port));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Definitions of PC serial ports
|
||||
*/
|
||||
enum {
|
||||
COMPORT_DATA_OFFSET = 0,
|
||||
COMPORT_STATUS_OFFSET = 5,
|
||||
|
||||
STATUS_THR_EMPTY = 0x20, /* transmitter hold register empty */
|
||||
STATUS_DHR_EMPTY = 0x40, /* data hold register empty
|
||||
- data completely sent */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize serial port
|
||||
*
|
||||
* Based on 'init_serial' of L4ka::Pistachio's 'kdb/platform/pc99/io.cc'
|
||||
*/
|
||||
static void init_comport(Genode::uint16_t port, unsigned baud)
|
||||
{
|
||||
if (!port)
|
||||
return;
|
||||
|
||||
const unsigned
|
||||
IER = port + 1,
|
||||
EIR = port + 2,
|
||||
LCR = port + 3,
|
||||
MCR = port + 4,
|
||||
LSR = port + 5,
|
||||
MSR = port + 6,
|
||||
DLLO = port + 0,
|
||||
DLHI = port + 1;
|
||||
|
||||
outb(LCR, 0x80); /* select bank 1 */
|
||||
// for (volatile int i = 10000000; i--; );
|
||||
outb(DLLO, (115200/baud) >> 0);
|
||||
outb(DLHI, (115200/baud) >> 8);
|
||||
outb(LCR, 0x03); /* set 8,N,1 */
|
||||
outb(IER, 0x00); /* disable interrupts */
|
||||
outb(EIR, 0x07); /* enable FIFOs */
|
||||
outb(MCR, 0x0b); /* force data terminal ready */
|
||||
outb(IER, 0x01); /* enable RX interrupts */
|
||||
inb(IER);
|
||||
inb(EIR);
|
||||
inb(LCR);
|
||||
inb(MCR);
|
||||
inb(LSR);
|
||||
inb(MSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output character to serial port
|
||||
*/
|
||||
inline void serial_out_char(Genode::uint16_t comport, Genode::uint8_t c)
|
||||
{
|
||||
/* wait until serial port is ready */
|
||||
Genode::uint8_t ready = STATUS_THR_EMPTY;
|
||||
while ((inb(comport + COMPORT_STATUS_OFFSET) & ready) != ready);
|
||||
|
||||
/* output character */
|
||||
outb(comport + COMPORT_DATA_OFFSET, c);
|
||||
}
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Serial output driver for core
|
||||
*/
|
||||
class Serial
|
||||
{
|
||||
private:
|
||||
|
||||
uint16_t _comport;
|
||||
|
||||
public:
|
||||
|
||||
void put_char(char c)
|
||||
{
|
||||
if (!_comport)
|
||||
return;
|
||||
|
||||
if (c == '\n')
|
||||
serial_out_char(_comport, '\r');
|
||||
serial_out_char(_comport, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* XXX: The 'baud_rate' argument is ignored for now.
|
||||
*/
|
||||
Serial(unsigned) : _comport(0x3f8)
|
||||
{
|
||||
init_comport(_comport, 115200);
|
||||
}
|
||||
|
||||
Serial(const char *s) : _comport(0x3f8)
|
||||
{
|
||||
init_comport(_comport, 115200);
|
||||
|
||||
while (*s)
|
||||
put_char(*s++);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _SERIAL_H_ */
|
63
repos/base-hw/src/core/include/spec/x86/timer.h
Normal file
63
repos/base-hw/src/core/include/spec/x86/timer.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* \brief Timer 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 _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* Timer driver for core
|
||||
*
|
||||
* Timer channel 0 apparently doesn't work on the RPI, so we use channel 1
|
||||
*/
|
||||
class Timer;
|
||||
}
|
||||
|
||||
class Genode::Timer
|
||||
{
|
||||
public:
|
||||
|
||||
Timer() { }
|
||||
|
||||
static unsigned interrupt_id(int)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void start_one_shot(uint32_t const tics, unsigned)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
static uint32_t ms_to_tics(unsigned const ms)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned value(unsigned)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
namespace Kernel { class Timer : public Genode::Timer { }; }
|
||||
|
||||
#endif /* _TIMER_H_ */
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* \brief x86_64 translation table definitions for core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2012-02-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _TRANSLATION_TABLE_H_
|
||||
#define _TRANSLATION_TABLE_H_
|
||||
|
||||
#include <page_flags.h>
|
||||
#include <assert.h>
|
||||
#include <page_slab.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* First level translation table
|
||||
*/
|
||||
class Translation_table;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Translation_table
|
||||
{
|
||||
public:
|
||||
|
||||
enum {
|
||||
ALIGNM_LOG2 = 12,
|
||||
MIN_PAGE_SIZE_LOG2 = 12,
|
||||
MAX_COSTS_PER_TRANSLATION = 4*4096
|
||||
};
|
||||
|
||||
void * operator new (size_t, void * p) { return p; }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Translation_table() { }
|
||||
|
||||
/**
|
||||
* Maximum virtual offset that can be translated by this table
|
||||
*/
|
||||
static addr_t max_virt_offset()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert translations into this table
|
||||
*
|
||||
* \param vo offset of virt. transl. region in virt. table region
|
||||
* \param pa base of physical backing store
|
||||
* \param size size of translated region
|
||||
* \param f mapping flags
|
||||
* \param s second level page slab allocator
|
||||
*/
|
||||
void insert_translation(addr_t vo, addr_t pa, size_t size,
|
||||
Page_flags const & f, Page_slab * const s)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove translations that overlap with a given virtual region
|
||||
*
|
||||
* \param vo region offset within the tables virtual region
|
||||
* \param size region size
|
||||
* \param slab second level page slab allocator
|
||||
*/
|
||||
void remove_translation(addr_t vo, size_t size, Page_slab * slab)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _TRANSLATION_TABLE_H_ */
|
26
repos/base-hw/src/core/spec/x86/kernel/cpu.cc
Normal file
26
repos/base-hw/src/core/spec/x86/kernel/cpu.cc
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Class for kernel data that is needed to manage a specific CPU
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 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 <kernel/cpu.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::min, 0) {
|
||||
PDBG("not implemented"); }
|
||||
|
||||
|
||||
void Cpu_idle::exception(unsigned const cpu) {
|
||||
PDBG("not implemented"); }
|
30
repos/base-hw/src/core/spec/x86/kernel/thread.cc
Normal file
30
repos/base-hw/src/core/spec/x86/kernel/thread.cc
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Kernel backend for execution contexts in userland
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-01-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 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 <kernel/thread.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
Thread::Thread(unsigned const priority, unsigned const quota,
|
||||
char const * const label)
|
||||
:
|
||||
Thread_base(this), Cpu_job(priority, quota), _state(AWAITS_START), _pd(0),
|
||||
_utcb_phys(0), _signal_receiver(0), _label(label)
|
||||
{ PDBG("not implemented"); }
|
||||
|
||||
|
||||
void Thread::exception(unsigned const cpu) {
|
||||
PDBG("not implemented"); }
|
22
repos/base-hw/src/core/spec/x86/kernel/vm.cc
Normal file
22
repos/base-hw/src/core/spec/x86/kernel/vm.cc
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* \brief Kernel backend for virtual machines
|
||||
* \author Martin Stein
|
||||
* \date 2013-10-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <kernel/vm.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
void Vm::exception(unsigned const cpu) {
|
||||
PDBG("not implemented"); }
|
||||
|
50
repos/base-hw/src/core/spec/x86/platform_support.cc
Normal file
50
repos/base-hw/src/core/spec/x86/platform_support.cc
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* \brief Platform implementations specific for base-hw and Raspberry Pi
|
||||
* \author Norman Feske
|
||||
* \date 2013-04-05
|
||||
*
|
||||
* XXX dimension allocators according to the available physical memory
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <cpu.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Native_region * Platform::_ram_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
{ 2*1024*1024, 1024*1024*254 }
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Native_region * Platform::_core_only_mmio_regions(unsigned const i)
|
||||
{
|
||||
static Native_region _regions[] =
|
||||
{
|
||||
};
|
||||
return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0;
|
||||
}
|
||||
|
||||
|
||||
Cpu::User_context::User_context() { }
|
45
repos/base-hw/src/core/spec/x86_64/crt0.s
Normal file
45
repos/base-hw/src/core/spec/x86_64/crt0.s
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* \brief Startup code for Genode 64Bit applications
|
||||
* \author Sebastian Sumpf
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.section ".text"
|
||||
|
||||
/* program entry-point */
|
||||
.global _core_start
|
||||
_core_start:
|
||||
|
||||
/* initialize GLOBAL OFFSET TABLE */
|
||||
leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
|
||||
|
||||
/* create proper environment for the main thread */
|
||||
call init_main_thread
|
||||
|
||||
/* apply environment that was created by init_main_thread */
|
||||
movq init_main_thread_result@GOTPCREL(%rip), %rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
/* clear the base pointer in order that stack backtraces will work */
|
||||
xorq %rbp, %rbp
|
||||
|
||||
/*
|
||||
* We jump into initial C code instead of calling it as it should never
|
||||
* return on the one hand and because the alignment of the stack pointer
|
||||
* that init_main_thread returned expects a jump at the other hand. The
|
||||
* latter matters because GCC expects the initial stack pointer to be
|
||||
* aligned to 16 byte for at least the handling of floating points.
|
||||
*/
|
||||
jmp _main
|
66
repos/base-hw/src/core/spec/x86_64/kernel/crt0.s
Normal file
66
repos/base-hw/src/core/spec/x86_64/kernel/crt0.s
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* \brief Startup code for core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-10-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
/* magic multi-boot header to make GRUB happy */
|
||||
.long 0x1badb002
|
||||
.long 0x0
|
||||
.long 0xe4524ffe
|
||||
|
||||
/**********************************
|
||||
** Startup code for primary CPU **
|
||||
**********************************/
|
||||
|
||||
.code32
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
leaq _stack_high@GOTPCREL(%rip),%rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
/* uniprocessor kernel-initialization which activates multiprocessor */
|
||||
call init_kernel_up
|
||||
|
||||
/*********************************************
|
||||
** Startup code that is common to all CPUs **
|
||||
*********************************************/
|
||||
|
||||
.global _start_secondary_cpus
|
||||
_start_secondary_cpus:
|
||||
|
||||
/* do multiprocessor kernel-initialization */
|
||||
call init_kernel_mp
|
||||
|
||||
/* call the kernel main-routine */
|
||||
call kernel
|
||||
|
||||
/* catch erroneous return of the kernel main-routine */
|
||||
1: jmp 1b
|
||||
|
||||
|
||||
/*********************************
|
||||
** .bss (non-initialized data) **
|
||||
*********************************/
|
||||
|
||||
.bss
|
||||
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 8
|
||||
.space 32 * 1024
|
||||
_stack_high:
|
83
repos/base-hw/src/core/spec/x86_64/kernel/thread_base.cc
Normal file
83
repos/base-hw/src/core/spec/x86_64/kernel/thread_base.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* \brief CPU specific implementations of core
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-11-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.
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
/*************************
|
||||
** Kernel::Thread_base **
|
||||
*************************/
|
||||
|
||||
Thread_base::Thread_base(Thread * const t)
|
||||
:
|
||||
_fault(t),
|
||||
_fault_pd(0),
|
||||
_fault_addr(0),
|
||||
_fault_writes(0),
|
||||
_fault_signal(0)
|
||||
{ }
|
||||
|
||||
|
||||
/********************
|
||||
** Kernel::Thread **
|
||||
********************/
|
||||
|
||||
addr_t Thread::* Thread::_reg(addr_t const id) const
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
|
||||
Thread_event Thread::* Thread::_event(unsigned const id) const
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void Thread::_mmu_exception()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** Kernel::Cpu_context **
|
||||
*************************/
|
||||
|
||||
void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table)
|
||||
{ }
|
||||
|
||||
|
||||
/*************************
|
||||
** CPU-state utilities **
|
||||
*************************/
|
||||
|
||||
typedef Thread_reg_id Reg_id;
|
||||
|
||||
static addr_t const _cpu_state_regs[] = { };
|
||||
|
||||
addr_t const * cpu_state_regs() { return _cpu_state_regs; }
|
||||
|
||||
|
||||
size_t cpu_state_regs_length()
|
||||
{
|
||||
return sizeof(_cpu_state_regs)/sizeof(_cpu_state_regs[0]);
|
||||
}
|
68
repos/base-hw/src/core/spec/x86_64/mode_transition.s
Normal file
68
repos/base-hw/src/core/spec/x86_64/mode_transition.s
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* \brief Transition between kernel/userland, and secure/non-secure world
|
||||
* \author Martin Stein
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2011-11-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
|
||||
.include "macros.s"
|
||||
|
||||
.section .text
|
||||
|
||||
/*
|
||||
* Page aligned base of mode transition code.
|
||||
*
|
||||
* This position independent code switches between a kernel context and a
|
||||
* user context and thereby between their address spaces. Due to the latter
|
||||
* it must be mapped executable to the same region in every address space.
|
||||
* To enable such switching, the kernel context must be stored within this
|
||||
* region, thus one should map it solely accessable for privileged modes.
|
||||
*/
|
||||
.p2align MIN_PAGE_SIZE_LOG2
|
||||
.global _mt_begin
|
||||
_mt_begin:
|
||||
|
||||
/* space for a copy of the kernel context */
|
||||
.p2align 2
|
||||
.global _mt_master_context_begin
|
||||
_mt_master_context_begin:
|
||||
|
||||
/* space must be at least as large as 'Cpu_state' */
|
||||
.space 32*4
|
||||
|
||||
.global _mt_master_context_end
|
||||
_mt_master_context_end:
|
||||
|
||||
/* space for a client context-pointer per CPU */
|
||||
.p2align 2
|
||||
.global _mt_client_context_ptr
|
||||
_mt_client_context_ptr:
|
||||
|
||||
/* a globally mapped buffer per CPU */
|
||||
.p2align 2
|
||||
.global _mt_buffer
|
||||
_mt_buffer:
|
||||
|
||||
/*
|
||||
* On user exceptions the CPU has to jump to one of the following
|
||||
* seven entry vectors to switch to a kernel context.
|
||||
*/
|
||||
.global _mt_kernel_entry_pic
|
||||
_mt_kernel_entry_pic:
|
||||
1: jmp 1b
|
||||
|
||||
.global _mt_user_entry_pic
|
||||
_mt_user_entry_pic:
|
||||
1: jmp 1b
|
||||
|
||||
/* end of the mode transition code */
|
||||
.global _mt_end
|
||||
_mt_end:
|
||||
1: jmp 1b
|
@ -139,9 +139,14 @@ proc run_boot_dir {binaries {core_type core}} {
|
||||
|
||||
# offer ELF image
|
||||
set elf_img "[run_dir]/image.elf"
|
||||
#exec cp -L bin/$core_bin $elf_img
|
||||
exec [cross_dev_prefix]objcopy -O elf32-i386 bin/$core_bin $elf_img
|
||||
#exec [cross_dev_prefix]strip $elf_img
|
||||
if {[have_spec "x86_64"]} {
|
||||
# as startup is done in 32 bit mode, GRUB expects a 32 bit image
|
||||
exec [cross_dev_prefix]objcopy -O elf32-i386 bin/$core_bin $elf_img
|
||||
}
|
||||
if {[expr [have_spec "arm"] || [have_spec "x86_32"]]} {
|
||||
exec cp -L bin/$core_bin $elf_img
|
||||
}
|
||||
exec [cross_dev_prefix]strip $elf_img
|
||||
|
||||
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||
#
|
||||
|
Loading…
x
Reference in New Issue
Block a user