mirror of https://github.com/l4ka/pistachio.git
Add an architecture-independent tracebuffer facility (works for x86
and ppc) for both kernel and user level.
This commit is contained in:
parent
c53bc2e832
commit
2e480db6e9
|
@ -40,8 +40,6 @@
|
||||||
#include INC_API(tcb.h)
|
#include INC_API(tcb.h)
|
||||||
#include INC_GLUE(schedule.h)
|
#include INC_GLUE(schedule.h)
|
||||||
|
|
||||||
FEATURESTRING ("tracebuffer");
|
|
||||||
|
|
||||||
#define TB_WRAP 80
|
#define TB_WRAP 80
|
||||||
extern void list_tp_choices (void);
|
extern void list_tp_choices (void);
|
||||||
|
|
||||||
|
@ -273,11 +271,11 @@ public:
|
||||||
{ return get_tracebuffer()->config; }
|
{ return get_tracebuffer()->config; }
|
||||||
|
|
||||||
|
|
||||||
word_t get_tbuf_size()
|
word_t get_tbuf_max()
|
||||||
{ return (TRACEBUFFER_SIZE / sizeof (tracerecord_t)) - 1; }
|
{ return get_tracebuffer()->max; }
|
||||||
|
|
||||||
word_t get_tbuf_current()
|
word_t get_tbuf_current()
|
||||||
{ return get_tracebuffer()->current / sizeof (tracerecord_t); }
|
{ return get_tracebuffer()->current; }
|
||||||
|
|
||||||
void reset_tbuf()
|
void reset_tbuf()
|
||||||
{
|
{
|
||||||
|
@ -606,7 +604,7 @@ tbuf_handler_t tbuf_handler;
|
||||||
|
|
||||||
void tbuf_dump (word_t count, word_t usec, word_t tp_id, word_t cpumask)
|
void tbuf_dump (word_t count, word_t usec, word_t tp_id, word_t cpumask)
|
||||||
{
|
{
|
||||||
word_t start, end, size;
|
word_t start, end, max;
|
||||||
word_t old_tp_id[tbuf_handler_t::max_filters];
|
word_t old_tp_id[tbuf_handler_t::max_filters];
|
||||||
word_t old_cpumask = tbuf_handler.get_cpumask();
|
word_t old_cpumask = tbuf_handler.get_cpumask();
|
||||||
word_t old_typemask = tbuf_handler.get_typemask();
|
word_t old_typemask = tbuf_handler.get_typemask();
|
||||||
|
@ -624,7 +622,7 @@ void tbuf_dump (word_t count, word_t usec, word_t tp_id, word_t cpumask)
|
||||||
}
|
}
|
||||||
tbuf_handler.set_id(0, tp_id);
|
tbuf_handler.set_id(0, tp_id);
|
||||||
|
|
||||||
size = tbuf_handler.get_tbuf_size();
|
max = tbuf_handler.get_tbuf_max();
|
||||||
end = tbuf_handler.get_tbuf_current();
|
end = tbuf_handler.get_tbuf_current();
|
||||||
|
|
||||||
if (usec)
|
if (usec)
|
||||||
|
@ -633,15 +631,15 @@ void tbuf_dump (word_t count, word_t usec, word_t tp_id, word_t cpumask)
|
||||||
ASSERT (pdesc);
|
ASSERT (pdesc);
|
||||||
word_t freq = pdesc->internal_freq + 1;
|
word_t freq = pdesc->internal_freq + 1;
|
||||||
u64_t tsc = get_cpu_cycles() - ((u64_t) usec * (u64_t) (freq / 1000));
|
u64_t tsc = get_cpu_cycles() - ((u64_t) usec * (u64_t) (freq / 1000));
|
||||||
count = size;
|
count = max;
|
||||||
tbuf_handler.set_tsc(tsc);
|
tbuf_handler.set_tsc(tsc);
|
||||||
}
|
}
|
||||||
else if (count == 0)
|
else if (count == 0)
|
||||||
count = size;
|
count = max;
|
||||||
|
|
||||||
start = tbuf_handler.find_tbuf_start(end, count, size);
|
start = tbuf_handler.find_tbuf_start(end, count, max);
|
||||||
count = (end >= start) ? end - start : end + size - start;
|
count = (end >= start) ? end - start : end + max - start;
|
||||||
tbuf_handler.dump_tbuf(start, count, size, false);
|
tbuf_handler.dump_tbuf(start, count, max, false);
|
||||||
|
|
||||||
if (tp_id)
|
if (tp_id)
|
||||||
{
|
{
|
||||||
|
@ -761,12 +759,12 @@ DECLARE_CMD (cmd_tb_dump, tracebuf, 'd', "dump", "Dump tracebuffer");
|
||||||
|
|
||||||
CMD (cmd_tb_dump, cg)
|
CMD (cmd_tb_dump, cg)
|
||||||
{
|
{
|
||||||
word_t start, end, size, count;
|
word_t start, end, max, count;
|
||||||
|
|
||||||
if (!tbuf_handler.is_tbuf_valid())
|
if (!tbuf_handler.is_tbuf_valid())
|
||||||
return CMD_NOQUIT;
|
return CMD_NOQUIT;
|
||||||
|
|
||||||
size = tbuf_handler.get_tbuf_size();
|
max = tbuf_handler.get_tbuf_max();
|
||||||
count = 32;
|
count = 32;
|
||||||
start = 0;
|
start = 0;
|
||||||
end = tbuf_handler.get_tbuf_current();
|
end = tbuf_handler.get_tbuf_current();
|
||||||
|
@ -774,26 +772,26 @@ CMD (cmd_tb_dump, cg)
|
||||||
switch (get_choice ("Dump tracebuffer", "All/Region/Top/Bottom", 'b'))
|
switch (get_choice ("Dump tracebuffer", "All/Region/Top/Bottom", 'b'))
|
||||||
{
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
count = size;
|
count = max;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
start = get_dec ("From record", 0);
|
start = get_dec ("From record", 0);
|
||||||
// Fall through
|
// Fall through
|
||||||
case 't':
|
case 't':
|
||||||
count = get_dec ("Record count", count);
|
count = get_dec ("Record count", count);
|
||||||
end = tbuf_handler.find_tbuf_end(start, count, size);
|
end = tbuf_handler.find_tbuf_end(start, count, max);
|
||||||
if (count > size) count = size;
|
if (count > max) count = max;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
default:
|
default:
|
||||||
count = get_dec ("Record count", count);
|
count = get_dec ("Record count", count);
|
||||||
if (count > size) count = size;
|
if (count > max) count = max;
|
||||||
start = tbuf_handler.find_tbuf_start(end, count, size);
|
start = tbuf_handler.find_tbuf_start(end, count, max);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = (end >= start) ? end - start : end + size - start;
|
count = (end >= start) ? end - start : end + max - start;
|
||||||
tbuf_handler.dump_tbuf(start, count, size);
|
tbuf_handler.dump_tbuf(start, count, max);
|
||||||
|
|
||||||
return CMD_NOQUIT;
|
return CMD_NOQUIT;
|
||||||
}
|
}
|
||||||
|
@ -809,18 +807,18 @@ DECLARE_CMD (cmd_tb_dump_def, root, 'Y', "tracebuffer dump",
|
||||||
|
|
||||||
CMD (cmd_tb_dump_def, cg)
|
CMD (cmd_tb_dump_def, cg)
|
||||||
{
|
{
|
||||||
word_t start, end, size, count;
|
word_t start, end, max, count;
|
||||||
|
|
||||||
if (!tbuf_handler.is_tbuf_valid())
|
if (!tbuf_handler.is_tbuf_valid())
|
||||||
return CMD_NOQUIT;
|
return CMD_NOQUIT;
|
||||||
|
|
||||||
|
|
||||||
size = tbuf_handler.get_tbuf_size();
|
max = tbuf_handler.get_tbuf_max();
|
||||||
count = 64;
|
count = 64;
|
||||||
end = tbuf_handler.get_tbuf_current();
|
end = tbuf_handler.get_tbuf_current();
|
||||||
start = tbuf_handler.find_tbuf_start(end, count, size);
|
start = tbuf_handler.find_tbuf_start(end, count, max);
|
||||||
count = (end >= start) ? end - start : end + size - start;
|
count = (end >= start) ? end - start : end + max - start;
|
||||||
tbuf_handler.dump_tbuf(start, count, size);
|
tbuf_handler.dump_tbuf(start, count, max);
|
||||||
|
|
||||||
return CMD_NOQUIT;
|
return CMD_NOQUIT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,8 +323,6 @@ void space_t::handle_pagefault(addr_t addr, addr_t ip, access_e access, bool ker
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SYS_SPACE_CONTROL (threadid_t space_tid, word_t control, fpage_t kip_area,
|
SYS_SPACE_CONTROL (threadid_t space_tid, word_t control, fpage_t kip_area,
|
||||||
fpage_t utcb_area, threadid_t redirector_tid)
|
fpage_t utcb_area, threadid_t redirector_tid)
|
||||||
{
|
{
|
||||||
|
@ -429,3 +427,4 @@ void space_t::free (void)
|
||||||
fp.set_rwx ();
|
fp.set_rwx ();
|
||||||
unmap_fpage (fp, true, true);
|
unmap_fpage (fp, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (C) 1999-2010, Karlsruhe University
|
* Copyright (C) 1999-2010, Karlsruhe University
|
||||||
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
||||||
*
|
*
|
||||||
* File path: src/arch/powerpc/page.h
|
* File path: arch/powerpc/page.h
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (C) 1999-2010, Karlsruhe University
|
* Copyright (C) 1999-2010, Karlsruhe University
|
||||||
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
||||||
*
|
*
|
||||||
* File path: src/arch/powerpc/softhvm.h
|
* File path: arch/powerpc/softhvm.h
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "msr.h"
|
#include "msr.h"
|
||||||
#include "swtlb.h"
|
#include "swtlb.h"
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
#define LAZY_TLB
|
#define LAZY_TLB
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include <tcb_layout.h>
|
#include <tcb_layout.h>
|
||||||
#include INC_ARCH(ppc_registers.h)
|
#include INC_ARCH(ppc_registers.h)
|
||||||
|
|
||||||
#define TRACEBUFFER_SIZE ( 1 * 1024 * 1024)
|
#define TRACEBUFFER_SIZE ( 1024 * 1024)
|
||||||
INLINE void tracerecord_t::store_arch(const traceconfig_t config)
|
INLINE void tracerecord_t::store_arch(const traceconfig_t config)
|
||||||
{
|
{
|
||||||
tsc = ppc_get_timebase();
|
tsc = ppc_get_timebase();
|
||||||
|
|
|
@ -34,13 +34,6 @@
|
||||||
#include INC_ARCH(cpu.h)
|
#include INC_ARCH(cpu.h)
|
||||||
#include <tcb_layout.h>
|
#include <tcb_layout.h>
|
||||||
|
|
||||||
#if defined(CONFIG_IS_32BIT)
|
|
||||||
#define TRACEBUFFER_PGENTSZ pgent_t::size_4m
|
|
||||||
#else
|
|
||||||
#define TRACEBUFFER_PGENTSZ pgent_t::size_2m
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_TBUF_PERFMON_ENERGY)
|
#if defined(CONFIG_TBUF_PERFMON_ENERGY)
|
||||||
#define TRACEBUFFER_SIZE (32 * 1024 * 1024)
|
#define TRACEBUFFER_SIZE (32 * 1024 * 1024)
|
||||||
#else
|
#else
|
||||||
|
@ -114,7 +107,7 @@ INLINE void tracerecord_t::store_arch(const traceconfig_t config)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pmc0 = (word_t) x86_rdpmc(12);
|
pmc0 = (word_t) x86_rdpmc(12);
|
||||||
pmc1 = (word_t) x86_rdpmc(2);
|
pmc1 = (word_t) x86_rdpmc(14);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -144,5 +137,6 @@ INLINE void tracebuffer_t::initialize()
|
||||||
config.pmon_cpu = 1;
|
config.pmon_cpu = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
printf("sz %d rec %d max %d\n", TRACEBUFFER_SIZE, sizeof(tracerecord_t), max);
|
||||||
}
|
}
|
||||||
#endif /* !__ARCH__X86__TRACEBUFFER_H__ */
|
#endif /* !__ARCH__X86__TRACEBUFFER_H__ */
|
||||||
|
|
|
@ -130,6 +130,7 @@ void kdebug_entry (void *);
|
||||||
# define printf(fmt, args...) do { } while (false)
|
# define printf(fmt, args...) do { } while (false)
|
||||||
# define enter_kdebug(x) do { } while (true)
|
# define enter_kdebug(x) do { } while (true)
|
||||||
# define UNIMPLEMENTED() do { } while (true)
|
# define UNIMPLEMENTED() do { } while (true)
|
||||||
|
# define UNTESTED() do { } while (true)
|
||||||
# define ASSERT(x) do { } while (false)
|
# define ASSERT(x) do { } while (false)
|
||||||
# define WARNING(fmt, args...) do { } while (false)
|
# define WARNING(fmt, args...) do { } while (false)
|
||||||
# define TRACE(x...) do { } while (false)
|
# define TRACE(x...) do { } while (false)
|
||||||
|
|
|
@ -133,8 +133,8 @@ SECTION(SEC_INIT) void dtree_remap( kernel_interface_page_t *kip )
|
||||||
|
|
||||||
dtree_t *dtreemapping;
|
dtree_t *dtreemapping;
|
||||||
paddr_t pdtree = (paddr_t) dtree;
|
paddr_t pdtree = (paddr_t) dtree;
|
||||||
printf("dtree %p %d\n", dtree, dtree_size);
|
//TRACEF("dtree %p %d\n", dtree, dtree_size);
|
||||||
addr_t page = get_kernel_space()->map_device( pdtree, dtree_size, pgent_t::cache_standard );
|
addr_t page = get_kernel_space()->map_device( pdtree, dtree_size, true, pgent_t::cache_standard );
|
||||||
dtreemapping = (dtree_t*)addr_offset(page, pdtree & (KERNEL_PAGE_SIZE - 1));
|
dtreemapping = (dtree_t*)addr_offset(page, pdtree & (KERNEL_PAGE_SIZE - 1));
|
||||||
|
|
||||||
if (!dtreemapping->is_valid())
|
if (!dtreemapping->is_valid())
|
||||||
|
@ -348,6 +348,7 @@ SECTION(SEC_INIT) static word_t init_bootmem()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Per-cpu init.
|
* Per-cpu init.
|
||||||
|
@ -371,16 +372,6 @@ static SECTION(SEC_INIT) void perfmon_init( void )
|
||||||
ppc_set_pmc4( 0 );
|
ppc_set_pmc4( 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(CONFIG_TRACEBUFFER)
|
|
||||||
tracebuffer_t * tracebuffer;
|
|
||||||
EXTERN_KMEM_GROUP (kmem_misc);
|
|
||||||
|
|
||||||
void SECTION(SEC_INIT) setup_tracebuffer (void)
|
|
||||||
{
|
|
||||||
tracebuffer = (tracebuffer_t *) kmem.alloc (kmem_misc, TRACEBUFFER_SIZE);
|
|
||||||
tracebuffer->initialize ();
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_TRACEBUFFER */
|
|
||||||
|
|
||||||
static SECTION(SEC_INIT) void timer_start( void )
|
static SECTION(SEC_INIT) void timer_start( void )
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ EXTERN_KMEM_GROUP(kmem_space);
|
||||||
//#define TRACE_TLB(x...) TRACEF(x)
|
//#define TRACE_TLB(x...) TRACEF(x)
|
||||||
#define TRACE_TLB(x...)
|
#define TRACE_TLB(x...)
|
||||||
|
|
||||||
|
word_t space_t::pinned_mapping;
|
||||||
// used by initialization code...
|
// used by initialization code...
|
||||||
word_t swtlb_high_water;
|
word_t swtlb_high_water;
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ void space_t::init(fpage_t utcb_area, fpage_t kip_area)
|
||||||
|
|
||||||
void SECTION(".init.memory") space_t::init_kernel_mappings()
|
void SECTION(".init.memory") space_t::init_kernel_mappings()
|
||||||
{
|
{
|
||||||
//this->pinned_mapping = PINNED_AREA_START;
|
this->pinned_mapping = PINNED_AREA_START;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,8 +247,7 @@ NOINLINE bool space_t::handle_tlb_miss( addr_t lookup_vaddr, addr_t install_vadd
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
addr_t space_t::map_device_pinned(paddr_t paddr, word_t size, bool kernel, word_t attrib)
|
||||||
addr_t space_t::map_device_pinned(paddr_t paddr, word_t size, word_t attrib)
|
|
||||||
{
|
{
|
||||||
word_t log2sz;
|
word_t log2sz;
|
||||||
word_t vaddr = pinned_mapping;
|
word_t vaddr = pinned_mapping;
|
||||||
|
@ -270,6 +270,8 @@ addr_t space_t::map_device_pinned(paddr_t paddr, word_t size, word_t attrib)
|
||||||
ppc_tlb2_t tlb2;
|
ppc_tlb2_t tlb2;
|
||||||
tlb2.init_device();
|
tlb2.init_device();
|
||||||
tlb2.set_kernel_perms(true, true, false);
|
tlb2.set_kernel_perms(true, true, false);
|
||||||
|
if (!kernel)
|
||||||
|
tlb2.set_user_perms(true, true, false);
|
||||||
|
|
||||||
word_t tlb_index = swtlb.allocate_pinned();
|
word_t tlb_index = swtlb.allocate_pinned();
|
||||||
tlb0.write(tlb_index);
|
tlb0.write(tlb_index);
|
||||||
|
@ -284,7 +286,6 @@ addr_t space_t::map_device_pinned(paddr_t paddr, word_t size, word_t attrib)
|
||||||
|
|
||||||
return addr_offset((addr_t)vaddr, paddr - paddr_align);
|
return addr_offset((addr_t)vaddr, paddr - paddr_align);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
asid_t *space_t::get_asid()
|
asid_t *space_t::get_asid()
|
||||||
{
|
{
|
||||||
|
@ -464,6 +465,25 @@ extern "C" SECTION(".einit") void init_paging( int cpu )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_TRACEBUFFER)
|
||||||
|
FEATURESTRING ("tracebuffer");
|
||||||
|
tracebuffer_t * tracebuffer;
|
||||||
|
EXTERN_KMEM_GROUP (kmem_misc);
|
||||||
|
void setup_tracebuffer (void)
|
||||||
|
{
|
||||||
|
tracebuffer = (tracebuffer_t *) kmem.alloc (kmem_misc, TRACEBUFFER_SIZE);
|
||||||
|
if (!tracebuffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addr_t vaddr = get_kernel_space()->map_device_pinned(virt_to_phys((paddr_t)tracebuffer),
|
||||||
|
TRACEBUFFER_SIZE, false, pgent_t::cache_standard );
|
||||||
|
get_kip()->memory_info.insert(memdesc_t::reserved, true, vaddr,
|
||||||
|
addr_offset(vaddr, TRACEBUFFER_SIZE -1));
|
||||||
|
|
||||||
|
tracebuffer->initialize ();
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_TRACEBUFFER */
|
||||||
|
|
||||||
addr_t setup_console_mapping(paddr_t paddr, int log2size)
|
addr_t setup_console_mapping(paddr_t paddr, int log2size)
|
||||||
{
|
{
|
||||||
static word_t console_area = CONSOLE_AREA_START;
|
static word_t console_area = CONSOLE_AREA_START;
|
||||||
|
|
|
@ -191,7 +191,7 @@ void SECTION(".init.memory") space_t::init_kernel_space()
|
||||||
kernel_space->init_kernel_mappings();
|
kernel_space->init_kernel_mappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
addr_t space_t::map_device( paddr_t paddr, word_t size, word_t attrib)
|
addr_t space_t::map_device( paddr_t paddr, word_t size, bool kernel, word_t attrib)
|
||||||
{
|
{
|
||||||
addr_t start_addr = (addr_t)(DEVICE_AREA_START + DEVICE_AREA_BAT_SIZE);
|
addr_t start_addr = (addr_t)(DEVICE_AREA_START + DEVICE_AREA_BAT_SIZE);
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ found:
|
||||||
for( word_t page = 0; page < size; page += POWERPC_PAGE_SIZE )
|
for( word_t page = 0; page < size; page += POWERPC_PAGE_SIZE )
|
||||||
{
|
{
|
||||||
this->add_mapping( addr_offset(start_addr, page),
|
this->add_mapping( addr_offset(start_addr, page),
|
||||||
paddr + page, pgent_t::size_4k, true, true, attrib );
|
paddr + page, pgent_t::size_4k, true, kernel, attrib );
|
||||||
}
|
}
|
||||||
|
|
||||||
return start_addr;
|
return start_addr;
|
||||||
|
|
|
@ -145,7 +145,7 @@ public:
|
||||||
|
|
||||||
void init_kernel_mappings();
|
void init_kernel_mappings();
|
||||||
void init_cpu_mappings(cpuid_t cpu);
|
void init_cpu_mappings(cpuid_t cpu);
|
||||||
addr_t map_device( paddr_t paddr, word_t size, word_t attrib );
|
addr_t map_device( paddr_t paddr, word_t size, bool kernel, word_t attrib );
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_MMU_SEGMENTS
|
#ifdef CONFIG_PPC_MMU_SEGMENTS
|
||||||
bool handle_hash_miss( addr_t vaddr );
|
bool handle_hash_miss( addr_t vaddr );
|
||||||
|
@ -153,7 +153,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_MMU_TLB
|
#ifdef CONFIG_PPC_MMU_TLB
|
||||||
addr_t map_device_pinned( paddr_t paddr, word_t log2size, word_t attrib );
|
addr_t map_device_pinned( paddr_t paddr, word_t size, bool kernel, word_t attrib );
|
||||||
bool handle_tlb_miss( addr_t lookup_vaddr, addr_t install_vaddr, bool user, bool global = false );
|
bool handle_tlb_miss( addr_t lookup_vaddr, addr_t install_vaddr, bool user, bool global = false );
|
||||||
bool handle_hvm_tlb_miss( ppc_softhvm_t*, ppc_softhvm_t::tlb_t*, word_t gvaddr, paddr_t &gpaddr );
|
bool handle_hvm_tlb_miss( ppc_softhvm_t*, ppc_softhvm_t::tlb_t*, word_t gvaddr, paddr_t &gpaddr );
|
||||||
asid_t *get_asid(); // asid of current cpu
|
asid_t *get_asid(); // asid of current cpu
|
||||||
|
@ -183,12 +183,12 @@ public:
|
||||||
return (space_t *)( (vsid & 0xfffffff0) << (POWERPC_PAGE_BITS - 4) );
|
return (space_t *)( (vsid & 0xfffffff0) << (POWERPC_PAGE_BITS - 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void add_mapping( addr_t vaddr, paddr_t paddr, pgent_t::pgsize_e size,
|
void add_mapping( addr_t vaddr, paddr_t paddr, pgent_t::pgsize_e size,
|
||||||
bool writable, bool kernel,
|
bool writable, bool kernel,
|
||||||
word_t attrib = pgent_t::cache_standard );
|
word_t attrib = pgent_t::cache_standard );
|
||||||
void flush_mapping( addr_t vaddr, pgent_t::pgsize_e size, pgent_t *pgent );
|
void flush_mapping( addr_t vaddr, pgent_t::pgsize_e size, pgent_t *pgent );
|
||||||
|
|
||||||
|
private:
|
||||||
pgent_t pdir[1024];
|
pgent_t pdir[1024];
|
||||||
union {
|
union {
|
||||||
word_t raw[1024];
|
word_t raw[1024];
|
||||||
|
@ -210,6 +210,7 @@ private:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static word_t pinned_mapping;
|
||||||
friend class kdb_t;
|
friend class kdb_t;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,26 +72,6 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid);
|
||||||
void SECTION(".init.cpu") setup_vmx (cpuid_t cpuid);
|
void SECTION(".init.cpu") setup_vmx (cpuid_t cpuid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_TRACEBUFFER)
|
|
||||||
tracebuffer_t * tracebuffer;
|
|
||||||
EXTERN_KMEM_GROUP (kmem_misc);
|
|
||||||
|
|
||||||
void SECTION(SEC_INIT) setup_tracebuffer (void)
|
|
||||||
{
|
|
||||||
tracebuffer = (tracebuffer_t *) kmem.alloc (kmem_misc, TRACEBUFFER_SIZE);
|
|
||||||
for (word_t p = 0; p < TRACEBUFFER_SIZE; p += page_size(TRACEBUFFER_PGENTSZ))
|
|
||||||
{
|
|
||||||
//TRACEF("add tbuf mapping %t -> %t\n", addr_offset(tracebuffer, p),
|
|
||||||
// virt_to_phys(addr_offset(tracebuffer, p)));
|
|
||||||
get_kernel_space()->add_mapping(addr_offset(tracebuffer, p),
|
|
||||||
virt_to_phys(addr_offset(tracebuffer, p)),
|
|
||||||
TRACEBUFFER_PGENTSZ,
|
|
||||||
true, false, true);
|
|
||||||
}
|
|
||||||
tracebuffer->initialize ();
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_TRACEBUFFER */
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_SMP)
|
#if defined(CONFIG_SMP)
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -280,6 +260,29 @@ void SECTION(SEC_INIT) add_more_kmem (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_TRACEBUFFER)
|
||||||
|
FEATURESTRING ("tracebuffer");
|
||||||
|
tracebuffer_t * tracebuffer;
|
||||||
|
EXTERN_KMEM_GROUP (kmem_misc);
|
||||||
|
void setup_tracebuffer (void)
|
||||||
|
{
|
||||||
|
tracebuffer = (tracebuffer_t *) kmem.alloc (kmem_misc, TRACEBUFFER_SIZE);
|
||||||
|
if (!tracebuffer)
|
||||||
|
return;
|
||||||
|
for (word_t p = 0; p < TRACEBUFFER_SIZE; p += KERNEL_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
//TRACEF("add tbuf mapping %t -> %t\n", addr_offset(tracebuffer, p),
|
||||||
|
// virt_to_phys(addr_offset(tracebuffer, p)));
|
||||||
|
get_kernel_space()->add_mapping(addr_offset(tracebuffer, p),
|
||||||
|
(paddr_t) virt_to_phys(addr_offset(tracebuffer, p)),
|
||||||
|
PGSIZE_KERNEL, true, false, true);
|
||||||
|
}
|
||||||
|
get_kip()->memory_info.insert(memdesc_t::reserved, true, tracebuffer,
|
||||||
|
addr_offset(tracebuffer, TRACEBUFFER_SIZE -1));
|
||||||
|
|
||||||
|
tracebuffer->initialize ();
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_TRACEBUFFER */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_cpu: initializes the processor
|
* init_cpu: initializes the processor
|
||||||
|
|
|
@ -703,19 +703,12 @@ void SECTION(".init.memory") space_t::init_kernel_mappings()
|
||||||
* each processor gets a full cache line to avoid bouncing
|
* each processor gets a full cache line to avoid bouncing
|
||||||
* page is user-writable and global
|
* page is user-writable and global
|
||||||
*/
|
*/
|
||||||
EXTERN_KMEM_GROUP(kmem_misc);
|
|
||||||
add_mapping((addr_t)UTCB_MAPPING,
|
|
||||||
virt_to_phys(kmem.alloc(kmem_misc, X86_PAGE_SIZE)),
|
|
||||||
pgent_t::size_4k, true, false, true);
|
|
||||||
|
|
||||||
EXTERN_KMEM_GROUP(kmem_misc);
|
EXTERN_KMEM_GROUP(kmem_misc);
|
||||||
utcb_page = kmem.alloc(kmem_misc, X86_PAGE_SIZE);
|
utcb_page = kmem.alloc(kmem_misc, X86_PAGE_SIZE);
|
||||||
ASSERT(utcb_page);
|
ASSERT(utcb_page);
|
||||||
add_mapping((addr_t)UTCB_MAPPING, virt_to_phys(utcb_page),
|
add_mapping((addr_t)UTCB_MAPPING, virt_to_phys(utcb_page),
|
||||||
pgent_t::size_4k, true, false, true);
|
pgent_t::size_4k, true, false, true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_X86_SMALL_SPACES) && defined(CONFIG_X86_SYSENTER)
|
#if defined(CONFIG_X86_SMALL_SPACES) && defined(CONFIG_X86_SYSENTER)
|
||||||
/* User-level trampoline for ipc_sysexit, readonly but global. */
|
/* User-level trampoline for ipc_sysexit, readonly but global. */
|
||||||
extern word_t _start_utramp_p[];
|
extern word_t _start_utramp_p[];
|
||||||
|
|
|
@ -423,9 +423,7 @@ INLINE void reload_user_segregs (void)
|
||||||
{
|
{
|
||||||
asm volatile (
|
asm volatile (
|
||||||
" movl %0, %%es \n"
|
" movl %0, %%es \n"
|
||||||
#if !defined(CONFIG_TRACEBUFFER)
|
|
||||||
" movl %0, %%fs \n"
|
" movl %0, %%fs \n"
|
||||||
#endif
|
|
||||||
" movl %1, %%gs \n"
|
" movl %1, %%gs \n"
|
||||||
:
|
:
|
||||||
: "r" (X86_UDS), "r" (X86_UTCBS));
|
: "r" (X86_UDS), "r" (X86_UTCBS));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2004, 2006-2009, Karlsruhe University
|
* Copyright (C) 2002-2004, 2006-2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: glue/v4-x86/thread.cc
|
* File path: glue/v4-x86/thread.cc
|
||||||
* Description:
|
* Description:
|
||||||
|
@ -54,14 +54,10 @@ void return_to_user_wrapper()
|
||||||
" mov %0, %%eax \n"
|
" mov %0, %%eax \n"
|
||||||
" mov %%eax, %%ds \n"
|
" mov %%eax, %%ds \n"
|
||||||
" mov %%eax, %%es \n"
|
" mov %%eax, %%es \n"
|
||||||
#if defined(CONFIG_TRACEBUFFER)
|
|
||||||
" mov %1, %%eax \n"
|
|
||||||
#else
|
|
||||||
" mov %%eax, %%fs \n"
|
" mov %%eax, %%fs \n"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_IS_64BIT)
|
#if defined(CONFIG_IS_64BIT)
|
||||||
" add %3, %%rsp \n"
|
" add %1, %%rsp \n"
|
||||||
" iretq \n"
|
" iretq \n"
|
||||||
#else
|
#else
|
||||||
#if defined(CONFIG_X_CTRLXFER_MSG)
|
#if defined(CONFIG_X_CTRLXFER_MSG)
|
||||||
|
@ -69,13 +65,12 @@ void return_to_user_wrapper()
|
||||||
" popa \n"
|
" popa \n"
|
||||||
" addl $4, %%esp \n"
|
" addl $4, %%esp \n"
|
||||||
#else
|
#else
|
||||||
" add %3, %%esp \n"
|
" add %1, %%esp \n"
|
||||||
#endif
|
#endif
|
||||||
" iret \n"
|
" iret \n"
|
||||||
#endif
|
#endif
|
||||||
:
|
:
|
||||||
: "i"(X86_UDS), "i" (X86_TBS), "i"(X86_UTCBS),
|
: "i"(X86_UDS), "i"(EXC_FRAME_SIZE * BYTES_WORD)
|
||||||
"i"(EXC_FRAME_SIZE * BYTES_WORD)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,6 @@
|
||||||
#define X86_UTCBS 0x2b
|
#define X86_UTCBS 0x2b
|
||||||
#define X86_TSS 0x30
|
#define X86_TSS 0x30
|
||||||
#define X86_KDB 0x38
|
#define X86_KDB 0x38
|
||||||
#define X86_TBS 0x43
|
|
||||||
|
|
||||||
/* user mode e-flags */
|
/* user mode e-flags */
|
||||||
#if defined(CONFIG_X86_PVI)
|
#if defined(CONFIG_X86_PVI)
|
||||||
|
|
|
@ -1554,30 +1554,23 @@ void vmexit_entry_point_wrapper ()
|
||||||
" mov %0, %%bx \n"
|
" mov %0, %%bx \n"
|
||||||
" mov %%bx, %%ds \n"
|
" mov %%bx, %%ds \n"
|
||||||
" mov %%bx, %%es \n"
|
" mov %%bx, %%es \n"
|
||||||
|
|
||||||
// FS.
|
|
||||||
#if defined(CONFIG_TRACEBUFFER)
|
|
||||||
" mov %1, %%bx \n"
|
|
||||||
#endif
|
|
||||||
" mov %%bx, %%fs \n"
|
" mov %%bx, %%fs \n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GS.
|
// GS.
|
||||||
" mov %2, %%bx \n"
|
" mov %1, %%bx \n"
|
||||||
" mov %%bx, %%gs \n"
|
" mov %%bx, %%gs \n"
|
||||||
|
|
||||||
// EFLAGS.
|
// EFLAGS.
|
||||||
// VM-Exit has a cleared eflags (except bit 1, which is always 1)
|
// VM-Exit has a cleared eflags (except bit 1, which is always 1)
|
||||||
" pushl %3 \n"
|
" pushl %2 \n"
|
||||||
" popfl \n"
|
" popfl \n"
|
||||||
|
|
||||||
// Call do_handle_vmexit.
|
// Call do_handle_vmexit.
|
||||||
" jmp %4 \n"
|
" jmp %3 \n"
|
||||||
:
|
:
|
||||||
: "i" (X86_UDS), // %0
|
: "i" (X86_UDS), // %0
|
||||||
"i" (X86_TBS), // %1
|
"i" (X86_UTCBS), // %1
|
||||||
"i" (X86_UTCBS), // %2
|
"i" (X86_KERNEL_FLAGS), // %2
|
||||||
"i" (X86_KERNEL_FLAGS), // %3
|
"m" (*do_handle_vmexit_ptr) // %3
|
||||||
"m" (*do_handle_vmexit_ptr) // %4
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
ASSERT(unsigned(cpuid * CACHE_LINE_SIZE) < X86_PAGE_SIZE);
|
ASSERT(unsigned(cpuid * CACHE_LINE_SIZE) < X86_PAGE_SIZE);
|
||||||
gdt[gdt_idx(X86_UTCBS)].set_seg((u32_t)UTCB_MAPPING +
|
gdt[gdt_idx(X86_UTCBS)].set_seg((u32_t)UTCB_MAPPING +
|
||||||
(cpuid * CACHE_LINE_SIZE),
|
(cpuid * CACHE_LINE_SIZE),
|
||||||
sizeof(threadid_t) - 1,
|
sizeof(threadid_t) - 1,
|
||||||
3, x86_segdesc_t::data);
|
3, x86_segdesc_t::data);
|
||||||
|
|
||||||
/* the TSS
|
/* the TSS
|
||||||
|
@ -152,17 +152,8 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
0, x86_segdesc_t::tss);
|
0, x86_segdesc_t::tss);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_TRACEBUFFER
|
|
||||||
if (get_tracebuffer())
|
|
||||||
gdt[gdt_idx(X86_TBS)].set_seg((u32_t)get_tracebuffer(), TRACEBUFFER_SIZE-1, 3,
|
|
||||||
x86_segdesc_t::data);
|
|
||||||
else
|
|
||||||
gdt[gdt_idx(X86_TBS)].set_seg(0, ~0UL, 3, x86_segdesc_t::data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* create a temporary GDT descriptor to load the GDTR from */
|
/* create a temporary GDT descriptor to load the GDTR from */
|
||||||
|
|
||||||
x86_descreg_t gdtr((word_t) &gdt, sizeof(gdt));
|
x86_descreg_t gdtr((word_t) &gdt, sizeof(gdt));
|
||||||
gdtr.setdescreg(x86_descreg_t::gdtr);
|
gdtr.setdescreg(x86_descreg_t::gdtr);
|
||||||
x86_descreg_t tr(X86_TSS);
|
x86_descreg_t tr(X86_TSS);
|
||||||
|
@ -185,11 +176,7 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
"mov %0, %%es \n" /* need valid %es for movs/stos */
|
"mov %0, %%es \n" /* need valid %es for movs/stos */
|
||||||
"mov %1, %%ss \n" /* reload stack segment */
|
"mov %1, %%ss \n" /* reload stack segment */
|
||||||
"mov %2, %%gs \n" /* load UTCB segment */
|
"mov %2, %%gs \n" /* load UTCB segment */
|
||||||
#ifdef CONFIG_TRACEBUFFER
|
|
||||||
"mov %3, %%fs \n" /* tracebuffer segment */
|
|
||||||
#else
|
|
||||||
"mov %0, %%fs \n" /* default without tracebuffer */
|
"mov %0, %%fs \n" /* default without tracebuffer */
|
||||||
#endif
|
|
||||||
"xor %%eax, %%eax \n" /* */
|
"xor %%eax, %%eax \n" /* */
|
||||||
"lldt %%ax \n" /* clear LDTR */
|
"lldt %%ax \n" /* clear LDTR */
|
||||||
:
|
:
|
||||||
|
@ -199,7 +186,7 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
#else
|
#else
|
||||||
"r"(X86_UDS),
|
"r"(X86_UDS),
|
||||||
#endif
|
#endif
|
||||||
"r"(X86_KDS), "r"(X86_UTCBS), "r"(X86_TBS)
|
"r"(X86_KDS), "r"(X86_UTCBS)
|
||||||
: "eax", "memory"
|
: "eax", "memory"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#define PGSIZE_KTCB (pgent_t::size_4k)
|
#define PGSIZE_KTCB (pgent_t::size_4k)
|
||||||
#define PGSIZE_UTCB (pgent_t::size_4k)
|
#define PGSIZE_UTCB (pgent_t::size_4k)
|
||||||
#define PGSIZE_KERNEL ((KERNEL_PAGE_SIZE == X86_SUPERPAGE_SIZE) ? pgent_t::size_4m : pgent_t::size_4k)
|
#define PGSIZE_KERNEL ((KERNEL_PAGE_SIZE == X86_SUPERPAGE_SIZE) ? pgent_t::size_4m : pgent_t::size_4k)
|
||||||
|
|
||||||
#define PGSIZE_KIP (pgent_t::size_4k)
|
#define PGSIZE_KIP (pgent_t::size_4k)
|
||||||
#define PGSIZE_SIGMA PGSIZE_KERNEL
|
#define PGSIZE_SIGMA PGSIZE_KERNEL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002, 2004-2009, Karlsruhe University
|
* Copyright (C) 2002, 2004-2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: glue/v4-x86/x32/tcb.h
|
* File path: glue/v4-x86/x32/tcb.h
|
||||||
* Description: TCB related functions for Version 4, IA-32
|
* Description: TCB related functions for Version 4, IA-32
|
||||||
|
@ -137,7 +137,6 @@ INLINE SECTION(".text") void tcb_t::switch_to(tcb_t * dest)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_X86_SMALL_SPACES)
|
#if defined(CONFIG_X86_SMALL_SPACES)
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"/* switch_to_thread */ \n"
|
"/* switch_to_thread */ \n"
|
||||||
" pushl %%ebp \n"
|
" pushl %%ebp \n"
|
||||||
|
@ -171,9 +170,7 @@ INLINE SECTION(".text") void tcb_t::switch_to(tcb_t * dest)
|
||||||
" movl %%eax, 28(%%ebp) \n"
|
" movl %%eax, 28(%%ebp) \n"
|
||||||
" movl $"MKSTR(X86_UDS)", %%ecx \n"
|
" movl $"MKSTR(X86_UDS)", %%ecx \n"
|
||||||
" movl %%ecx, %%es \n"
|
" movl %%ecx, %%es \n"
|
||||||
#if !defined(CONFIG_TRACEBUFFER)
|
|
||||||
" movl %%ecx, %%fs \n"
|
" movl %%ecx, %%fs \n"
|
||||||
#endif
|
|
||||||
" movl $"MKSTR(X86_UTCBS)", %%ecx \n"
|
" movl $"MKSTR(X86_UTCBS)", %%ecx \n"
|
||||||
" movl %%ecx, %%gs \n"
|
" movl %%ecx, %%gs \n"
|
||||||
|
|
||||||
|
@ -196,9 +193,8 @@ INLINE SECTION(".text") void tcb_t::switch_to(tcb_t * dest)
|
||||||
|
|
||||||
" movl $"MKSTR(X86_UDS)", %%edx \n"
|
" movl $"MKSTR(X86_UDS)", %%edx \n"
|
||||||
" movl %%edx, %%es \n"
|
" movl %%edx, %%es \n"
|
||||||
#if !defined(CONFIG_TRACEBUFFER)
|
|
||||||
" movl %%edx, %%fs \n"
|
" movl %%edx, %%fs \n"
|
||||||
#endif
|
|
||||||
" movl $"MKSTR(X86_UTCBS)", %%edx \n"
|
" movl $"MKSTR(X86_UTCBS)", %%edx \n"
|
||||||
" movl %%edx, %%gs \n"
|
" movl %%edx, %%gs \n"
|
||||||
|
|
||||||
|
|
|
@ -244,10 +244,8 @@ fp_save_resources_done:
|
||||||
movl %eax, 28(%ebp)
|
movl %eax, 28(%ebp)
|
||||||
movl $X86_UDS, %ecx
|
movl $X86_UDS, %ecx
|
||||||
movl %ecx, %es
|
movl %ecx, %es
|
||||||
#if !defined(CONFIG_TRACEBUFFER)
|
|
||||||
movl %ecx, %fs
|
movl %ecx, %fs
|
||||||
#endif
|
movl $X86_UTCBS, %ecx
|
||||||
movl $X86_UTCBS, %ecx
|
|
||||||
movl %ecx, %gs
|
movl %ecx, %gs
|
||||||
movl $1, __is_small
|
movl $1, __is_small
|
||||||
1: popl %ecx
|
1: popl %ecx
|
||||||
|
@ -266,9 +264,7 @@ fp_save_resources_done:
|
||||||
|
|
||||||
movl $X86_UDS, %edx
|
movl $X86_UDS, %edx
|
||||||
movl %edx, %es
|
movl %edx, %es
|
||||||
#if !defined(CONFIG_TRACEBUFFER)
|
|
||||||
movl %edx, %fs
|
movl %edx, %fs
|
||||||
#endif
|
|
||||||
movl $X86_UTCBS, %edx
|
movl $X86_UTCBS, %edx
|
||||||
movl %edx, %gs
|
movl %edx, %gs
|
||||||
|
|
||||||
|
|
|
@ -213,8 +213,7 @@
|
||||||
#define X86_UDS 0x23 /* 4, RPL = 3 */
|
#define X86_UDS 0x23 /* 4, RPL = 3 */
|
||||||
#define X86_UCS 0x2b /* 5, RPL = 3 */
|
#define X86_UCS 0x2b /* 5, RPL = 3 */
|
||||||
#define X86_UTCBS 0x33 /* 6, RPL = 3 */
|
#define X86_UTCBS 0x33 /* 6, RPL = 3 */
|
||||||
#define X86_X64_KDBS 0x38 /* 7, RPL = 0 */
|
#define X86_X64_KDBS 0x38 /* 7, RPL = 0 */
|
||||||
#define X86_TBS 0x43 /* 8, RPL = 0 */
|
|
||||||
#define X86_TSS 0x48 /* 9, RPL = 0 */
|
#define X86_TSS 0x48 /* 9, RPL = 0 */
|
||||||
|
|
||||||
/* user mode e-flags */
|
/* user mode e-flags */
|
||||||
|
|
|
@ -219,14 +219,7 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
x86_segdesc_t::m_long,
|
x86_segdesc_t::m_long,
|
||||||
x86_segdesc_t::msr_gs);
|
x86_segdesc_t::msr_gs);
|
||||||
|
|
||||||
#if defined(CONFIG_TRACEBUFFER)
|
|
||||||
gdt.segdsc[GDT_IDX(X86_TBS)].set_seg((u64_t) get_tracebuffer(),
|
|
||||||
x86_segdesc_t::data,
|
|
||||||
3,
|
|
||||||
x86_segdesc_t::m_long,
|
|
||||||
x86_segdesc_t::msr_fs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("" ::: "memory");
|
__asm__ __volatile__ ("" ::: "memory");
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,16 +229,12 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
"mov %0, %%es \n\t" // load extra segment (ES)
|
"mov %0, %%es \n\t" // load extra segment (ES)
|
||||||
"mov %0, %%ss \n\t" // load stack segment (SS)
|
"mov %0, %%ss \n\t" // load stack segment (SS)
|
||||||
"mov %1, %%gs \n\t" // load UTCB segment (GS)
|
"mov %1, %%gs \n\t" // load UTCB segment (GS)
|
||||||
#ifdef CONFIG_TRACEBUFFER
|
|
||||||
"mov %2, %%fs \n\t" // tracebuffer segment (FS)
|
|
||||||
#else
|
|
||||||
"mov %0, %%fs \n\t" // no tracebuffer
|
"mov %0, %%fs \n\t" // no tracebuffer
|
||||||
#endif
|
"pushq %2 \n\t" // new CS
|
||||||
"pushq %3 \n\t" // new CS
|
|
||||||
"pushq $1f \n\t" // new IP
|
"pushq $1f \n\t" // new IP
|
||||||
"lretq \n\t"
|
"lretq \n\t"
|
||||||
"1: \n\t"
|
"1: \n\t"
|
||||||
: /* No Output */ : "r" (0), "r" (X86_UTCBS), "r" (X86_TBS), "r" ((u64_t) X86_KCS)
|
: /* No Output */ : "r" (0), "r" (X86_UTCBS), "r" ((u64_t) X86_KCS)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,14 +244,6 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
|
||||||
x86_segdesc_t::m_long,
|
x86_segdesc_t::m_long,
|
||||||
x86_segdesc_t::msr_gs);
|
x86_segdesc_t::msr_gs);
|
||||||
|
|
||||||
#if defined(CONFIG_TRACEBUFFER)
|
|
||||||
gdt.segdsc[GDT_IDX(X86_TBS)].set_seg( (u64_t) get_tracebuffer(),
|
|
||||||
x86_segdesc_t::data,
|
|
||||||
3,
|
|
||||||
x86_segdesc_t::m_long,
|
|
||||||
x86_segdesc_t::msr_fs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002, Karlsruhe University
|
* Copyright (C) 2002, 2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: init.h
|
* File path: kdb/init.h
|
||||||
* Description: Macro for declaring a kernel debugger init function.
|
* Description: Macro for declaring a kernel debugger init function.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -140,8 +140,7 @@ public:
|
||||||
|
|
||||||
bool next_record(word_t type, word_t id)
|
bool next_record(word_t type, word_t id)
|
||||||
{
|
{
|
||||||
if (!this)
|
if (!this) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Check wheter to filter the event */
|
/* Check wheter to filter the event */
|
||||||
if ((mask & ((type & 0xffff) << 16)) == 0)
|
if ((mask & ((type & 0xffff) << 16)) == 0)
|
||||||
|
@ -159,6 +158,7 @@ public:
|
||||||
|
|
||||||
void increase_counter(word_t ctr)
|
void increase_counter(word_t ctr)
|
||||||
{
|
{
|
||||||
|
if (!this) return;
|
||||||
counters[ctr & 0x7]++;
|
counters[ctr & 0x7]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,12 +223,13 @@ INLINE void __tbuf_record_event(word_t type, word_t tpid, const char *str, ...)
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup_tracebuffer (void);
|
||||||
|
|
||||||
#else /* !CONFIG_TRACEBUFFER */
|
#else /* !CONFIG_TRACEBUFFER */
|
||||||
#define tbuf_inc_counter(counter)
|
#define tbuf_inc_counter(counter)
|
||||||
#define tbuf_record_event(args...)
|
#define tbuf_record_event(args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
# define TBUF_REC_TRACEPOINT(tptype, tpid, str, args...) \
|
# define TBUF_REC_TRACEPOINT(tptype, tpid, str, args...) \
|
||||||
tbuf_record_event (tptype, tpid, str, ##args)
|
tbuf_record_event (tptype, tpid, str, ##args)
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,6 @@
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include <l4/arch.h>
|
#include <l4/arch.h>
|
||||||
|
|
||||||
#undef L4_TRACEBUFFER
|
|
||||||
#include <l4/tracebuffer.h>
|
|
||||||
|
|
||||||
#include L4_COMPAT_H_LOCATION
|
#include L4_COMPAT_H_LOCATION
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003, Karlsruhe University
|
* Copyright (C) 2003, 2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: bench/pingpong/crt0-ia32.S
|
* File path: bench/pingpong/crt0-ia32.S
|
||||||
* Description:
|
* Description:
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include <l4/arch.h>
|
#include <l4/arch.h>
|
||||||
|
|
||||||
#define L4_TRACEBUFFER
|
|
||||||
|
|
||||||
#define HAVE_HANDLE_ARCH_PAGEFAULT
|
#define HAVE_HANDLE_ARCH_PAGEFAULT
|
||||||
#define HAVE_READ_CYCLES
|
#define HAVE_READ_CYCLES
|
||||||
#define HAVE_ARCH_IPC
|
#define HAVE_ARCH_IPC
|
||||||
|
|
|
@ -38,35 +38,6 @@
|
||||||
#include <l4io.h>
|
#include <l4io.h>
|
||||||
#include <l4/arch.h>
|
#include <l4/arch.h>
|
||||||
|
|
||||||
int strcmp( const char *str1, const char *str2 )
|
|
||||||
{
|
|
||||||
while( *str1 && *str2 ) {
|
|
||||||
if( *str1 < *str2 )
|
|
||||||
return -1;
|
|
||||||
if( *str1 > *str2 )
|
|
||||||
return 1;
|
|
||||||
str1++;
|
|
||||||
str2++;
|
|
||||||
}
|
|
||||||
if( *str2 )
|
|
||||||
return -1;
|
|
||||||
if( *str1 )
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool l4_has_feature( const char *feature_name )
|
|
||||||
{
|
|
||||||
void *kip = L4_GetKernelInterface();
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
for( L4_Word_t i = 0; (name = L4_Feature(kip,i)) != '\0'; i++ )
|
|
||||||
if( !strcmp(feature_name, name) )
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(L4_ARCH_POWERPC64)
|
#if defined(L4_ARCH_POWERPC64)
|
||||||
extern long _start_pager;
|
extern long _start_pager;
|
||||||
extern long _start_ping_thread;
|
extern long _start_ping_thread;
|
||||||
|
@ -89,15 +60,8 @@ int SMALL_AS = 0;
|
||||||
int LIPC = 0;
|
int LIPC = 0;
|
||||||
int PRINT_TABLE = 0;
|
int PRINT_TABLE = 0;
|
||||||
|
|
||||||
bool tbuf, hsched;
|
int hsched;
|
||||||
|
|
||||||
#if defined(L4_TRACEBUFFER)
|
|
||||||
#define Dprintf(args...) \
|
|
||||||
|
|
||||||
if (tbuf) L4_Tbuf_RecordEvent (1, args);
|
|
||||||
#else
|
|
||||||
#define Dprintf(x...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
L4_ThreadId_t s0tid, roottid, pager_tid, ping_tid, pong_tid;
|
L4_ThreadId_t s0tid, roottid, pager_tid, ping_tid, pong_tid;
|
||||||
L4_KernelInterfacePage_t * kip;
|
L4_KernelInterfacePage_t * kip;
|
||||||
|
@ -140,7 +104,9 @@ void pong_thread (void);
|
||||||
#elif defined(L4_ARCH_AMD64)
|
#elif defined(L4_ARCH_AMD64)
|
||||||
#include "amd64.h"
|
#include "amd64.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <l4/tracebuffer.h>
|
||||||
|
|
||||||
|
#define debug_printf(x...) L4_Tbuf_RecordEvent (1, x)
|
||||||
|
|
||||||
static inline void rdpmc (int no, L4_Word64_t* res)
|
static inline void rdpmc (int no, L4_Word64_t* res)
|
||||||
{
|
{
|
||||||
|
@ -227,7 +193,7 @@ void pong_thread (void)
|
||||||
else
|
else
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Dprintf("pong ipc\n");
|
debug_printf("pong ipc\n");
|
||||||
untyped = pingpong_ipc (ping_tid, untyped);
|
untyped = pingpong_ipc (ping_tid, untyped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,7 +248,7 @@ void ping_thread (void)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < FACTOR; k++)
|
for (int k = 0; k < FACTOR; k++)
|
||||||
{
|
{
|
||||||
Dprintf( "ping ipc\n");
|
debug_printf( "ping ipc\n");
|
||||||
pingpong_ipc (pong_tid, j);
|
pingpong_ipc (pong_tid, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,8 +336,8 @@ void pager (void)
|
||||||
{
|
{
|
||||||
L4_Store (tag, &msg);
|
L4_Store (tag, &msg);
|
||||||
|
|
||||||
Dprintf( "Pager got msg from %p\n", (L4_Word_t) tid.raw);
|
debug_printf( "Pager got msg from %p\n", (L4_Word_t) tid.raw);
|
||||||
Dprintf( "\tmsg (%p, %p, %p, %p)\n",
|
debug_printf( "\tmsg (%p, %p, %p, %p)\n",
|
||||||
(L4_Word_t) tag.raw,
|
(L4_Word_t) tag.raw,
|
||||||
(L4_Word_t) L4_Get (&msg, 0),
|
(L4_Word_t) L4_Get (&msg, 0),
|
||||||
(L4_Word_t) L4_Get (&msg, 1),
|
(L4_Word_t) L4_Get (&msg, 1),
|
||||||
|
@ -454,9 +420,11 @@ int main (void)
|
||||||
// We need a maximum of two threads per task
|
// We need a maximum of two threads per task
|
||||||
utcb_area = L4_FpageLog2 ((L4_Word_t) UTCB_ADDRESS,
|
utcb_area = L4_FpageLog2 ((L4_Word_t) UTCB_ADDRESS,
|
||||||
L4_UtcbAreaSizeLog2 (kip) + 1);
|
L4_UtcbAreaSizeLog2 (kip) + 1);
|
||||||
Dprintf ("kip_area = %lx, utcb_area = %lx, utcb_size = %lx\n",
|
|
||||||
|
debug_printf ("kip_area = %lx, utcb_area = %lx, utcb_size = %lx\n",
|
||||||
kip_area.raw, utcb_area.raw, utcb_size);
|
kip_area.raw, utcb_area.raw, utcb_size);
|
||||||
|
|
||||||
|
|
||||||
// Create pager
|
// Create pager
|
||||||
pager_tid = L4_GlobalId (L4_ThreadNo (roottid) + 1, 2);
|
pager_tid = L4_GlobalId (L4_ThreadNo (roottid) + 1, 2);
|
||||||
ping_tid = L4_GlobalId (L4_ThreadNo (roottid) + 2, 2);
|
ping_tid = L4_GlobalId (L4_ThreadNo (roottid) + 2, 2);
|
||||||
|
@ -464,16 +432,13 @@ int main (void)
|
||||||
|
|
||||||
L4_ThreadId_t scheduler_tid[2] = { roottid, roottid };
|
L4_ThreadId_t scheduler_tid[2] = { roottid, roottid };
|
||||||
|
|
||||||
hsched = l4_has_feature("hscheduling");
|
hsched = L4_HasFeature("hscheduling");
|
||||||
|
|
||||||
#if defined(L4_TRACEBUFFER)
|
|
||||||
tbuf = l4_has_feature("tracebuffer");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// VU: calculate UTCB address -- this has to be revised
|
// VU: calculate UTCB address -- this has to be revised
|
||||||
L4_Word_t pager_utcb = L4_MyLocalId().raw;
|
L4_Word_t pager_utcb = L4_MyLocalId().raw;
|
||||||
pager_utcb = (pager_utcb & ~(utcb_size - 1)) + utcb_size;
|
pager_utcb = (pager_utcb & ~(utcb_size - 1)) + utcb_size;
|
||||||
Dprintf("local id = %lx, pager UTCB = %lx\n", L4_MyLocalId().raw,
|
debug_printf("local id = %lx, pager UTCB = %lx\n", L4_MyLocalId().raw,
|
||||||
pager_utcb);
|
pager_utcb);
|
||||||
|
|
||||||
L4_ThreadControl (pager_tid, L4_Myself (), scheduler_tid[0], L4_Myself (), (void*)pager_utcb);
|
L4_ThreadControl (pager_tid, L4_Myself (), scheduler_tid[0], L4_Myself (), (void*)pager_utcb);
|
||||||
|
@ -504,7 +469,7 @@ int main (void)
|
||||||
|
|
||||||
const char *str = "Pingpong started %x\n";
|
const char *str = "Pingpong started %x\n";
|
||||||
printf(str, L4_Myself());
|
printf(str, L4_Myself());
|
||||||
Dprintf( str, L4_Myself().raw);
|
debug_printf( str, L4_Myself().raw);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (C) 1999-2010, Karlsruhe University
|
* Copyright (C) 1999-2010, Karlsruhe University
|
||||||
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
||||||
*
|
*
|
||||||
* File path: apps/bench/pingpong/powerpc.h
|
* File path: bench/pingpong/powerpc.h
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -133,7 +133,7 @@ bad_send(void)
|
||||||
L4_Load( &msg );
|
L4_Load( &msg );
|
||||||
|
|
||||||
tag = L4_Call_Timeouts( L4_Pager(), L4_Never, L4_TimePeriod( 1000 * 1000 ));
|
tag = L4_Call_Timeouts( L4_Pager(), L4_Never, L4_TimePeriod( 1000 * 1000 ));
|
||||||
bool ok = L4_IpcFailed(tag) && (L4_ErrorCode() & 0x1 == 1);
|
bool ok = (L4_IpcFailed(tag) && (L4_ErrorCode() & 0x1 == 1));
|
||||||
|
|
||||||
/* give sigma0 a little time to recover */
|
/* give sigma0 a little time to recover */
|
||||||
msec_sleep(1000);
|
msec_sleep(1000);
|
||||||
|
|
|
@ -35,6 +35,13 @@
|
||||||
/*
|
/*
|
||||||
* Architecture specific helper functions.
|
* Architecture specific helper functions.
|
||||||
*/
|
*/
|
||||||
|
L4_INLINE void __L4_Inc_Atomic (L4_Word_t *w)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"/* l4_inc_atomic() */\n"
|
||||||
|
"lock; add $1, %0"
|
||||||
|
: "=m"(w));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
L4_INLINE int __L4_Msb (L4_Word_t w) __attribute__ ((const));
|
L4_INLINE int __L4_Msb (L4_Word_t w) __attribute__ ((const));
|
||||||
|
@ -77,5 +84,29 @@ L4_INLINE int __L4_Lsb (L4_Word_t w)
|
||||||
return bitnum;
|
return bitnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
L4_INLINE L4_Word64_t __L4_Rdtsc ()
|
||||||
|
{
|
||||||
|
L4_Word_t eax, edx;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"/* l4_rdtsc() */ \n"
|
||||||
|
"rdtsc"
|
||||||
|
: "=a"(eax), "=d"(edx));
|
||||||
|
|
||||||
|
return (((L4_Word64_t)edx) << 32) | (L4_Word64_t)eax;
|
||||||
|
}
|
||||||
|
|
||||||
|
L4_INLINE L4_Word64_t __L4_Rdpmc (const L4_Word_t ctrsel)
|
||||||
|
{
|
||||||
|
L4_Word_t eax, edx;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"/* l4_rdpmc() */ \n"
|
||||||
|
"rdpmc"
|
||||||
|
: "=a"(eax), "=d"(edx)
|
||||||
|
: "c"(ctrsel));
|
||||||
|
|
||||||
|
return (((L4_Word64_t)edx) << 32) | (L4_Word64_t)eax;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !__L4__AMD64__SPECIALS_H__ */
|
#endif /* !__L4__AMD64__SPECIALS_H__ */
|
||||||
|
|
|
@ -30,193 +30,70 @@
|
||||||
#ifndef __L4__AMD64__TRACEBUFFER_H__
|
#ifndef __L4__AMD64__TRACEBUFFER_H__
|
||||||
#define __L4__AMD64__TRACEBUFFER_H__
|
#define __L4__AMD64__TRACEBUFFER_H__
|
||||||
|
|
||||||
|
#include __L4_INC_ARCH(specials.h)
|
||||||
|
|
||||||
/* Turn preprocessor symbol definition into string */
|
/**********************************************************************
|
||||||
#define MKSTR(sym) MKSTR2(sym)
|
* Sample PMC energy weights
|
||||||
#define MKSTR2(sym) #sym
|
**********************************************************************/
|
||||||
|
/* Pentium D */
|
||||||
|
#define X86_PMC_TSC_WEIGHT (1418)
|
||||||
|
#define X86_PMC_UC_WEIGHT (1285)
|
||||||
|
#define X86_PMC_LDM_WEIGHT (881)
|
||||||
|
#define X86_PMC_MR_WEIGHT (649)
|
||||||
|
#define X86_PMC_MB_WEIGHT (23421)
|
||||||
|
#define X86_PMC_MLR_WEIGHT (4320)
|
||||||
|
#define X86_PMC_RB_WEIGHT (840)
|
||||||
|
#define X86_PMC_MQW_WEIGHT (75)
|
||||||
|
|
||||||
#if defined(L4_64BIT)
|
#define X86_PMC_TSC_SHIFT 6
|
||||||
# define __PLUS32 + 32
|
#define X86_PMC_UC (0)
|
||||||
#else
|
#define X86_PMC_MLR (1)
|
||||||
# define __PLUS32
|
#define X86_PMC_MQW (4)
|
||||||
#endif
|
#define X86_PMC_RB (5)
|
||||||
|
#define X86_PMC_MB (12)
|
||||||
|
#define X86_PMC_MR (13)
|
||||||
|
#define X86_PMC_LDM (14)
|
||||||
|
|
||||||
#define L4_TRACEBUFFER_MAGIC (0x1464b123acebf)
|
L4_INLINE void L4_Tbuf_StoreRecordArch(L4_TraceRecord_t *rec, L4_TraceConfig_t config)
|
||||||
#define L4_TRACEBUFFER_NUM_ARGS (9)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A tracebuffer record indicates the type of event, the time of the
|
|
||||||
* event, the current thread, a number of event specific parameters,
|
|
||||||
* and potentially the current performance counters.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
struct {
|
rec->tsc = __L4_Rdtsc();
|
||||||
L4_Word_t utype : 16;
|
|
||||||
L4_Word_t __pad0 : 16 __PLUS32;
|
|
||||||
L4_Word_t cpu : 16;
|
|
||||||
L4_Word_t id : 16 __PLUS32;
|
|
||||||
} X;
|
|
||||||
|
|
||||||
L4_Word_t tsc;
|
if (config.X.pmon)
|
||||||
L4_Word_t thread;
|
{
|
||||||
L4_Word_t pmc0;
|
switch (config.X.pmon_cpu)
|
||||||
L4_Word_t pmc1;
|
{
|
||||||
L4_Word_t str;
|
case 0:
|
||||||
L4_Word_t data[9];
|
// P2/P3/K8
|
||||||
} L4_TraceRecord_t;
|
rec->pmc0 = __L4_Rdpmc(0);
|
||||||
|
rec->pmc1 = __L4_Rdpmc(1);
|
||||||
|
break;
|
||||||
/*
|
case 1:
|
||||||
* Tracebuffer access macros
|
// P4
|
||||||
*/
|
if (config.X.pmon_e)
|
||||||
|
{
|
||||||
#define __L4_TBUF_RDPMCS \
|
L4_Word64_t pmce =
|
||||||
/* Get config into rbx/ebx */ \
|
X86_PMC_TSC_WEIGHT * __L4_Rdtsc() +
|
||||||
" push %%rbx \n" /* save ebx */ \
|
X86_PMC_UC_WEIGHT * __L4_Rdpmc(X86_PMC_UC) +
|
||||||
" movq %%fs:4*%c9, %%rbx \n" \
|
X86_PMC_MLR_WEIGHT * __L4_Rdpmc(X86_PMC_MLR) +
|
||||||
" test $2, %%rbx \n" \
|
X86_PMC_MQW_WEIGHT * __L4_Rdpmc(X86_PMC_MQW) +
|
||||||
" jz 4f \n" /* no pmon, rdtsc only */ \
|
X86_PMC_RB_WEIGHT * __L4_Rdpmc(X86_PMC_RB) +
|
||||||
" test $4, %%rbx \n" \
|
X86_PMC_MB_WEIGHT * __L4_Rdpmc(X86_PMC_MB) +
|
||||||
" jz 3f \n" /* P2/K8 pmon */ \
|
X86_PMC_MR_WEIGHT * __L4_Rdpmc(X86_PMC_MR) +
|
||||||
/* P4 PerfMon */ \
|
X86_PMC_LDM_WEIGHT * __L4_Rdpmc(X86_PMC_LDM);
|
||||||
" mov $12, %1 \n" \
|
|
||||||
" rdpmc \n" \
|
rec->pmc0 = (L4_Word_t) pmce;
|
||||||
" shl $32, %%rdx \n" \
|
rec->pmc1 = (L4_Word_t) (pmce >> 32);
|
||||||
" movl %%eax, %%edx \n" \
|
}
|
||||||
" mov %2, %%fs:4*%c9(%0) \n" \
|
else
|
||||||
" add $2, %1 \n" \
|
{
|
||||||
" rdpmc \n" \
|
rec->pmc0 = (L4_Word_t) __L4_Rdpmc(12);
|
||||||
" shl $32, %%rdx \n" \
|
rec->pmc1 = (L4_Word_t) __L4_Rdpmc(14);
|
||||||
" movl %%eax, %%edx \n" \
|
}
|
||||||
" mov %2, %%fs:5*%c9(%0) \n" \
|
break;
|
||||||
" jmp 4f \n" \
|
default:
|
||||||
"3: \n" \
|
break;
|
||||||
/* P2/K8 PerfMon */ \
|
}
|
||||||
" xor %1, %1 \n" \
|
}
|
||||||
" rdpmc \n" \
|
}
|
||||||
" shl $32, %%rdx \n" \
|
|
||||||
" movl %%eax, %%edx \n" \
|
|
||||||
" mov %2, %%fs:4*%c9(%0) \n" \
|
|
||||||
" mov $1, %1 \n" \
|
|
||||||
" rdpmc \n" \
|
|
||||||
" shl $32, %%rdx \n" \
|
|
||||||
" movl %%eax, %%edx \n" \
|
|
||||||
" mov %2, %%fs:5*%c9(%0) \n" \
|
|
||||||
"4: \n" \
|
|
||||||
" rdtsc \n" \
|
|
||||||
" shl $32, %%rdx \n" \
|
|
||||||
" movl %%eax, %%edx \n" \
|
|
||||||
" mov %2, %%fs:2*%c9(%0) \n" \
|
|
||||||
" pop %%rbx \n" /* restore ebx */ \
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define __L4_TBUF_INCREASE_COUNTER(ctr) \
|
|
||||||
do { \
|
|
||||||
asm volatile ( \
|
|
||||||
" testl $1, %%fs:4*%c9 \n" \
|
|
||||||
" jz 2f \n" \
|
|
||||||
" lock; \n" \
|
|
||||||
" inc %%fs:8*%c1(%0) \n" \
|
|
||||||
: \
|
|
||||||
: \
|
|
||||||
"r" ((ctr & 0x7) * 4), \
|
|
||||||
"i" (sizeof(L4_Word_t))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define __L4_TBUF_GET_NEXT_RECORD(type, id) \
|
|
||||||
({ \
|
|
||||||
L4_Word_t _dummy, _addr; \
|
|
||||||
asm volatile ( \
|
|
||||||
/* Check wheter to filter the event */ \
|
|
||||||
" mov %%fs:2*%c9, %3 \n" \
|
|
||||||
" and %1, %3 \n" \
|
|
||||||
" jz 7f \n" \
|
|
||||||
" or %2, %1 \n" \
|
|
||||||
\
|
|
||||||
/* Get record offset into EDI */ \
|
|
||||||
"1: mov %%fs:1*%c9, %3 \n" \
|
|
||||||
" mov %8, %0 \n" \
|
|
||||||
" mov %0, %2 \n" \
|
|
||||||
" add %3, %0 \n" \
|
|
||||||
" and %%fs:3*%c9, %0 \n" \
|
|
||||||
" cmovz %2, %0 \n" \
|
|
||||||
" testl $1, %%fs:4*%c9 \n" \
|
|
||||||
" jz 2f \n" \
|
|
||||||
" lock; \n" \
|
|
||||||
"2: \n" \
|
|
||||||
" cmpxchg %0, %%fs:1*%c9 \n" \
|
|
||||||
" jnz 1b \n" \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
/* Store type, cpu, id, thread, counters */ \
|
|
||||||
" mov %1, %2 \n" \
|
|
||||||
" movzx %%cx, %%ecx \n" \
|
|
||||||
" movl %%ecx, %%fs:(%0) \n" \
|
|
||||||
" mov %%gs:0, %1 \n" \
|
|
||||||
" movw "MKSTR(__L4_TCR_PROCESSOR_NO)"*%c9(%1), %%dx\n"\
|
|
||||||
" movl %%edx, %%fs:1*%c9(%0) \n" \
|
|
||||||
" mov "MKSTR(__L4_TCR_MY_GLOBAL_ID)"*%c9(%1), %2\n" \
|
|
||||||
" mov %2, %%fs:3*%c9(%0) \n" \
|
|
||||||
__L4_TBUF_RDPMCS \
|
|
||||||
"7: \n" \
|
|
||||||
: \
|
|
||||||
"=D" (_addr), /* 0 */ \
|
|
||||||
"=c" (_dummy), /* 1 */ \
|
|
||||||
"=d" (_dummy), /* 2 */ \
|
|
||||||
"=a" (_dummy) /* 3 */ \
|
|
||||||
: \
|
|
||||||
"0" (0), /* 4 */ \
|
|
||||||
"1" (type & 0xffff), /* 5 */ \
|
|
||||||
"2" ((id & 0xffff)<<16), /* 6 */ \
|
|
||||||
"3" (0), /* 7 */ \
|
|
||||||
"i" (sizeof (L4_TraceRecord_t)), /* 8 */ \
|
|
||||||
"i" (sizeof(L4_Word_t)) /* 9 */ \
|
|
||||||
); \
|
|
||||||
_addr; \
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record (format) string into event buffer.
|
|
||||||
*
|
|
||||||
* @param addr offset of event record
|
|
||||||
* @param offset string to be recorded
|
|
||||||
*/
|
|
||||||
#define __L4_TBUF_STORE_STR(addr, str) \
|
|
||||||
do { \
|
|
||||||
asm volatile ( \
|
|
||||||
"mov %0, %%fs:6*%c2(%1)\n" \
|
|
||||||
: \
|
|
||||||
: \
|
|
||||||
"r" (str), \
|
|
||||||
"D" (addr), \
|
|
||||||
"i" (sizeof(L4_Word_t))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record arguments into event buffer at indicated location.
|
|
||||||
*
|
|
||||||
* @param addr offset of event record
|
|
||||||
* @param offset offset within event record
|
|
||||||
* @param item value to be recorded
|
|
||||||
*/
|
|
||||||
#define __L4_TBUF_STORE_DATA(addr, offset, item) \
|
|
||||||
do { \
|
|
||||||
L4_Word_t _dummy; \
|
|
||||||
asm volatile ( \
|
|
||||||
"mov %2, %%fs:(%1)\n" \
|
|
||||||
: \
|
|
||||||
"=D" (_dummy) \
|
|
||||||
: \
|
|
||||||
"0" (addr + (7 + offset) * sizeof(L4_Word_t)), \
|
|
||||||
"r" (item)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#undef __PLUS32
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__L4__AMD64__TRACEBUFFER_H__ */
|
#endif /* !__L4__AMD64__TRACEBUFFER_H__ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2003, 2005-2007, Karlsruhe University
|
* Copyright (C) 2002-2003, 2005-2007, 2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: l4/ia32/specials.h
|
* File path: l4/ia32/specials.h
|
||||||
* Description: x86 specific functions and defines
|
* Description: x86 specific functions and defines
|
||||||
|
@ -29,14 +29,22 @@
|
||||||
* $Id: specials.h,v 1.12 2006/11/17 16:48:17 skoglund Exp $
|
* $Id: specials.h,v 1.12 2006/11/17 16:48:17 skoglund Exp $
|
||||||
*
|
*
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#ifndef __L4__X86__SPECIALS_H__
|
#ifndef __L4__IA32__SPECIALS_H__
|
||||||
#define __L4__X86__SPECIALS_H__
|
#define __L4__IA32__SPECIALS_H__
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Architecture specific helper functions.
|
* Architecture specific helper functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
L4_INLINE void __L4_Inc_Atomic (L4_Word_t *w)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"/* l4_inc_atomic() */\n"
|
||||||
|
"lock; add $1, %0"
|
||||||
|
: "=m"(w));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
L4_INLINE int __L4_Msb (L4_Word_t w) __attribute__ ((const));
|
L4_INLINE int __L4_Msb (L4_Word_t w) __attribute__ ((const));
|
||||||
|
|
||||||
L4_INLINE int __L4_Msb (L4_Word_t w)
|
L4_INLINE int __L4_Msb (L4_Word_t w)
|
||||||
|
@ -74,6 +82,31 @@ L4_INLINE int __L4_Lsb (L4_Word_t w)
|
||||||
return bitnum;
|
return bitnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
L4_INLINE L4_Word64_t __L4_Rdtsc ()
|
||||||
|
{
|
||||||
|
L4_Word_t eax, edx;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"/* l4_rdtsc() */ \n"
|
||||||
|
"rdtsc"
|
||||||
|
: "=a"(eax), "=d"(edx));
|
||||||
|
|
||||||
|
return (((L4_Word64_t)edx) << 32) | (L4_Word64_t)eax;
|
||||||
|
}
|
||||||
|
|
||||||
|
L4_INLINE L4_Word64_t __L4_Rdpmc (const L4_Word_t ctrsel)
|
||||||
|
{
|
||||||
|
L4_Word_t eax, edx;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"/* l4_rdpmc() */ \n"
|
||||||
|
"rdpmc"
|
||||||
|
: "=a"(eax), "=d"(edx)
|
||||||
|
: "c"(ctrsel));
|
||||||
|
|
||||||
|
return (((L4_Word64_t)edx) << 32) | (L4_Word64_t)eax;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control parameter for SpaceControl system call.
|
* Control parameter for SpaceControl system call.
|
||||||
*/
|
*/
|
||||||
|
@ -113,5 +146,4 @@ L4_INLINE L4_Word_t L4_SmallSpace (L4_Word_t location, L4_Word_t size)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__L4__IA32__SPECIALS_H__ */
|
||||||
#endif /* !__L4__X86__SPECIALS_H__ */
|
|
||||||
|
|
|
@ -30,245 +30,69 @@
|
||||||
#ifndef __L4__IA32__TRACEBUFFER_H__
|
#ifndef __L4__IA32__TRACEBUFFER_H__
|
||||||
#define __L4__IA32__TRACEBUFFER_H__
|
#define __L4__IA32__TRACEBUFFER_H__
|
||||||
|
|
||||||
#include <l4/types.h>
|
#include __L4_INC_ARCH(specials.h)
|
||||||
|
|
||||||
/* Turn preprocessor symbol definition into string */
|
/**********************************************************************
|
||||||
#define MKSTR(sym) MKSTR2(sym)
|
* Sample PMC energy weights
|
||||||
#define MKSTR2(sym) #sym
|
**********************************************************************/
|
||||||
|
/* Pentium D */
|
||||||
|
#define X86_PMC_TSC_WEIGHT (1418)
|
||||||
|
#define X86_PMC_UC_WEIGHT (1285)
|
||||||
|
#define X86_PMC_LDM_WEIGHT (881)
|
||||||
|
#define X86_PMC_MR_WEIGHT (649)
|
||||||
|
#define X86_PMC_MB_WEIGHT (23421)
|
||||||
|
#define X86_PMC_MLR_WEIGHT (4320)
|
||||||
|
#define X86_PMC_RB_WEIGHT (840)
|
||||||
|
#define X86_PMC_MQW_WEIGHT (75)
|
||||||
|
|
||||||
#if defined(L4_64BIT)
|
#define X86_PMC_TSC_SHIFT 6
|
||||||
# define __PLUS32 + 32
|
#define X86_PMC_UC (0)
|
||||||
#else
|
#define X86_PMC_MLR (1)
|
||||||
# define __PLUS32
|
#define X86_PMC_MQW (4)
|
||||||
#endif
|
#define X86_PMC_RB (5)
|
||||||
|
#define X86_PMC_MB (12)
|
||||||
|
#define X86_PMC_MR (13)
|
||||||
|
#define X86_PMC_LDM (14)
|
||||||
|
|
||||||
|
L4_INLINE void L4_Tbuf_StoreRecordArch(L4_TraceRecord_t *rec, L4_TraceConfig_t config)
|
||||||
#define L4_TRACEBUFFER_MAGIC (0x143acebf)
|
|
||||||
#define L4_TRACEBUFFER_NUM_ARGS (9)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A tracebuffer record indicates the type of event, the time of the
|
|
||||||
* event, the current thread, a number of event specific parameters,
|
|
||||||
* and potentially the current performance counters.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
struct {
|
rec->tsc = __L4_Rdtsc();
|
||||||
L4_Word_t utype : 16;
|
|
||||||
L4_Word_t __pad0 : 16 __PLUS32;
|
|
||||||
L4_Word_t cpu : 16;
|
|
||||||
L4_Word_t id : 16 __PLUS32;
|
|
||||||
} X;
|
|
||||||
|
|
||||||
L4_Word_t tsc;
|
if (config.X.pmon)
|
||||||
L4_Word_t thread;
|
{
|
||||||
L4_Word_t pmc0;
|
switch (config.X.pmon_cpu)
|
||||||
L4_Word_t pmc1;
|
{
|
||||||
L4_Word_t str;
|
case 0:
|
||||||
L4_Word_t data[9];
|
// P2/P3/K8
|
||||||
} L4_TraceRecord_t;
|
rec->pmc0 = __L4_Rdpmc(0);
|
||||||
|
rec->pmc1 = __L4_Rdpmc(1);
|
||||||
|
break;
|
||||||
/*
|
case 1:
|
||||||
* Access to performance monitoring counters
|
// P4
|
||||||
*/
|
if (config.X.pmon_e)
|
||||||
|
{
|
||||||
#include <l4/ia32/arch.h>
|
L4_Word64_t pmce =
|
||||||
|
X86_PMC_TSC_WEIGHT * __L4_Rdtsc() +
|
||||||
#define __L4_TBUF_RDPMC_WEIGHTED(nr, weight, op) \
|
X86_PMC_UC_WEIGHT * __L4_Rdpmc(X86_PMC_UC) +
|
||||||
" mov $"MKSTR(nr)", %%ecx \n" /* select pmc */ \
|
X86_PMC_MLR_WEIGHT * __L4_Rdpmc(X86_PMC_MLR) +
|
||||||
" "#op" \n" /* pmc/tsc in %edx:%eax */ \
|
X86_PMC_MQW_WEIGHT * __L4_Rdpmc(X86_PMC_MQW) +
|
||||||
" mov %%edx, %%esi \n" /* save pmc_hi */ \
|
X86_PMC_RB_WEIGHT * __L4_Rdpmc(X86_PMC_RB) +
|
||||||
" mov $"MKSTR(weight)", %%ecx \n" /* load weight */ \
|
X86_PMC_MB_WEIGHT * __L4_Rdpmc(X86_PMC_MB) +
|
||||||
" mul %%ecx \n" /* r1 = pmc_lo * weight */ \
|
X86_PMC_MR_WEIGHT * __L4_Rdpmc(X86_PMC_MR) +
|
||||||
" mov %%edx, %%ebx \n" /* save r1_hi */ \
|
X86_PMC_LDM_WEIGHT * __L4_Rdpmc(X86_PMC_LDM);
|
||||||
" xchg %%eax, %%ecx \n" /* r1_lo <-> weight */ \
|
|
||||||
" mul %%esi \n" /* r2 = weight * pmc_hi */ \
|
rec->pmc0 = (L4_Word_t) pmce;
|
||||||
" add %%ebx, %%eax \n" /* r2_lo += r1_hi */ \
|
rec->pmc1 = (L4_Word_t) (pmce >> 32);
|
||||||
" addl %%ecx, %%fs:4*%c9(%0) \n" /* result_lo */ \
|
}
|
||||||
" adcl %%eax, %%fs:5*%c9(%0) \n" /* result_hi */
|
else
|
||||||
|
{
|
||||||
|
rec->pmc0 = (L4_Word_t) __L4_Rdpmc(12);
|
||||||
|
rec->pmc1 = (L4_Word_t) __L4_Rdpmc(14);
|
||||||
#define __L4_TBUF_RDPMCS \
|
}
|
||||||
/* Get config into rbx/ebx */ \
|
break;
|
||||||
" push %%ebx \n" /* save ebx */ \
|
default:
|
||||||
" movl %%fs:4*%c9, %%ebx \n" \
|
break;
|
||||||
" test $2, %%ebx \n" \
|
}
|
||||||
" jz 5f \n" /* no pmon, rdtsc only */ \
|
}
|
||||||
" test $4, %%ebx \n" \
|
}
|
||||||
" jz 4f \n" /* P2/K8 pmon */ \
|
|
||||||
" test $8, %%ebx \n" \
|
|
||||||
" jz 3f \n" /* P4 pmon */ \
|
|
||||||
/* P4 PerfMon Energy */ \
|
|
||||||
" push %%ebx \n" /* save ebx */ \
|
|
||||||
" push %%esi \n" /* save esi */ \
|
|
||||||
" movl $0, %%fs:4*%c9(%0) \n" /* result_lo */ \
|
|
||||||
" movl $0, %%fs:5*%c9(%0) \n" /* result_hi */ \
|
|
||||||
__L4_TBUF_RDPMC_WEIGHTED(L4_X86_PMC_UC, L4_X86_PMC_UC_WEIGHT, rdpmc) \
|
|
||||||
__L4_TBUF_RDPMC_WEIGHTED(L4_X86_PMC_RB, L4_X86_PMC_RB_WEIGHT, rdpmc) \
|
|
||||||
__L4_TBUF_RDPMC_WEIGHTED(L4_X86_PMC_MR, L4_X86_PMC_MR_WEIGHT, rdpmc) \
|
|
||||||
__L4_TBUF_RDPMC_WEIGHTED(L4_X86_PMC_LDM, L4_X86_PMC_LDM_WEIGHT, rdpmc) \
|
|
||||||
__L4_TBUF_RDPMC_WEIGHTED(L4_X86_PMC_TSC, L4_X86_PMC_TSC_WEIGHT, rdtsc) \
|
|
||||||
" pop %%esi \n" /* restore esi */ \
|
|
||||||
" pop %%ebx \n" /* restore ebx */ \
|
|
||||||
" rdtsc \n" \
|
|
||||||
" shrd $"MKSTR(L4_X86_PMC_TSC_SHIFT)", %%edx, %%eax\n" \
|
|
||||||
" mov %%eax, %%fs:2*%c9(%0) \n" \
|
|
||||||
" jmp 6f \n" \
|
|
||||||
"3: \n" \
|
|
||||||
/* P4 PerfMon */ \
|
|
||||||
" mov $12, %1 \n" \
|
|
||||||
" rdpmc \n" \
|
|
||||||
" movl %%eax, %%fs:4*%c9(%0) \n" \
|
|
||||||
" add $2, %1 \n" \
|
|
||||||
" rdpmc \n" \
|
|
||||||
" movl %%eax, %%fs:5*%c9(%0) \n" \
|
|
||||||
" jmp 5f \n" \
|
|
||||||
"4: \n" \
|
|
||||||
/* P2/K8 PerfMon */ \
|
|
||||||
" xor %1, %1 \n" \
|
|
||||||
" rdpmc \n" \
|
|
||||||
" movl %%eax, %%fs:4*%c9(%0) \n" \
|
|
||||||
" mov $1, %1 \n" \
|
|
||||||
" rdpmc \n" \
|
|
||||||
" movl %%eax, %%fs:5*%c9(%0) \n" \
|
|
||||||
"5: \n" \
|
|
||||||
" rdtsc \n" \
|
|
||||||
" mov %%eax, %%fs:2*%c9(%0) \n" \
|
|
||||||
"6: \n" \
|
|
||||||
" pop %%ebx \n" /* restore ebx */ \
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tracebuffer access macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __L4_TBUF_INCREASE_COUNTER(ctr) \
|
|
||||||
do { \
|
|
||||||
asm volatile ( \
|
|
||||||
" testl $1, %%fs:4*%c1 \n" \
|
|
||||||
" jz 2f \n" \
|
|
||||||
" lock; \n" \
|
|
||||||
" inc %%fs:8*%c1(%0) \n" \
|
|
||||||
: \
|
|
||||||
: \
|
|
||||||
"r" ((ctr & 0x7) * 4), \
|
|
||||||
"i" (sizeof(L4_Word_t))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define __L4_TBUF_GET_NEXT_RECORD(type, id) \
|
|
||||||
({ \
|
|
||||||
L4_Word_t _dummy, _addr; \
|
|
||||||
asm volatile ( \
|
|
||||||
/* Check wheter to filter the event */ \
|
|
||||||
" mov %%fs:2*%c9, %3 \n" \
|
|
||||||
" and %1, %3 \n" \
|
|
||||||
" jz 7f \n" \
|
|
||||||
" or %2, %1 \n" \
|
|
||||||
\
|
|
||||||
/* Get record offset into EDI */ \
|
|
||||||
"1: mov %%fs:1*%c9, %3 \n" \
|
|
||||||
" mov %8, %0 \n" \
|
|
||||||
" mov %0, %2 \n" \
|
|
||||||
" add %3, %0 \n" \
|
|
||||||
" and %%fs:3*%c9, %0 \n" \
|
|
||||||
" cmovz %2, %0 \n" \
|
|
||||||
" testl $1, %%fs:4*%c9 \n" \
|
|
||||||
" jz 2f \n" \
|
|
||||||
" lock; \n" \
|
|
||||||
"2: \n" \
|
|
||||||
" cmpxchg %0, %%fs:1*%c9 \n" \
|
|
||||||
" jnz 1b \n" \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
/* Store type, cpu, id, thread, counters */ \
|
|
||||||
" mov %1, %2 \n" \
|
|
||||||
" movzx %%cx, %%ecx \n" \
|
|
||||||
" movl %%ecx, %%fs:(%0) \n" \
|
|
||||||
" mov %%gs:0, %1 \n" \
|
|
||||||
" movw "MKSTR(__L4_TCR_PROCESSOR_NO)"*%c9(%1), %%dx\n" \
|
|
||||||
" movl %%edx, %%fs:1*%c9(%0) \n" \
|
|
||||||
" mov "MKSTR(__L4_TCR_MY_GLOBAL_ID)"*%c9(%1), %2\n" \
|
|
||||||
" mov %2, %%fs:3*%c9(%0) \n" \
|
|
||||||
__L4_TBUF_RDPMCS \
|
|
||||||
"7: \n" \
|
|
||||||
: \
|
|
||||||
"=D" (_addr), /* 0 */ \
|
|
||||||
"=c" (_dummy), /* 1 */ \
|
|
||||||
"=d" (_dummy), /* 2 */ \
|
|
||||||
"=a" (_dummy) /* 3 */ \
|
|
||||||
: \
|
|
||||||
"0" (0), /* 4 */ \
|
|
||||||
"1" (type & 0xffff), /* 5 */ \
|
|
||||||
"2" ((id & 0xffff)<<16), /* 6 */ \
|
|
||||||
"3" (0), /* 7 */ \
|
|
||||||
"i" (sizeof (L4_TraceRecord_t)), /* 8 */ \
|
|
||||||
"i" (sizeof(L4_Word_t)) /* 9 */ \
|
|
||||||
); \
|
|
||||||
_addr; \
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record (format) string into event buffer.
|
|
||||||
*
|
|
||||||
* @param addr offset of event record
|
|
||||||
* @param offset string to be recorded
|
|
||||||
*/
|
|
||||||
#define __L4_TBUF_STORE_STR(addr, str) \
|
|
||||||
do { \
|
|
||||||
* (volatile char *) str; \
|
|
||||||
asm volatile ( \
|
|
||||||
"mov %0, %%fs:6*%c2(%1)\n" \
|
|
||||||
: \
|
|
||||||
: \
|
|
||||||
"r" (str), \
|
|
||||||
"D" (addr), \
|
|
||||||
"i" (sizeof(L4_Word_t))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record arguments into event buffer at indicated location.
|
|
||||||
*
|
|
||||||
* @param addr offset of event record
|
|
||||||
* @param offset offset within event record
|
|
||||||
* @param item value to be recorded
|
|
||||||
*/
|
|
||||||
#define __L4_TBUF_STORE_DATA(addr, offset, item) \
|
|
||||||
do { \
|
|
||||||
L4_Word_t _dummy; \
|
|
||||||
asm volatile ( \
|
|
||||||
"mov %2, %%fs:(%1)\n" \
|
|
||||||
: \
|
|
||||||
"=D" (_dummy) \
|
|
||||||
: \
|
|
||||||
"0" (addr + (7 + offset) * sizeof(L4_Word_t)), \
|
|
||||||
"r" (item)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record arguments into event buffer at indicated location.
|
|
||||||
*
|
|
||||||
* @param addr offset of event record
|
|
||||||
* @param offset offset within event record
|
|
||||||
* @param item value to be recorded
|
|
||||||
*/
|
|
||||||
#define L4_TBUF_SET_TYPEMASK(mask) \
|
|
||||||
do { \
|
|
||||||
L4_Word_t _dummy; \
|
|
||||||
asm volatile ( \
|
|
||||||
"mov %0, %%fs:2*%c2 \n" \
|
|
||||||
: \
|
|
||||||
"=D" (_dummy) \
|
|
||||||
: \
|
|
||||||
"0" (mask), \
|
|
||||||
"i" (sizeof(L4_Word_t))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#undef __PLUS32
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__L4__IA32__TRACEBUFFER_H__ */
|
#endif /* !__L4__IA32__TRACEBUFFER_H__ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2004, 2006-2007, Karlsruhe University
|
* Copyright (C) 2001-2004, 2006-2007, 2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: l4/kip.h
|
* File path: l4/kip.h
|
||||||
* Description: Kernel interface page definitions.
|
* Description: Kernel interface page definitions.
|
||||||
|
@ -553,6 +553,26 @@ L4_INLINE char * L4_Feature (void * KernelInterface, L4_Word_t num)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
L4_INLINE L4_Bool_t L4_HasFeature (const char *feature_name)
|
||||||
|
{
|
||||||
|
void *kip = L4_GetKernelInterface();
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
for( L4_Word_t i = 0; (name = L4_Feature(kip,i)) != '\0'; i++ )
|
||||||
|
{
|
||||||
|
const char *n = name;
|
||||||
|
const char *fn = feature_name;
|
||||||
|
|
||||||
|
while (*n == *fn++)
|
||||||
|
if (*n++ == 0)
|
||||||
|
return true;
|
||||||
|
if (*(L4_Word8_t *)n - *(L4_Word8_t *)--fn)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
L4_Word_t raw[2];
|
L4_Word_t raw[2];
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -33,6 +33,26 @@
|
||||||
#ifndef __L4__POWERPC__SPECIALS_H__
|
#ifndef __L4__POWERPC__SPECIALS_H__
|
||||||
#define __L4__POWERPC__SPECIALS_H__
|
#define __L4__POWERPC__SPECIALS_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Architecture specific helper functions.
|
||||||
|
*/
|
||||||
|
L4_INLINE void __L4_Inc_Atomic (L4_Word_t *w)
|
||||||
|
{
|
||||||
|
L4_Word_t dummy;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"/* l4_inc_atomic() */\n"
|
||||||
|
"sync\n"
|
||||||
|
"1: lwarx %0,0,%1\n"
|
||||||
|
" addic %0,%0,1\n"
|
||||||
|
" stwcx. %0,0,%1 \n"
|
||||||
|
" bne- 1b"
|
||||||
|
"isync\n"
|
||||||
|
: "=&r" (dummy)
|
||||||
|
: "r" (w)
|
||||||
|
: "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
L4_INLINE int __L4_Msb( L4_Word_t w ) __attribute__ ((const));
|
L4_INLINE int __L4_Msb( L4_Word_t w ) __attribute__ ((const));
|
||||||
|
|
||||||
L4_INLINE int __L4_Msb( L4_Word_t w )
|
L4_INLINE int __L4_Msb( L4_Word_t w )
|
||||||
|
@ -59,3 +79,4 @@ L4_INLINE L4_Fpage_t L4_Fpage (L4_Fpage_t f)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __L4__POWERPC__SPECIALS_H__ */
|
#endif /* __L4__POWERPC__SPECIALS_H__ */
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (C) 1999-2010, Karlsruhe University
|
* Copyright (C) 1999-2010, Karlsruhe University
|
||||||
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
|
||||||
*
|
*
|
||||||
* File path: include/l4/tracebuffer.h
|
* File path: l4/tracebuffer.h
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -34,78 +34,162 @@
|
||||||
#ifndef __L4__TRACEBUFFER_H__
|
#ifndef __L4__TRACEBUFFER_H__
|
||||||
#define __L4__TRACEBUFFER_H__
|
#define __L4__TRACEBUFFER_H__
|
||||||
|
|
||||||
/* use
|
|
||||||
* L4_TRACEBUFFER
|
|
||||||
* to enable tracebuffer and tbuf performance counting
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(L4_TRACEBUFFER)
|
|
||||||
|
|
||||||
#include <l4/thread.h>
|
#include <l4/thread.h>
|
||||||
#include __L4_INC_ARCH(tracebuffer.h)
|
|
||||||
|
|
||||||
|
#if defined(L4_64BIT)
|
||||||
|
# define __PLUS32 + 32
|
||||||
|
# define L4_TRACEBUFFER_MAGIC (0x1464b123acebf)
|
||||||
|
#else
|
||||||
|
# define __PLUS32
|
||||||
|
# define L4_TRACEBUFFER_MAGIC (0x1464b123)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define L4_TRACEBUFFER_NUM_ARGS (9)
|
||||||
#define L4_TRACEBUFFER_USERID_START (100)
|
#define L4_TRACEBUFFER_USERID_START (100)
|
||||||
#define L4_TRACEBUFFER_DEFAULT_TYPE (0x1)
|
#define L4_TRACEBUFFER_DEFAULT_TYPE (0x1)
|
||||||
|
|
||||||
|
typedef union{
|
||||||
|
struct {
|
||||||
|
L4_Word_t smp : 1; // SMP
|
||||||
|
L4_Word_t pmon : 1; // Enable perf monitoring
|
||||||
|
L4_Word_t pmon_cpu : 2; // CPU: x86: 00=P2/P3/K8, 01=P4
|
||||||
|
L4_Word_t pmon_e : 2; // Enable energy monitoring
|
||||||
|
L4_Word_t : 26 __PLUS32;
|
||||||
|
} X;
|
||||||
|
L4_Word_t raw;
|
||||||
|
} L4_TraceConfig_t;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A tracebuffer record indicates the type of event, the time of the
|
||||||
|
* event, the current thread, a number of event specific parameters,
|
||||||
|
* and potentially the current performance counters.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
L4_Word_t utype : 16;
|
||||||
|
L4_Word_t __pad0 : 16 __PLUS32;
|
||||||
|
L4_Word_t cpu : 16;
|
||||||
|
L4_Word_t id : 16 __PLUS32;
|
||||||
|
} X;
|
||||||
|
|
||||||
|
L4_Word_t tsc;
|
||||||
|
L4_Word_t thread;
|
||||||
|
L4_Word_t pmc0;
|
||||||
|
L4_Word_t pmc1;
|
||||||
|
L4_Word_t str;
|
||||||
|
L4_Word_t data[9];
|
||||||
|
} L4_TraceRecord_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
L4_Word_t magic;
|
||||||
|
L4_Word_t current;
|
||||||
|
L4_Word_t mask;
|
||||||
|
L4_Word_t max;
|
||||||
|
L4_TraceConfig_t config;
|
||||||
|
L4_Word_t __pad[3];
|
||||||
|
L4_Word_t counters[8];
|
||||||
|
L4_TraceRecord_t tracerecords[];
|
||||||
|
} L4_TraceBuffer_t;
|
||||||
|
|
||||||
|
#include __L4_INC_ARCH(tracebuffer.h)
|
||||||
|
|
||||||
|
extern L4_TraceBuffer_t *L4_GetTraceBuffer();
|
||||||
|
|
||||||
|
L4_INLINE void L4_Tbuf_StoreRecord(L4_TraceRecord_t *rec, const L4_TraceConfig_t config, L4_Word_t type, L4_Word_t id)
|
||||||
|
{
|
||||||
|
/* Store type, cpu, id, thread, counters */
|
||||||
|
rec->X.utype = type;
|
||||||
|
rec->X.id = id;
|
||||||
|
rec->X.cpu = L4_ProcessorNo();
|
||||||
|
rec->thread = L4_Myself().raw;
|
||||||
|
L4_Tbuf_StoreRecordArch(rec, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
L4_INLINE L4_TraceRecord_t *L4_Tbuf_NextRecord(L4_Word_t type, L4_Word_t id)
|
||||||
|
{
|
||||||
|
L4_TraceBuffer_t *__L4_tbuf = L4_GetTraceBuffer();
|
||||||
|
if (!__L4_tbuf) return 0;
|
||||||
|
|
||||||
|
/* Check wheter to filter the event */
|
||||||
|
if ((__L4_tbuf->mask & ((type & 0xffff) << 16)) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
//__L4_Inc_Atomic (&__L4_tbuf->current);
|
||||||
|
if (__L4_tbuf->current == __L4_tbuf->max)
|
||||||
|
__L4_tbuf->current = 0;
|
||||||
|
|
||||||
|
/* Store type, cpu, id, thread, counters */
|
||||||
|
L4_Tbuf_StoreRecord(__L4_tbuf->tracerecords + __L4_tbuf->current, __L4_tbuf->config, type, id);
|
||||||
|
|
||||||
|
return __L4_tbuf->tracerecords + __L4_tbuf->current;
|
||||||
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_IncCounter (L4_Word_t counter)
|
L4_INLINE void L4_Tbuf_IncCounter (L4_Word_t counter)
|
||||||
{
|
{
|
||||||
__L4_TBUF_INCREASE_COUNTER (counter);
|
L4_TraceBuffer_t *__L4_tbuf = L4_GetTraceBuffer();
|
||||||
|
if (!__L4_tbuf) return;
|
||||||
|
__L4_tbuf->counters[counter & 0x7]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_RecordEvent_t0 (L4_Word_t id, const char * str)
|
L4_INLINE void L4_Tbuf_RecordEvent_t0 (L4_Word_t id, const char * str)
|
||||||
{
|
{
|
||||||
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
||||||
if (addr == 0)
|
if (rec == 0)
|
||||||
return;
|
return;
|
||||||
__L4_TBUF_STORE_STR (addr, str);
|
|
||||||
|
rec->str = (L4_Word_t) str;
|
||||||
}
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_RecordEvent_t1 (L4_Word_t id, const char * str,
|
L4_INLINE void L4_Tbuf_RecordEvent_t1 (L4_Word_t id, const char * str,
|
||||||
L4_Word_t p0)
|
L4_Word_t p0)
|
||||||
{
|
{
|
||||||
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
||||||
if (addr == 0)
|
if (rec == 0)
|
||||||
return;
|
return;
|
||||||
__L4_TBUF_STORE_STR (addr, str);
|
rec->str = (L4_Word_t) str;
|
||||||
__L4_TBUF_STORE_DATA (addr, 0, p0);
|
rec->data[0] = p0;
|
||||||
}
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_RecordEvent_t2 (L4_Word_t id, const char * str,
|
L4_INLINE void L4_Tbuf_RecordEvent_t2 (L4_Word_t id, const char * str,
|
||||||
L4_Word_t p0, L4_Word_t p1)
|
L4_Word_t p0, L4_Word_t p1)
|
||||||
{
|
{
|
||||||
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
||||||
if (addr == 0)
|
if (rec == 0)
|
||||||
return;
|
return;
|
||||||
__L4_TBUF_STORE_STR (addr, str);
|
rec->str = (L4_Word_t) str;
|
||||||
__L4_TBUF_STORE_DATA (addr, 0, p0);
|
rec->data[0] = p0;
|
||||||
__L4_TBUF_STORE_DATA (addr, 1, p1);
|
rec->data[1] = p1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_RecordEvent_t3 (L4_Word_t id, const char * str,
|
L4_INLINE void L4_Tbuf_RecordEvent_t3 (L4_Word_t id, const char * str,
|
||||||
L4_Word_t p0, L4_Word_t p1,
|
L4_Word_t p0, L4_Word_t p1,
|
||||||
L4_Word_t p2)
|
L4_Word_t p2)
|
||||||
{
|
{
|
||||||
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
||||||
if (addr == 0)
|
if (rec == 0)
|
||||||
return;
|
return;
|
||||||
__L4_TBUF_STORE_STR (addr, str);
|
rec->str = (L4_Word_t) str;
|
||||||
__L4_TBUF_STORE_DATA (addr, 0, p0);
|
rec->data[0] = p0;
|
||||||
__L4_TBUF_STORE_DATA (addr, 1, p1);
|
rec->data[1] = p1;
|
||||||
__L4_TBUF_STORE_DATA (addr, 2, p2);
|
rec->data[2] = p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_RecordEvent_t4 (L4_Word_t id, const char * str,
|
L4_INLINE void L4_Tbuf_RecordEvent_t4 (L4_Word_t id, const char * str,
|
||||||
L4_Word_t p0, L4_Word_t p1,
|
L4_Word_t p0, L4_Word_t p1,
|
||||||
L4_Word_t p2, L4_Word_t p3)
|
L4_Word_t p2, L4_Word_t p3)
|
||||||
{
|
{
|
||||||
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
|
||||||
if (addr == 0)
|
if (rec == 0)
|
||||||
return;
|
return;
|
||||||
__L4_TBUF_STORE_STR (addr, str);
|
rec->str = (L4_Word_t) str;
|
||||||
__L4_TBUF_STORE_DATA (addr, 0, p0);
|
rec->data[0] = p0;
|
||||||
__L4_TBUF_STORE_DATA (addr, 1, p1);
|
rec->data[1] = p1;
|
||||||
__L4_TBUF_STORE_DATA (addr, 2, p2);
|
rec->data[2] = p2;
|
||||||
__L4_TBUF_STORE_DATA (addr, 3, p3);
|
rec->data[3] = p3;
|
||||||
}
|
}
|
||||||
|
|
||||||
L4_INLINE void L4_Tbuf_RecordEvent_0 (L4_Word_t id, const char * str)
|
L4_INLINE void L4_Tbuf_RecordEvent_0 (L4_Word_t id, const char * str)
|
||||||
|
@ -171,15 +255,7 @@ L4_INLINE void L4_Tbuf_RecordEvent (L4_Word_t id, const char * str,
|
||||||
L4_Tbuf_RecordEvent_4 (id, str, p0, p1, p2, p3);
|
L4_Tbuf_RecordEvent_4 (id, str, p0, p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#else /* !TRACEBUFFER */
|
|
||||||
#define L4_Tbuf_RecordEvent_0(args...)
|
|
||||||
#define L4_Tbuf_RecordEvent_1(args...)
|
|
||||||
#define L4_Tbuf_RecordEvent_2(args...)
|
|
||||||
#define L4_Tbuf_RecordEvent_3(args...)
|
|
||||||
#define L4_Tbuf_RecordEvent_4(args...)
|
|
||||||
#define L4_Tbuf_RecordEvent(args...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !__L4__TRACEBUFFER_H__ */
|
#endif /* !__L4__TRACEBUFFER_H__ */
|
||||||
|
|
|
@ -36,14 +36,10 @@ top_builddir= @top_builddir@
|
||||||
include $(top_srcdir)/Mk/l4.base.mk
|
include $(top_srcdir)/Mk/l4.base.mk
|
||||||
|
|
||||||
|
|
||||||
ia32_SRCS= ia32-getc.cc ia32-putc.cc
|
powerpc_SRCS= 1275tree.cc fdt.cc
|
||||||
powerpc_SRCS= powerpc-io.cc 1275tree.cc fdt.cc
|
|
||||||
powerpc64_SRCS= powerpc64-getc.cc powerpc64-putc.cc
|
|
||||||
amd64_SRCS= amd64-getc.cc amd64-putc.cc
|
|
||||||
|
|
||||||
LIBRARY= io
|
LIBRARY= io
|
||||||
SRCS= get_hex.cc print.cc $($(ARCH)_SRCS)
|
SRCS= get_hex.cc print.cc $(ARCH).cc $($(ARCH)_SRCS)
|
||||||
|
|
||||||
|
|
||||||
include $(top_srcdir)/Mk/l4.lib.mk
|
include $(top_srcdir)/Mk/l4.lib.mk
|
||||||
|
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*********************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001-2003, Karlsruhe University
|
|
||||||
*
|
|
||||||
* File path: amd64-putc.cc
|
|
||||||
* Description: putc() for amd64-based PCs, serial and screen
|
|
||||||
*
|
|
||||||
* 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: amd64-putc.cc,v 1.4 2006/10/19 22:57:40 ud3 Exp $
|
|
||||||
*
|
|
||||||
********************************************************************/
|
|
||||||
#include <config.h>
|
|
||||||
#include <l4/types.h>
|
|
||||||
|
|
||||||
#include "amd64-port.h"
|
|
||||||
|
|
||||||
extern "C" void __l4_putc (int c);
|
|
||||||
extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
|
||||||
|
|
||||||
#if defined(CONFIG_COMPORT)
|
|
||||||
#if CONFIG_COMPORT == 0
|
|
||||||
# define COMPORT 0x3f8
|
|
||||||
#elif CONFIG_COMPORT == 1
|
|
||||||
# define COMPORT 0x2f8
|
|
||||||
#elif CONFIG_COMPORT == 2
|
|
||||||
# define COMPORT 0x3e8
|
|
||||||
#elif CONFIG_COMPORT == 3
|
|
||||||
# define COMPORT 0x2e8
|
|
||||||
#else
|
|
||||||
#define COMPORT CONFIG_COMPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void __l4_putc(int c)
|
|
||||||
{
|
|
||||||
while (!(inb(COMPORT+5) & 0x60));
|
|
||||||
outb(COMPORT,c);
|
|
||||||
if (c == '\n')
|
|
||||||
putc('\r');
|
|
||||||
}
|
|
||||||
#else /* ! CONFIG_COMPORT */
|
|
||||||
|
|
||||||
#define DISPLAY ((char*)0xb8000)
|
|
||||||
#define COLOR 7
|
|
||||||
#define NUM_LINES 25
|
|
||||||
unsigned __cursor;
|
|
||||||
|
|
||||||
void __l4_putc(int c)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
static int initialized = 0;
|
|
||||||
|
|
||||||
if (! initialized)
|
|
||||||
{
|
|
||||||
__cursor = NUM_LINES * 160 - 2;
|
|
||||||
while (__cursor >= 0)
|
|
||||||
if (DISPLAY[__cursor] != ' ' && DISPLAY[__cursor] != 0)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
__cursor -= 2;
|
|
||||||
|
|
||||||
__cursor += (160 - (__cursor % 160));
|
|
||||||
initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(c) {
|
|
||||||
case '\r':
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DISPLAY[__cursor++] = ' ';
|
|
||||||
DISPLAY[__cursor++] = COLOR;
|
|
||||||
}
|
|
||||||
while (__cursor % 160 != 0);
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DISPLAY[__cursor++] = ' ';
|
|
||||||
DISPLAY[__cursor++] = COLOR;
|
|
||||||
}
|
|
||||||
while (__cursor % 16 != 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DISPLAY[__cursor++] = c;
|
|
||||||
DISPLAY[__cursor++] = COLOR;
|
|
||||||
}
|
|
||||||
if (__cursor == (160 * NUM_LINES)) {
|
|
||||||
for (i = (160 / sizeof (L4_Word_t));
|
|
||||||
i < (160 / sizeof (L4_Word_t)) * NUM_LINES;
|
|
||||||
i++)
|
|
||||||
((L4_Word_t *) DISPLAY)[i - 160 / sizeof (L4_Word_t)]
|
|
||||||
= ((L4_Word_t *) DISPLAY)[i];
|
|
||||||
for (i = 0; i < 160 / sizeof (L4_Word_t); i++)
|
|
||||||
((L4_Word_t *) DISPLAY)[160 / sizeof (L4_Word_t)
|
|
||||||
* (NUM_LINES-1) + i] = 0;
|
|
||||||
__cursor -= 160;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001-2006, Karlsruhe University
|
* Copyright (C) 2001-2006, 2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: ia32-putc.cc
|
* File path: amd64.cc
|
||||||
* Description: putc() for x86-based PCs, serial and screen
|
* Description: putc() for x86-based PCs, serial and screen
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -32,10 +32,13 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <l4/types.h>
|
#include <l4/types.h>
|
||||||
|
|
||||||
#include "ia32-port.h"
|
#include "amd64.h"
|
||||||
|
|
||||||
extern "C" void __l4_putc (int c);
|
extern "C" void __l4_putc (int c);
|
||||||
extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
||||||
|
extern "C" int __l4_getc (void);
|
||||||
|
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_COMPORT)
|
#if defined(CONFIG_COMPORT)
|
||||||
|
|
||||||
|
@ -51,8 +54,47 @@ extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
||||||
#define COMPORT CONFIG_COMPORT
|
#define COMPORT CONFIG_COMPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void io_init( void )
|
||||||
|
{
|
||||||
|
static bool io_initialized = false;
|
||||||
|
|
||||||
|
if (io_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
io_initialized = true;
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
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 */
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void __l4_putc(int c)
|
void __l4_putc(int c)
|
||||||
{
|
{
|
||||||
|
io_init();
|
||||||
|
|
||||||
while (!(inb(COMPORT+5) & 0x20));
|
while (!(inb(COMPORT+5) & 0x20));
|
||||||
outb(COMPORT,c);
|
outb(COMPORT,c);
|
||||||
while (!(inb(COMPORT+5) & 0x40));
|
while (!(inb(COMPORT+5) & 0x40));
|
||||||
|
@ -60,12 +102,36 @@ void __l4_putc(int c)
|
||||||
__l4_putc('\r');
|
__l4_putc('\r');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __l4_getc (void)
|
||||||
|
{
|
||||||
|
while ((inb(COMPORT+5) & 0x01) == 0);
|
||||||
|
return inb(COMPORT);
|
||||||
|
}
|
||||||
|
|
||||||
#else /* ! CONFIG_COMPORT */
|
#else /* ! CONFIG_COMPORT */
|
||||||
|
|
||||||
#define DISPLAY ((char*)0xb8000)
|
#define DISPLAY ((char*)0xb8000)
|
||||||
#define COLOR 7
|
#define COLOR 7
|
||||||
#define NUM_LINES 25
|
#define NUM_LINES 25
|
||||||
|
|
||||||
|
#define KBD_STATUS_REG 0x64
|
||||||
|
#define KBD_CNTL_REG 0x64
|
||||||
|
#define KBD_DATA_REG 0x60
|
||||||
|
|
||||||
|
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
|
||||||
|
|
||||||
|
#define kbd_read_input() inb(KBD_DATA_REG)
|
||||||
|
#define kbd_read_status() inb(KBD_STATUS_REG)
|
||||||
|
|
||||||
|
static unsigned char keyb_layout[128] =
|
||||||
|
"\000\0331234567890-+\177\t" /* 0x00 - 0x0f */
|
||||||
|
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
|
||||||
|
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
|
||||||
|
"bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
|
||||||
|
"\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
|
||||||
|
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
||||||
|
"\r\000/"; /* 0x60 - 0x6f */
|
||||||
|
|
||||||
void __l4_putc(int c)
|
void __l4_putc(int c)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -115,4 +181,28 @@ void __l4_putc(int c)
|
||||||
__l4_putc_cursor = __cursor;
|
__l4_putc_cursor = __cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No SHIFT key support!!! */
|
||||||
|
|
||||||
|
int __l4_getc()
|
||||||
|
{
|
||||||
|
static unsigned char last_key = 0;
|
||||||
|
char c;
|
||||||
|
while(1) {
|
||||||
|
unsigned char status = kbd_read_status();
|
||||||
|
while (status & KBD_STAT_OBF) {
|
||||||
|
unsigned char scancode;
|
||||||
|
scancode = kbd_read_input();
|
||||||
|
if (scancode & 0x80)
|
||||||
|
last_key = 0;
|
||||||
|
else if (last_key != scancode)
|
||||||
|
{
|
||||||
|
//printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[scancode]);
|
||||||
|
last_key = scancode;
|
||||||
|
c = keyb_layout[scancode];
|
||||||
|
if (c > 0) return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,104 +0,0 @@
|
||||||
/*********************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2001-2004, 2010, Karlsruhe University
|
|
||||||
*
|
|
||||||
* File path: ia32-getc.cc
|
|
||||||
* Description: getc() for x86-based PCs
|
|
||||||
*
|
|
||||||
* 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: ia32-getc.cc,v 1.8 2004/01/29 15:50:05 uhlig Exp $
|
|
||||||
*
|
|
||||||
********************************************************************/
|
|
||||||
#include <l4/types.h>
|
|
||||||
#include "ia32-port.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
extern "C" int __l4_getc (void);
|
|
||||||
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
|
||||||
|
|
||||||
#if defined(CONFIG_COMPORT)
|
|
||||||
|
|
||||||
#if CONFIG_COMPORT == 0
|
|
||||||
# define COMPORT 0x3f8
|
|
||||||
#elif CONFIG_COMPORT == 1
|
|
||||||
# define COMPORT 0x2f8
|
|
||||||
#elif CONFIG_COMPORT == 2
|
|
||||||
# define COMPORT 0x3e8
|
|
||||||
#elif CONFIG_COMPORT == 3
|
|
||||||
# define COMPORT 0x2e8
|
|
||||||
#else
|
|
||||||
#define COMPORT CONFIG_COMPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int __l4_getc (void)
|
|
||||||
{
|
|
||||||
while ((inb(COMPORT+5) & 0x01) == 0);
|
|
||||||
return inb(COMPORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* CONFIG_COMPORT */
|
|
||||||
|
|
||||||
/* No SHIFT key support!!! */
|
|
||||||
|
|
||||||
#define KBD_STATUS_REG 0x64
|
|
||||||
#define KBD_CNTL_REG 0x64
|
|
||||||
#define KBD_DATA_REG 0x60
|
|
||||||
|
|
||||||
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
|
|
||||||
|
|
||||||
#define kbd_read_input() inb(KBD_DATA_REG)
|
|
||||||
#define kbd_read_status() inb(KBD_STATUS_REG)
|
|
||||||
|
|
||||||
static unsigned char keyb_layout[128] =
|
|
||||||
"\000\0331234567890-+\177\t" /* 0x00 - 0x0f */
|
|
||||||
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
|
|
||||||
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
|
|
||||||
"bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
|
|
||||||
"\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
|
|
||||||
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
|
||||||
"\r\000/"; /* 0x60 - 0x6f */
|
|
||||||
|
|
||||||
|
|
||||||
int __l4_getc()
|
|
||||||
{
|
|
||||||
static unsigned char last_key = 0;
|
|
||||||
char c;
|
|
||||||
while(1) {
|
|
||||||
unsigned char status = kbd_read_status();
|
|
||||||
while (status & KBD_STAT_OBF) {
|
|
||||||
unsigned char scancode;
|
|
||||||
scancode = kbd_read_input();
|
|
||||||
if (scancode & 0x80)
|
|
||||||
last_key = 0;
|
|
||||||
else if (last_key != scancode)
|
|
||||||
{
|
|
||||||
//printf("kbd: %d, %d, %c\n", scancode, last_key, keyb_layout[scancode]);
|
|
||||||
last_key = scancode;
|
|
||||||
c = keyb_layout[scancode];
|
|
||||||
if (c > 0) return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2001, 2003-2004, Karlsruhe University
|
* Copyright (C) 2001-2006, 2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: amd64-getc.cc
|
* File path: ia32.cc
|
||||||
* Description: getc() for amd64-based PCs
|
* Description: putc() for x86-based PCs, serial and screen
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -26,17 +26,21 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: amd64-getc.cc,v 1.5 2006/10/19 22:57:40 ud3 Exp $
|
* $Id: ia32-putc.cc,v 1.13 2006/10/07 16:30:25 ud3 Exp $
|
||||||
*
|
*
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <l4/types.h>
|
#include <l4/types.h>
|
||||||
#include "amd64-port.h"
|
#include "ia32.h"
|
||||||
|
|
||||||
|
extern "C" void __l4_putc (int c);
|
||||||
|
extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
||||||
extern "C" int __l4_getc (void);
|
extern "C" int __l4_getc (void);
|
||||||
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_COMPORT)
|
#if defined(CONFIG_COMPORT)
|
||||||
|
|
||||||
#if CONFIG_COMPORT == 0
|
#if CONFIG_COMPORT == 0
|
||||||
# define COMPORT 0x3f8
|
# define COMPORT 0x3f8
|
||||||
#elif CONFIG_COMPORT == 1
|
#elif CONFIG_COMPORT == 1
|
||||||
|
@ -49,14 +53,67 @@ extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
||||||
#define COMPORT CONFIG_COMPORT
|
#define COMPORT CONFIG_COMPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void io_init( void )
|
||||||
|
{
|
||||||
|
static bool io_initialized = false;
|
||||||
|
|
||||||
|
if (io_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
io_initialized = true;
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
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 */
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void __l4_putc(int c)
|
||||||
|
{
|
||||||
|
io_init();
|
||||||
|
|
||||||
|
while (!(inb(COMPORT+5) & 0x20));
|
||||||
|
outb(COMPORT,c);
|
||||||
|
while (!(inb(COMPORT+5) & 0x40));
|
||||||
|
if (c == '\n')
|
||||||
|
__l4_putc('\r');
|
||||||
|
}
|
||||||
|
|
||||||
int __l4_getc (void)
|
int __l4_getc (void)
|
||||||
{
|
{
|
||||||
|
io_init();
|
||||||
|
|
||||||
while ((inb(COMPORT+5) & 0x01) == 0);
|
while ((inb(COMPORT+5) & 0x01) == 0);
|
||||||
return inb(COMPORT);
|
return inb(COMPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_COMPORT */
|
#else /* ! CONFIG_COMPORT */
|
||||||
/* No SHIFT key support!!! */
|
|
||||||
|
#define DISPLAY ((char*)0xb8000)
|
||||||
|
#define COLOR 7
|
||||||
|
#define NUM_LINES 25
|
||||||
|
|
||||||
#define KBD_STATUS_REG 0x64
|
#define KBD_STATUS_REG 0x64
|
||||||
#define KBD_CNTL_REG 0x64
|
#define KBD_CNTL_REG 0x64
|
||||||
|
@ -76,7 +133,58 @@ static unsigned char keyb_layout[128] =
|
||||||
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
||||||
"\r\000/"; /* 0x60 - 0x6f */
|
"\r\000/"; /* 0x60 - 0x6f */
|
||||||
|
|
||||||
int __l4_getc(void)
|
void __l4_putc(int c)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
// Shared cursor pointer
|
||||||
|
static unsigned __l4_putc_cursor = 160 * (NUM_LINES - 1);
|
||||||
|
|
||||||
|
// Create thread-local copy. Using proper locking would be better.
|
||||||
|
unsigned __cursor = __l4_putc_cursor;
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
case '\r':
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DISPLAY[__cursor++] = ' ';
|
||||||
|
DISPLAY[__cursor++] = COLOR;
|
||||||
|
}
|
||||||
|
while (__cursor % 160 != 0);
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DISPLAY[__cursor++] = ' ';
|
||||||
|
DISPLAY[__cursor++] = COLOR;
|
||||||
|
}
|
||||||
|
while (__cursor % 16 != 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DISPLAY[__cursor++] = c;
|
||||||
|
DISPLAY[__cursor++] = COLOR;
|
||||||
|
}
|
||||||
|
if (__cursor == (160 * NUM_LINES)) {
|
||||||
|
for (i = (160 / sizeof (L4_Word_t));
|
||||||
|
i < (160 / sizeof (L4_Word_t)) * NUM_LINES;
|
||||||
|
i++)
|
||||||
|
((L4_Word_t *) DISPLAY)[i - 160 / sizeof (L4_Word_t)]
|
||||||
|
= ((L4_Word_t *) DISPLAY)[i];
|
||||||
|
for (i = 0; i < 160 / sizeof (L4_Word_t); i++)
|
||||||
|
((L4_Word_t *) DISPLAY)[160 / sizeof (L4_Word_t)
|
||||||
|
* (NUM_LINES-1) + i] = 0;
|
||||||
|
__cursor -= 160;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write back thread-local cursor value
|
||||||
|
__l4_putc_cursor = __cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No SHIFT key support!!! */
|
||||||
|
|
||||||
|
int __l4_getc()
|
||||||
{
|
{
|
||||||
static unsigned char last_key = 0;
|
static unsigned char last_key = 0;
|
||||||
char c;
|
char c;
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, Karlsruhe Institute of Technology
|
* Copyright (C) 2010, Karlsruhe Institute of Technology
|
||||||
*
|
*
|
||||||
* Filename: powerpc-io.cc
|
* Filename: powerpc.cc
|
||||||
* Author: Jan Stoess <stoess@kit.edu>
|
* Author: Jan Stoess <stoess@kit.edu>
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
|
@ -48,14 +48,12 @@ extern "C" void putc( int c ) __attribute__ ((weak, alias("__l4_putc")));
|
||||||
#if defined(CONFIG_COMPORT)
|
#if defined(CONFIG_COMPORT)
|
||||||
|
|
||||||
#include <l4/sigma0.h>
|
#include <l4/sigma0.h>
|
||||||
#include "powerpc-port.h"
|
#include "powerpc.h"
|
||||||
#include "fdt.h"
|
#include "fdt.h"
|
||||||
#include "1275tree.h"
|
#include "1275tree.h"
|
||||||
|
|
||||||
static volatile L4_Word8_t *comport = CONFIG_COMPORT;
|
static volatile L4_Word8_t *comport = CONFIG_COMPORT;
|
||||||
static bool io_initialized = false;
|
|
||||||
|
|
||||||
#define DTREE_KIP_SUBTYPE 0xf
|
|
||||||
#define DTREE_KIP_SUBTYPE 0xf
|
#define DTREE_KIP_SUBTYPE 0xf
|
||||||
#define DTREE_KIP_TYPE (L4_BootLoaderSpecificMemoryType + (DTREE_KIP_SUBTYPE << 4))
|
#define DTREE_KIP_TYPE (L4_BootLoaderSpecificMemoryType + (DTREE_KIP_SUBTYPE << 4))
|
||||||
|
|
||||||
|
@ -73,10 +71,9 @@ static L4_Word8_t __attribute__((aligned(4096))) comport_page[4096];
|
||||||
#define DLLO (comport+0)
|
#define DLLO (comport+0)
|
||||||
#define DLHI (comport+1)
|
#define DLHI (comport+1)
|
||||||
|
|
||||||
extern "C" int printf (const char *fmt, ...);
|
|
||||||
|
|
||||||
static void io_init( void )
|
static void io_init( void )
|
||||||
{
|
{
|
||||||
|
static bool io_initialized = false;
|
||||||
|
|
||||||
if (io_initialized)
|
if (io_initialized)
|
||||||
return;
|
return;
|
|
@ -36,6 +36,9 @@
|
||||||
extern "C" void __l4_putc (int c);
|
extern "C" void __l4_putc (int c);
|
||||||
extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
|
||||||
|
|
||||||
|
extern "C" int __l4_getc (void);
|
||||||
|
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
||||||
|
|
||||||
extern "C" void __l4_putc( int c )
|
extern "C" void __l4_putc( int c )
|
||||||
{
|
{
|
||||||
L4_KDB_PrintChar( c );
|
L4_KDB_PrintChar( c );
|
||||||
|
@ -43,3 +46,8 @@ extern "C" void __l4_putc( int c )
|
||||||
L4_KDB_PrintChar( '\r' );
|
L4_KDB_PrintChar( '\r' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" int __l4_getc()
|
||||||
|
{
|
||||||
|
return L4_KDB_ReadChar_Blocked();
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
##
|
##
|
||||||
## Copyright (C) 2003, 2007, Karlsruhe University
|
## Copyright (C) 2003, 2007, 2010, Karlsruhe University
|
||||||
##
|
##
|
||||||
## File path: Makefile.in
|
## File path: Makefile.in
|
||||||
##
|
##
|
||||||
|
@ -36,13 +36,10 @@ top_builddir= @top_builddir@
|
||||||
include $(top_srcdir)/Mk/l4.base.mk
|
include $(top_srcdir)/Mk/l4.base.mk
|
||||||
|
|
||||||
|
|
||||||
ia32_OBJS= ia32-syscall-init.cc ia32-syscall-stubs.S
|
ia32_OBJS= ia32-syscall-stubs.S
|
||||||
powerpc_OBJS= powerpc-syscalls.c
|
|
||||||
powerpc64_OBJS= powerpc64-syscalls.c
|
|
||||||
amd64_OBJS= amd64-syscalls.c
|
|
||||||
|
|
||||||
LIBRARY= l4
|
LIBRARY= l4
|
||||||
SRCS= $($(ARCH)_OBJS)
|
SRCS= debug.cc $(ARCH).cc $($(ARCH)_OBJS)
|
||||||
|
|
||||||
|
|
||||||
include $(top_srcdir)/Mk/l4.lib.mk
|
include $(top_srcdir)/Mk/l4.lib.mk
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2003, 2009, Karlsruhe University
|
* Copyright (C) 2003, 2009-2010, Karlsruhe University
|
||||||
*
|
*
|
||||||
* File path: amd64-syscalls.c
|
* File path: amd64.cc
|
||||||
* Description: AMD64 syscall pointers.
|
* Description: AMD64 syscall pointers.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -49,12 +49,12 @@ __L4_SpaceControl_t __L4_SpaceControl = NULL;
|
||||||
__L4_ProcessorControl_t __L4_ProcessorControl = NULL;
|
__L4_ProcessorControl_t __L4_ProcessorControl = NULL;
|
||||||
__L4_MemoryControl_t __L4_MemoryControl = NULL;
|
__L4_MemoryControl_t __L4_MemoryControl = NULL;
|
||||||
|
|
||||||
void __L4_Init( void )
|
extern "C" void __L4_Init( void )
|
||||||
{
|
{
|
||||||
L4_KernelInterfacePage_t *kip;
|
L4_KernelInterfacePage_t *kip;
|
||||||
L4_Word_t dummy;
|
L4_Word_t dummy;
|
||||||
|
|
||||||
kip = L4_KernelInterface( &dummy, &dummy, &dummy );
|
kip = (L4_KernelInterfacePage_t *) L4_KernelInterface( &dummy, &dummy, &dummy );
|
||||||
|
|
||||||
|
|
||||||
__L4_Ipc = (__L4_Ipc_t) (kip->Ipc);
|
__L4_Ipc = (__L4_Ipc_t) (kip->Ipc);
|
|
@ -1,10 +1,11 @@
|
||||||
/****************************************************************************
|
/*********************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002, Karlsruhe University
|
* Copyright (C) 2010, Karlsruhe Institute of Technology
|
||||||
*
|
*
|
||||||
* File path: lib/io/powerpc-ofppc-getc.c
|
* Filename: debug.cc
|
||||||
* Description: debugger getc() for PowerPC-L4.
|
* Author: Jan Stoess <stoess@kit.edu>
|
||||||
*
|
* Description:
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
|
@ -25,19 +26,42 @@
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: powerpc64-getc.cc,v 1.4 2004/05/19 05:19:48 cvansch Exp $
|
********************************************************************/
|
||||||
*
|
#include <l4/kip.h>
|
||||||
***************************************************************************/
|
#include <l4/tracebuffer.h>
|
||||||
|
|
||||||
#include <l4/types.h>
|
L4_TraceBuffer_t *__L4_Tracebuffer = 0;
|
||||||
#include <l4/powerpc64/kdebug.h>
|
|
||||||
|
|
||||||
extern "C" int __l4_getc (void);
|
L4_TraceBuffer_t *L4_GetTraceBuffer()
|
||||||
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
|
|
||||||
|
|
||||||
extern "C" int __l4_getc()
|
|
||||||
{
|
{
|
||||||
return L4_KDB_ReadChar_Blocked();
|
static L4_Bool_t initialized = false;
|
||||||
}
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
L4_Word_t dummy;
|
||||||
|
L4_KernelInterfacePage_t *kip;
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
kip = (L4_KernelInterfacePage_t *) L4_KernelInterface( &dummy, &dummy, &dummy );
|
||||||
|
|
||||||
|
if (L4_HasFeature("tracebuffer"))
|
||||||
|
{
|
||||||
|
for( L4_Word_t i = 0; i < L4_NumMemoryDescriptors(kip); i++ )
|
||||||
|
{
|
||||||
|
|
||||||
|
L4_MemoryDesc_t *mdesc = L4_MemoryDesc( kip, i );
|
||||||
|
if( L4_MemoryDescType(mdesc) == L4_ReservedMemoryType && L4_IsVirtual(mdesc))
|
||||||
|
{
|
||||||
|
__L4_Tracebuffer = (L4_TraceBuffer_t*) L4_MemoryDescLow(mdesc);
|
||||||
|
|
||||||
|
if (__L4_Tracebuffer->magic != L4_TRACEBUFFER_MAGIC)
|
||||||
|
__L4_Tracebuffer = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return __L4_Tracebuffer;
|
||||||
|
}
|
|
@ -48,11 +48,9 @@ __L4_SpaceControl_t __L4_SpaceControl = NULL;
|
||||||
__L4_ProcessorControl_t __L4_ProcessorControl = NULL;
|
__L4_ProcessorControl_t __L4_ProcessorControl = NULL;
|
||||||
__L4_MemoryControl_t __L4_MemoryControl = NULL;
|
__L4_MemoryControl_t __L4_MemoryControl = NULL;
|
||||||
|
|
||||||
void __L4_Init( void )
|
extern "C" void __L4_Init( void )
|
||||||
{
|
{
|
||||||
L4_KernelInterfacePage_t *kip;
|
L4_KernelInterfacePage_t *kip = (L4_KernelInterfacePage_t *) L4_KernelInterface( NULL, NULL, NULL );
|
||||||
|
|
||||||
kip = L4_KernelInterface( NULL, NULL, NULL );
|
|
||||||
|
|
||||||
#define KIP_RELOC(a) (a)
|
#define KIP_RELOC(a) (a)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
##
|
##
|
||||||
## Copyright (C) 2003, 2005, Karlsruhe University
|
## Copyright (C) 2003, 2005, 2010, Karlsruhe University
|
||||||
##
|
##
|
||||||
## File path: Makefile.in
|
## File path: Makefile.in
|
||||||
##
|
##
|
||||||
|
@ -56,7 +56,6 @@ LDFLAGS+= -Ttext=$(SIGMA0_LINKBASE)
|
||||||
CFLAGS_powerpc+= -msoft-float -fno-builtin
|
CFLAGS_powerpc+= -msoft-float -fno-builtin
|
||||||
CXXFLAGS_powerpc+= -fno-rtti
|
CXXFLAGS_powerpc+= -fno-rtti
|
||||||
|
|
||||||
CFLAGS_alpha = -O2 -freg-struct-return -mno-fp-regs -mcpu=ev4
|
|
||||||
|
|
||||||
|
|
||||||
include $(top_srcdir)/Mk/l4.prog.mk
|
include $(top_srcdir)/Mk/l4.prog.mk
|
||||||
|
|
|
@ -76,7 +76,7 @@ CPPFLAGS_amd64= -I$(top_srcdir)/lib/io -I$(srcdir) \
|
||||||
-DALSO_ELF64 -DALSO_BOOTINFO64
|
-DALSO_ELF64 -DALSO_BOOTINFO64
|
||||||
LDFLAGS_amd64= -b elf32-i386 --oformat elf32-i386 \
|
LDFLAGS_amd64= -b elf32-i386 --oformat elf32-i386 \
|
||||||
-N -m elf_i386 -L.
|
-N -m elf_i386 -L.
|
||||||
IO32FILES_amd64= get_hex.cc print.cc $(ARCH)-getc.cc $(ARCH)-putc.cc
|
IO32FILES_amd64= get_hex.cc print.cc $(ARCH).cc
|
||||||
PROGRAM_DEPS_amd64= $(top_builddir)/util/kickstart/libio32.a
|
PROGRAM_DEPS_amd64= $(top_builddir)/util/kickstart/libio32.a
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
Loading…
Reference in New Issue