Add an architecture-independent tracebuffer facility (works for x86

and ppc) for both kernel and user level.
This commit is contained in:
Jan Stoess 2010-09-09 11:29:56 +02:00
parent c53bc2e832
commit 2e480db6e9
56 changed files with 757 additions and 977 deletions

View File

@ -40,8 +40,6 @@
#include INC_API(tcb.h)
#include INC_GLUE(schedule.h)
FEATURESTRING ("tracebuffer");
#define TB_WRAP 80
extern void list_tp_choices (void);
@ -273,11 +271,11 @@ public:
{ return get_tracebuffer()->config; }
word_t get_tbuf_size()
{ return (TRACEBUFFER_SIZE / sizeof (tracerecord_t)) - 1; }
word_t get_tbuf_max()
{ return get_tracebuffer()->max; }
word_t get_tbuf_current()
{ return get_tracebuffer()->current / sizeof (tracerecord_t); }
{ return get_tracebuffer()->current; }
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)
{
word_t start, end, size;
word_t start, end, max;
word_t old_tp_id[tbuf_handler_t::max_filters];
word_t old_cpumask = tbuf_handler.get_cpumask();
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);
size = tbuf_handler.get_tbuf_size();
max = tbuf_handler.get_tbuf_max();
end = tbuf_handler.get_tbuf_current();
if (usec)
@ -633,15 +631,15 @@ void tbuf_dump (word_t count, word_t usec, word_t tp_id, word_t cpumask)
ASSERT (pdesc);
word_t freq = pdesc->internal_freq + 1;
u64_t tsc = get_cpu_cycles() - ((u64_t) usec * (u64_t) (freq / 1000));
count = size;
count = max;
tbuf_handler.set_tsc(tsc);
}
else if (count == 0)
count = size;
count = max;
start = tbuf_handler.find_tbuf_start(end, count, size);
count = (end >= start) ? end - start : end + size - start;
tbuf_handler.dump_tbuf(start, count, size, false);
start = tbuf_handler.find_tbuf_start(end, count, max);
count = (end >= start) ? end - start : end + max - start;
tbuf_handler.dump_tbuf(start, count, max, false);
if (tp_id)
{
@ -761,12 +759,12 @@ DECLARE_CMD (cmd_tb_dump, tracebuf, 'd', "dump", "Dump tracebuffer");
CMD (cmd_tb_dump, cg)
{
word_t start, end, size, count;
word_t start, end, max, count;
if (!tbuf_handler.is_tbuf_valid())
return CMD_NOQUIT;
size = tbuf_handler.get_tbuf_size();
max = tbuf_handler.get_tbuf_max();
count = 32;
start = 0;
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'))
{
case 'a':
count = size;
count = max;
break;
case 'r':
start = get_dec ("From record", 0);
// Fall through
case 't':
count = get_dec ("Record count", count);
end = tbuf_handler.find_tbuf_end(start, count, size);
if (count > size) count = size;
end = tbuf_handler.find_tbuf_end(start, count, max);
if (count > max) count = max;
break;
case 'b':
default:
count = get_dec ("Record count", count);
if (count > size) count = size;
start = tbuf_handler.find_tbuf_start(end, count, size);
if (count > max) count = max;
start = tbuf_handler.find_tbuf_start(end, count, max);
break;
}
count = (end >= start) ? end - start : end + size - start;
tbuf_handler.dump_tbuf(start, count, size);
count = (end >= start) ? end - start : end + max - start;
tbuf_handler.dump_tbuf(start, count, max);
return CMD_NOQUIT;
}
@ -809,18 +807,18 @@ DECLARE_CMD (cmd_tb_dump_def, root, 'Y', "tracebuffer dump",
CMD (cmd_tb_dump_def, cg)
{
word_t start, end, size, count;
word_t start, end, max, count;
if (!tbuf_handler.is_tbuf_valid())
return CMD_NOQUIT;
size = tbuf_handler.get_tbuf_size();
max = tbuf_handler.get_tbuf_max();
count = 64;
end = tbuf_handler.get_tbuf_current();
start = tbuf_handler.find_tbuf_start(end, count, size);
count = (end >= start) ? end - start : end + size - start;
tbuf_handler.dump_tbuf(start, count, size);
start = tbuf_handler.find_tbuf_start(end, count, max);
count = (end >= start) ? end - start : end + max - start;
tbuf_handler.dump_tbuf(start, count, max);
return CMD_NOQUIT;
}

View File

@ -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,
fpage_t utcb_area, threadid_t redirector_tid)
{
@ -429,3 +427,4 @@ void space_t::free (void)
fp.set_rwx ();
unmap_fpage (fp, true, true);
}

View File

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

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: src/arch/powerpc/softhvm.h
* File path: arch/powerpc/softhvm.h
* Description:
*
* Redistribution and use in source and binary forms, with or without
@ -34,6 +34,7 @@
#include "msr.h"
#include "swtlb.h"
#include "frame.h"
#define LAZY_TLB

View File

@ -31,7 +31,7 @@
#include <tcb_layout.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)
{
tsc = ppc_get_timebase();

View File

@ -34,13 +34,6 @@
#include INC_ARCH(cpu.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)
#define TRACEBUFFER_SIZE (32 * 1024 * 1024)
#else
@ -114,7 +107,7 @@ INLINE void tracerecord_t::store_arch(const traceconfig_t config)
else
{
pmc0 = (word_t) x86_rdpmc(12);
pmc1 = (word_t) x86_rdpmc(2);
pmc1 = (word_t) x86_rdpmc(14);
}
break;
default:
@ -144,5 +137,6 @@ INLINE void tracebuffer_t::initialize()
config.pmon_cpu = 1;
#endif
printf("sz %d rec %d max %d\n", TRACEBUFFER_SIZE, sizeof(tracerecord_t), max);
}
#endif /* !__ARCH__X86__TRACEBUFFER_H__ */

View File

@ -130,6 +130,7 @@ void kdebug_entry (void *);
# define printf(fmt, args...) do { } while (false)
# define enter_kdebug(x) do { } while (true)
# define UNIMPLEMENTED() do { } while (true)
# define UNTESTED() do { } while (true)
# define ASSERT(x) do { } while (false)
# define WARNING(fmt, args...) do { } while (false)
# define TRACE(x...) do { } while (false)

View File

@ -133,8 +133,8 @@ SECTION(SEC_INIT) void dtree_remap( kernel_interface_page_t *kip )
dtree_t *dtreemapping;
paddr_t pdtree = (paddr_t) dtree;
printf("dtree %p %d\n", dtree, dtree_size);
addr_t page = get_kernel_space()->map_device( pdtree, dtree_size, pgent_t::cache_standard );
//TRACEF("dtree %p %d\n", dtree, dtree_size);
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));
if (!dtreemapping->is_valid())
@ -348,6 +348,7 @@ SECTION(SEC_INIT) static word_t init_bootmem()
}
#endif
/****************************************************************************
*
* Per-cpu init.
@ -371,16 +372,6 @@ static SECTION(SEC_INIT) void perfmon_init( void )
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 )
{

View File

@ -53,6 +53,7 @@ EXTERN_KMEM_GROUP(kmem_space);
//#define TRACE_TLB(x...) TRACEF(x)
#define TRACE_TLB(x...)
word_t space_t::pinned_mapping;
// used by initialization code...
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()
{
//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;
}
#if 0
addr_t space_t::map_device_pinned(paddr_t paddr, word_t size, word_t attrib)
addr_t space_t::map_device_pinned(paddr_t paddr, word_t size, bool kernel, word_t attrib)
{
word_t log2sz;
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;
tlb2.init_device();
tlb2.set_kernel_perms(true, true, false);
if (!kernel)
tlb2.set_user_perms(true, true, false);
word_t tlb_index = swtlb.allocate_pinned();
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);
}
#endif
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)
{
static word_t console_area = CONSOLE_AREA_START;

View File

@ -191,7 +191,7 @@ void SECTION(".init.memory") space_t::init_kernel_space()
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);
@ -242,7 +242,7 @@ found:
for( word_t page = 0; page < size; page += POWERPC_PAGE_SIZE )
{
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;

View File

@ -145,7 +145,7 @@ public:
void init_kernel_mappings();
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
bool handle_hash_miss( addr_t vaddr );
@ -153,7 +153,7 @@ public:
#endif
#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_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
@ -183,12 +183,12 @@ public:
return (space_t *)( (vsid & 0xfffffff0) << (POWERPC_PAGE_BITS - 4) );
}
private:
void add_mapping( addr_t vaddr, paddr_t paddr, pgent_t::pgsize_e size,
bool writable, bool kernel,
word_t attrib = pgent_t::cache_standard );
void flush_mapping( addr_t vaddr, pgent_t::pgsize_e size, pgent_t *pgent );
private:
pgent_t pdir[1024];
union {
word_t raw[1024];
@ -210,6 +210,7 @@ private:
};
};
static word_t pinned_mapping;
friend class kdb_t;
};

View File

@ -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);
#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)
/**************************************************************************
@ -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

View File

@ -703,19 +703,12 @@ void SECTION(".init.memory") space_t::init_kernel_mappings()
* each processor gets a full cache line to avoid bouncing
* 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);
utcb_page = kmem.alloc(kmem_misc, X86_PAGE_SIZE);
ASSERT(utcb_page);
add_mapping((addr_t)UTCB_MAPPING, virt_to_phys(utcb_page),
pgent_t::size_4k, true, false, true);
#if defined(CONFIG_X86_SMALL_SPACES) && defined(CONFIG_X86_SYSENTER)
/* User-level trampoline for ipc_sysexit, readonly but global. */
extern word_t _start_utramp_p[];

View File

@ -423,9 +423,7 @@ INLINE void reload_user_segregs (void)
{
asm volatile (
" movl %0, %%es \n"
#if !defined(CONFIG_TRACEBUFFER)
" movl %0, %%fs \n"
#endif
" movl %1, %%gs \n"
:
: "r" (X86_UDS), "r" (X86_UTCBS));

View File

@ -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
* Description:
@ -54,14 +54,10 @@ void return_to_user_wrapper()
" mov %0, %%eax \n"
" mov %%eax, %%ds \n"
" mov %%eax, %%es \n"
#if defined(CONFIG_TRACEBUFFER)
" mov %1, %%eax \n"
#else
" mov %%eax, %%fs \n"
#endif
#if defined(CONFIG_IS_64BIT)
" add %3, %%rsp \n"
" add %1, %%rsp \n"
" iretq \n"
#else
#if defined(CONFIG_X_CTRLXFER_MSG)
@ -69,13 +65,12 @@ void return_to_user_wrapper()
" popa \n"
" addl $4, %%esp \n"
#else
" add %3, %%esp \n"
" add %1, %%esp \n"
#endif
" iret \n"
#endif
:
: "i"(X86_UDS), "i" (X86_TBS), "i"(X86_UTCBS),
"i"(EXC_FRAME_SIZE * BYTES_WORD)
: "i"(X86_UDS), "i"(EXC_FRAME_SIZE * BYTES_WORD)
);
}

View File

@ -163,7 +163,6 @@
#define X86_UTCBS 0x2b
#define X86_TSS 0x30
#define X86_KDB 0x38
#define X86_TBS 0x43
/* user mode e-flags */
#if defined(CONFIG_X86_PVI)

View File

@ -1554,30 +1554,23 @@ void vmexit_entry_point_wrapper ()
" mov %0, %%bx \n"
" mov %%bx, %%ds \n"
" mov %%bx, %%es \n"
// FS.
#if defined(CONFIG_TRACEBUFFER)
" mov %1, %%bx \n"
#endif
" mov %%bx, %%fs \n"
#endif
// GS.
" mov %2, %%bx \n"
" mov %1, %%bx \n"
" mov %%bx, %%gs \n"
// EFLAGS.
// VM-Exit has a cleared eflags (except bit 1, which is always 1)
" pushl %3 \n"
" pushl %2 \n"
" popfl \n"
// Call do_handle_vmexit.
" jmp %4 \n"
" jmp %3 \n"
:
: "i" (X86_UDS), // %0
"i" (X86_TBS), // %1
"i" (X86_UTCBS), // %2
"i" (X86_KERNEL_FLAGS), // %3
"m" (*do_handle_vmexit_ptr) // %4
"i" (X86_UTCBS), // %1
"i" (X86_KERNEL_FLAGS), // %2
"m" (*do_handle_vmexit_ptr) // %3
);
}

View File

@ -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);
gdt[gdt_idx(X86_UTCBS)].set_seg((u32_t)UTCB_MAPPING +
(cpuid * CACHE_LINE_SIZE),
sizeof(threadid_t) - 1,
sizeof(threadid_t) - 1,
3, x86_segdesc_t::data);
/* the TSS
@ -152,17 +152,8 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
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 */
x86_descreg_t gdtr((word_t) &gdt, sizeof(gdt));
gdtr.setdescreg(x86_descreg_t::gdtr);
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 %1, %%ss \n" /* reload stack 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 */
#endif
"xor %%eax, %%eax \n" /* */
"lldt %%ax \n" /* clear LDTR */
:
@ -199,7 +186,7 @@ void SECTION(SEC_INIT) setup_gdt(x86_tss_t &tss, cpuid_t cpuid)
#else
"r"(X86_UDS),
#endif
"r"(X86_KDS), "r"(X86_UTCBS), "r"(X86_TBS)
"r"(X86_KDS), "r"(X86_UTCBS)
: "eax", "memory"
);

View File

@ -61,6 +61,7 @@
#define PGSIZE_KTCB (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_KIP (pgent_t::size_4k)
#define PGSIZE_SIGMA PGSIZE_KERNEL

View File

@ -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
* 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
#if defined(CONFIG_X86_SMALL_SPACES)
__asm__ __volatile__ (
"/* switch_to_thread */ \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 $"MKSTR(X86_UDS)", %%ecx \n"
" movl %%ecx, %%es \n"
#if !defined(CONFIG_TRACEBUFFER)
" movl %%ecx, %%fs \n"
#endif
" movl $"MKSTR(X86_UTCBS)", %%ecx \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 %%edx, %%es \n"
#if !defined(CONFIG_TRACEBUFFER)
" movl %%edx, %%fs \n"
#endif
" movl $"MKSTR(X86_UTCBS)", %%edx \n"
" movl %%edx, %%gs \n"

View File

@ -244,10 +244,8 @@ fp_save_resources_done:
movl %eax, 28(%ebp)
movl $X86_UDS, %ecx
movl %ecx, %es
#if !defined(CONFIG_TRACEBUFFER)
movl %ecx, %fs
#endif
movl $X86_UTCBS, %ecx
movl $X86_UTCBS, %ecx
movl %ecx, %gs
movl $1, __is_small
1: popl %ecx
@ -266,9 +264,7 @@ fp_save_resources_done:
movl $X86_UDS, %edx
movl %edx, %es
#if !defined(CONFIG_TRACEBUFFER)
movl %edx, %fs
#endif
movl $X86_UTCBS, %edx
movl %edx, %gs

View File

@ -213,8 +213,7 @@
#define X86_UDS 0x23 /* 4, RPL = 3 */
#define X86_UCS 0x2b /* 5, RPL = 3 */
#define X86_UTCBS 0x33 /* 6, RPL = 3 */
#define X86_X64_KDBS 0x38 /* 7, RPL = 0 */
#define X86_TBS 0x43 /* 8, RPL = 0 */
#define X86_X64_KDBS 0x38 /* 7, RPL = 0 */
#define X86_TSS 0x48 /* 9, RPL = 0 */
/* user mode e-flags */

View File

@ -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::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");
@ -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, %%ss \n\t" // load stack segment (SS)
"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
#endif
"pushq %3 \n\t" // new CS
"pushq %2 \n\t" // new CS
"pushq $1f \n\t" // new IP
"lretq \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::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
}
/**

View File

@ -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.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -140,8 +140,7 @@ public:
bool next_record(word_t type, word_t id)
{
if (!this)
return false;
if (!this) return false;
/* Check wheter to filter the event */
if ((mask & ((type & 0xffff) << 16)) == 0)
@ -159,6 +158,7 @@ public:
void increase_counter(word_t ctr)
{
if (!this) return;
counters[ctr & 0x7]++;
}
@ -223,12 +223,13 @@ INLINE void __tbuf_record_event(word_t type, word_t tpid, const char *str, ...)
va_end(args);
}
void setup_tracebuffer (void);
#else /* !CONFIG_TRACEBUFFER */
#define tbuf_inc_counter(counter)
#define tbuf_record_event(args...)
#endif
# define TBUF_REC_TRACEPOINT(tptype, tpid, str, args...) \
tbuf_record_event (tptype, tpid, str, ##args)

View File

@ -31,9 +31,6 @@
********************************************************************/
#include <l4/arch.h>
#undef L4_TRACEBUFFER
#include <l4/tracebuffer.h>
#include L4_COMPAT_H_LOCATION

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2003, Karlsruhe University
* Copyright (C) 2003, 2010, Karlsruhe University
*
* File path: bench/pingpong/crt0-ia32.S
* Description:

View File

@ -32,8 +32,6 @@
********************************************************************/
#include <l4/arch.h>
#define L4_TRACEBUFFER
#define HAVE_HANDLE_ARCH_PAGEFAULT
#define HAVE_READ_CYCLES
#define HAVE_ARCH_IPC

View File

@ -38,35 +38,6 @@
#include <l4io.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)
extern long _start_pager;
extern long _start_ping_thread;
@ -89,15 +60,8 @@ int SMALL_AS = 0;
int LIPC = 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_KernelInterfacePage_t * kip;
@ -140,7 +104,9 @@ void pong_thread (void);
#elif defined(L4_ARCH_AMD64)
#include "amd64.h"
#endif
#include <l4/tracebuffer.h>
#define debug_printf(x...) L4_Tbuf_RecordEvent (1, x)
static inline void rdpmc (int no, L4_Word64_t* res)
{
@ -227,7 +193,7 @@ void pong_thread (void)
else
for (;;)
{
Dprintf("pong ipc\n");
debug_printf("pong ipc\n");
untyped = pingpong_ipc (ping_tid, untyped);
}
}
@ -282,7 +248,7 @@ void ping_thread (void)
{
for (int k = 0; k < FACTOR; k++)
{
Dprintf( "ping ipc\n");
debug_printf( "ping ipc\n");
pingpong_ipc (pong_tid, j);
}
}
@ -370,8 +336,8 @@ void pager (void)
{
L4_Store (tag, &msg);
Dprintf( "Pager got msg from %p\n", (L4_Word_t) tid.raw);
Dprintf( "\tmsg (%p, %p, %p, %p)\n",
debug_printf( "Pager got msg from %p\n", (L4_Word_t) tid.raw);
debug_printf( "\tmsg (%p, %p, %p, %p)\n",
(L4_Word_t) tag.raw,
(L4_Word_t) L4_Get (&msg, 0),
(L4_Word_t) L4_Get (&msg, 1),
@ -454,9 +420,11 @@ int main (void)
// We need a maximum of two threads per task
utcb_area = L4_FpageLog2 ((L4_Word_t) UTCB_ADDRESS,
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);
// Create pager
pager_tid = L4_GlobalId (L4_ThreadNo (roottid) + 1, 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 };
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
L4_Word_t pager_utcb = L4_MyLocalId().raw;
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);
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";
printf(str, L4_Myself());
Dprintf( str, L4_Myself().raw);
debug_printf( str, L4_Myself().raw);
for (;;)
{

View File

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

View File

@ -133,7 +133,7 @@ bad_send(void)
L4_Load( &msg );
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 */
msec_sleep(1000);

View File

@ -35,6 +35,13 @@
/*
* 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));
@ -77,5 +84,29 @@ L4_INLINE int __L4_Lsb (L4_Word_t w)
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__ */

View File

@ -30,193 +30,70 @@
#ifndef __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)
#define MKSTR2(sym) #sym
/**********************************************************************
* Sample PMC energy weights
**********************************************************************/
/* 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 __PLUS32 + 32
#else
# define __PLUS32
#endif
#define X86_PMC_TSC_SHIFT 6
#define X86_PMC_UC (0)
#define X86_PMC_MLR (1)
#define X86_PMC_MQW (4)
#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)
#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
L4_INLINE void L4_Tbuf_StoreRecordArch(L4_TraceRecord_t *rec, L4_TraceConfig_t config)
{
struct {
L4_Word_t utype : 16;
L4_Word_t __pad0 : 16 __PLUS32;
L4_Word_t cpu : 16;
L4_Word_t id : 16 __PLUS32;
} X;
rec->tsc = __L4_Rdtsc();
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;
/*
* Tracebuffer access macros
*/
#define __L4_TBUF_RDPMCS \
/* Get config into rbx/ebx */ \
" push %%rbx \n" /* save ebx */ \
" movq %%fs:4*%c9, %%rbx \n" \
" test $2, %%rbx \n" \
" jz 4f \n" /* no pmon, rdtsc only */ \
" test $4, %%rbx \n" \
" jz 3f \n" /* P2/K8 pmon */ \
/* P4 PerfMon */ \
" mov $12, %1 \n" \
" rdpmc \n" \
" shl $32, %%rdx \n" \
" movl %%eax, %%edx \n" \
" mov %2, %%fs:4*%c9(%0) \n" \
" add $2, %1 \n" \
" rdpmc \n" \
" shl $32, %%rdx \n" \
" movl %%eax, %%edx \n" \
" mov %2, %%fs:5*%c9(%0) \n" \
" jmp 4f \n" \
"3: \n" \
/* 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
if (config.X.pmon)
{
switch (config.X.pmon_cpu)
{
case 0:
// P2/P3/K8
rec->pmc0 = __L4_Rdpmc(0);
rec->pmc1 = __L4_Rdpmc(1);
break;
case 1:
// P4
if (config.X.pmon_e)
{
L4_Word64_t pmce =
X86_PMC_TSC_WEIGHT * __L4_Rdtsc() +
X86_PMC_UC_WEIGHT * __L4_Rdpmc(X86_PMC_UC) +
X86_PMC_MLR_WEIGHT * __L4_Rdpmc(X86_PMC_MLR) +
X86_PMC_MQW_WEIGHT * __L4_Rdpmc(X86_PMC_MQW) +
X86_PMC_RB_WEIGHT * __L4_Rdpmc(X86_PMC_RB) +
X86_PMC_MB_WEIGHT * __L4_Rdpmc(X86_PMC_MB) +
X86_PMC_MR_WEIGHT * __L4_Rdpmc(X86_PMC_MR) +
X86_PMC_LDM_WEIGHT * __L4_Rdpmc(X86_PMC_LDM);
rec->pmc0 = (L4_Word_t) pmce;
rec->pmc1 = (L4_Word_t) (pmce >> 32);
}
else
{
rec->pmc0 = (L4_Word_t) __L4_Rdpmc(12);
rec->pmc1 = (L4_Word_t) __L4_Rdpmc(14);
}
break;
default:
break;
}
}
}
#endif /* !__L4__AMD64__TRACEBUFFER_H__ */

View File

@ -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
* Description: x86 specific functions and defines
@ -29,14 +29,22 @@
* $Id: specials.h,v 1.12 2006/11/17 16:48:17 skoglund Exp $
*
********************************************************************/
#ifndef __L4__X86__SPECIALS_H__
#define __L4__X86__SPECIALS_H__
#ifndef __L4__IA32__SPECIALS_H__
#define __L4__IA32__SPECIALS_H__
/*
* 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)
@ -74,6 +82,31 @@ L4_INLINE int __L4_Lsb (L4_Word_t w)
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.
*/
@ -113,5 +146,4 @@ L4_INLINE L4_Word_t L4_SmallSpace (L4_Word_t location, L4_Word_t size)
#endif /* !__L4__X86__SPECIALS_H__ */
#endif /* !__L4__IA32__SPECIALS_H__ */

View File

@ -30,245 +30,69 @@
#ifndef __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)
#define MKSTR2(sym) #sym
/**********************************************************************
* Sample PMC energy weights
**********************************************************************/
/* 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 __PLUS32 + 32
#else
# define __PLUS32
#endif
#define X86_PMC_TSC_SHIFT 6
#define X86_PMC_UC (0)
#define X86_PMC_MLR (1)
#define X86_PMC_MQW (4)
#define X86_PMC_RB (5)
#define X86_PMC_MB (12)
#define X86_PMC_MR (13)
#define X86_PMC_LDM (14)
#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
L4_INLINE void L4_Tbuf_StoreRecordArch(L4_TraceRecord_t *rec, L4_TraceConfig_t config)
{
struct {
L4_Word_t utype : 16;
L4_Word_t __pad0 : 16 __PLUS32;
L4_Word_t cpu : 16;
L4_Word_t id : 16 __PLUS32;
} X;
rec->tsc = __L4_Rdtsc();
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;
/*
* Access to performance monitoring counters
*/
#include <l4/ia32/arch.h>
#define __L4_TBUF_RDPMC_WEIGHTED(nr, weight, op) \
" mov $"MKSTR(nr)", %%ecx \n" /* select pmc */ \
" "#op" \n" /* pmc/tsc in %edx:%eax */ \
" mov %%edx, %%esi \n" /* save pmc_hi */ \
" mov $"MKSTR(weight)", %%ecx \n" /* load weight */ \
" mul %%ecx \n" /* r1 = pmc_lo * weight */ \
" mov %%edx, %%ebx \n" /* save r1_hi */ \
" xchg %%eax, %%ecx \n" /* r1_lo <-> weight */ \
" mul %%esi \n" /* r2 = weight * pmc_hi */ \
" add %%ebx, %%eax \n" /* r2_lo += r1_hi */ \
" addl %%ecx, %%fs:4*%c9(%0) \n" /* result_lo */ \
" adcl %%eax, %%fs:5*%c9(%0) \n" /* result_hi */
#define __L4_TBUF_RDPMCS \
/* Get config into rbx/ebx */ \
" push %%ebx \n" /* save ebx */ \
" movl %%fs:4*%c9, %%ebx \n" \
" 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
if (config.X.pmon)
{
switch (config.X.pmon_cpu)
{
case 0:
// P2/P3/K8
rec->pmc0 = __L4_Rdpmc(0);
rec->pmc1 = __L4_Rdpmc(1);
break;
case 1:
// P4
if (config.X.pmon_e)
{
L4_Word64_t pmce =
X86_PMC_TSC_WEIGHT * __L4_Rdtsc() +
X86_PMC_UC_WEIGHT * __L4_Rdpmc(X86_PMC_UC) +
X86_PMC_MLR_WEIGHT * __L4_Rdpmc(X86_PMC_MLR) +
X86_PMC_MQW_WEIGHT * __L4_Rdpmc(X86_PMC_MQW) +
X86_PMC_RB_WEIGHT * __L4_Rdpmc(X86_PMC_RB) +
X86_PMC_MB_WEIGHT * __L4_Rdpmc(X86_PMC_MB) +
X86_PMC_MR_WEIGHT * __L4_Rdpmc(X86_PMC_MR) +
X86_PMC_LDM_WEIGHT * __L4_Rdpmc(X86_PMC_LDM);
rec->pmc0 = (L4_Word_t) pmce;
rec->pmc1 = (L4_Word_t) (pmce >> 32);
}
else
{
rec->pmc0 = (L4_Word_t) __L4_Rdpmc(12);
rec->pmc1 = (L4_Word_t) __L4_Rdpmc(14);
}
break;
default:
break;
}
}
}
#endif /* !__L4__IA32__TRACEBUFFER_H__ */

View File

@ -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
* Description: Kernel interface page definitions.
@ -553,6 +553,26 @@ L4_INLINE char * L4_Feature (void * KernelInterface, L4_Word_t num)
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 {
L4_Word_t raw[2];
struct {

View File

@ -33,6 +33,26 @@
#ifndef __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 )
@ -59,3 +79,4 @@ L4_INLINE L4_Fpage_t L4_Fpage (L4_Fpage_t f)
#endif
#endif /* __L4__POWERPC__SPECIALS_H__ */

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: include/l4/tracebuffer.h
* File path: l4/tracebuffer.h
* Description:
*
* Redistribution and use in source and binary forms, with or without
@ -34,78 +34,162 @@
#ifndef __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_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_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_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_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (addr == 0)
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (rec == 0)
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_Word_t p0)
{
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (addr == 0)
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (rec == 0)
return;
__L4_TBUF_STORE_STR (addr, str);
__L4_TBUF_STORE_DATA (addr, 0, p0);
rec->str = (L4_Word_t) str;
rec->data[0] = p0;
}
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 addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (addr == 0)
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (rec == 0)
return;
__L4_TBUF_STORE_STR (addr, str);
__L4_TBUF_STORE_DATA (addr, 0, p0);
__L4_TBUF_STORE_DATA (addr, 1, p1);
rec->str = (L4_Word_t) str;
rec->data[0] = p0;
rec->data[1] = p1;
}
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 p2)
{
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (addr == 0)
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (rec == 0)
return;
__L4_TBUF_STORE_STR (addr, str);
__L4_TBUF_STORE_DATA (addr, 0, p0);
__L4_TBUF_STORE_DATA (addr, 1, p1);
__L4_TBUF_STORE_DATA (addr, 2, p2);
rec->str = (L4_Word_t) str;
rec->data[0] = p0;
rec->data[1] = p1;
rec->data[2] = p2;
}
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 p2, L4_Word_t p3)
{
L4_Word_t addr = __L4_TBUF_GET_NEXT_RECORD (L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (addr == 0)
L4_TraceRecord_t *rec = L4_Tbuf_NextRecord(L4_TRACEBUFFER_DEFAULT_TYPE, id);
if (rec == 0)
return;
__L4_TBUF_STORE_STR (addr, str);
__L4_TBUF_STORE_DATA (addr, 0, p0);
__L4_TBUF_STORE_DATA (addr, 1, p1);
__L4_TBUF_STORE_DATA (addr, 2, p2);
__L4_TBUF_STORE_DATA (addr, 3, p3);
rec->str = (L4_Word_t) str;
rec->data[0] = p0;
rec->data[1] = p1;
rec->data[2] = p2;
rec->data[3] = p3;
}
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);
}
#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__ */

View File

@ -36,14 +36,10 @@ top_builddir= @top_builddir@
include $(top_srcdir)/Mk/l4.base.mk
ia32_SRCS= ia32-getc.cc ia32-putc.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
powerpc_SRCS= 1275tree.cc fdt.cc
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

View File

@ -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

View File

@ -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
*
* Redistribution and use in source and binary forms, with or without
@ -32,10 +32,13 @@
#include <config.h>
#include <l4/types.h>
#include "ia32-port.h"
#include "amd64.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 getc (void) __attribute__ ((weak, alias ("__l4_getc")));
#if defined(CONFIG_COMPORT)
@ -51,8 +54,47 @@ extern "C" void putc (int c) __attribute__ ((weak, alias ("__l4_putc")));
#define COMPORT CONFIG_COMPORT
#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));
@ -60,12 +102,36 @@ void __l4_putc(int c)
__l4_putc('\r');
}
int __l4_getc (void)
{
while ((inb(COMPORT+5) & 0x01) == 0);
return inb(COMPORT);
}
#else /* ! CONFIG_COMPORT */
#define DISPLAY ((char*)0xb8000)
#define COLOR 7
#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)
{
unsigned int i;
@ -115,4 +181,28 @@ void __l4_putc(int c)
__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

View File

@ -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

View File

@ -1,9 +1,9 @@
/*********************************************************************
*
* Copyright (C) 2001, 2003-2004, Karlsruhe University
* Copyright (C) 2001-2006, 2010, Karlsruhe University
*
* File path: amd64-getc.cc
* Description: getc() for amd64-based PCs
* File path: ia32.cc
* Description: putc() for x86-based PCs, serial and screen
*
* Redistribution and use in source and binary forms, with or without
* 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
* 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 <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 getc (void) __attribute__ ((weak, alias ("__l4_getc")));
#if defined(CONFIG_COMPORT)
#if CONFIG_COMPORT == 0
# define COMPORT 0x3f8
#elif CONFIG_COMPORT == 1
@ -49,14 +53,67 @@ extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
#define COMPORT CONFIG_COMPORT
#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)
{
io_init();
while ((inb(COMPORT+5) & 0x01) == 0);
return inb(COMPORT);
}
#else /* CONFIG_COMPORT */
/* No SHIFT key support!!! */
#else /* ! CONFIG_COMPORT */
#define DISPLAY ((char*)0xb8000)
#define COLOR 7
#define NUM_LINES 25
#define KBD_STATUS_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 */
"\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;
char c;

View File

@ -2,7 +2,7 @@
*
* Copyright (C) 2010, Karlsruhe Institute of Technology
*
* Filename: powerpc-io.cc
* Filename: powerpc.cc
* Author: Jan Stoess <stoess@kit.edu>
* Description:
*
@ -48,14 +48,12 @@ extern "C" void putc( int c ) __attribute__ ((weak, alias("__l4_putc")));
#if defined(CONFIG_COMPORT)
#include <l4/sigma0.h>
#include "powerpc-port.h"
#include "powerpc.h"
#include "fdt.h"
#include "1275tree.h"
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_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 DLHI (comport+1)
extern "C" int printf (const char *fmt, ...);
static void io_init( void )
{
static bool io_initialized = false;
if (io_initialized)
return;

View File

@ -36,6 +36,9 @@
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 getc (void) __attribute__ ((weak, alias ("__l4_getc")));
extern "C" void __l4_putc( int c )
{
L4_KDB_PrintChar( c );
@ -43,3 +46,8 @@ extern "C" void __l4_putc( int c )
L4_KDB_PrintChar( '\r' );
}
extern "C" int __l4_getc()
{
return L4_KDB_ReadChar_Blocked();
}

View File

@ -1,6 +1,6 @@
######################################################################
##
## Copyright (C) 2003, 2007, Karlsruhe University
## Copyright (C) 2003, 2007, 2010, Karlsruhe University
##
## File path: Makefile.in
##
@ -36,13 +36,10 @@ top_builddir= @top_builddir@
include $(top_srcdir)/Mk/l4.base.mk
ia32_OBJS= ia32-syscall-init.cc ia32-syscall-stubs.S
powerpc_OBJS= powerpc-syscalls.c
powerpc64_OBJS= powerpc64-syscalls.c
amd64_OBJS= amd64-syscalls.c
ia32_OBJS= ia32-syscall-stubs.S
LIBRARY= l4
SRCS= $($(ARCH)_OBJS)
SRCS= debug.cc $(ARCH).cc $($(ARCH)_OBJS)
include $(top_srcdir)/Mk/l4.lib.mk

View File

@ -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.
*
* 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_MemoryControl_t __L4_MemoryControl = NULL;
void __L4_Init( void )
extern "C" void __L4_Init( void )
{
L4_KernelInterfacePage_t *kip;
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);

View File

@ -1,10 +1,11 @@
/****************************************************************************
*
* Copyright (C) 2002, Karlsruhe University
*
* File path: lib/io/powerpc-ofppc-getc.c
* Description: debugger getc() for PowerPC-L4.
*
/*********************************************************************
*
* Copyright (C) 2010, Karlsruhe Institute of Technology
*
* Filename: debug.cc
* Author: Jan Stoess <stoess@kit.edu>
* Description:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -25,19 +26,42 @@
* 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: 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>
#include <l4/powerpc64/kdebug.h>
L4_TraceBuffer_t *__L4_Tracebuffer = 0;
extern "C" int __l4_getc (void);
extern "C" int getc (void) __attribute__ ((weak, alias ("__l4_getc")));
extern "C" int __l4_getc()
L4_TraceBuffer_t *L4_GetTraceBuffer()
{
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;
}

View File

@ -48,11 +48,9 @@ __L4_SpaceControl_t __L4_SpaceControl = NULL;
__L4_ProcessorControl_t __L4_ProcessorControl = NULL;
__L4_MemoryControl_t __L4_MemoryControl = NULL;
void __L4_Init( void )
extern "C" void __L4_Init( void )
{
L4_KernelInterfacePage_t *kip;
kip = L4_KernelInterface( NULL, NULL, NULL );
L4_KernelInterfacePage_t *kip = (L4_KernelInterfacePage_t *) L4_KernelInterface( NULL, NULL, NULL );
#define KIP_RELOC(a) (a)

View File

@ -1,6 +1,6 @@
######################################################################
##
## Copyright (C) 2003, 2005, Karlsruhe University
## Copyright (C) 2003, 2005, 2010, Karlsruhe University
##
## File path: Makefile.in
##
@ -56,7 +56,6 @@ LDFLAGS+= -Ttext=$(SIGMA0_LINKBASE)
CFLAGS_powerpc+= -msoft-float -fno-builtin
CXXFLAGS_powerpc+= -fno-rtti
CFLAGS_alpha = -O2 -freg-struct-return -mno-fp-regs -mcpu=ev4
include $(top_srcdir)/Mk/l4.prog.mk

View File

@ -76,7 +76,7 @@ CPPFLAGS_amd64= -I$(top_srcdir)/lib/io -I$(srcdir) \
-DALSO_ELF64 -DALSO_BOOTINFO64
LDFLAGS_amd64= -b elf32-i386 --oformat elf32-i386 \
-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
##