From 2e480db6e9524948574becddd5cad7501a8298ec Mon Sep 17 00:00:00 2001 From: Jan Stoess Date: Thu, 9 Sep 2010 11:29:56 +0200 Subject: [PATCH] Add an architecture-independent tracebuffer facility (works for x86 and ppc) for both kernel and user level. --- kernel/kdb/generic/tracebuffer.cc | 50 ++- kernel/src/api/v4/space.cc | 3 +- kernel/src/arch/powerpc/page.h | 2 +- kernel/src/arch/powerpc/softhvm.h | 3 +- kernel/src/arch/powerpc/tracebuffer.h | 2 +- kernel/src/arch/x86/tracebuffer.h | 10 +- kernel/src/generic/debug.h | 1 + kernel/src/glue/v4-powerpc/init.cc | 15 +- kernel/src/glue/v4-powerpc/space-swtlb.cc | 28 +- kernel/src/glue/v4-powerpc/space.cc | 4 +- kernel/src/glue/v4-powerpc/space.h | 7 +- kernel/src/glue/v4-x86/init.cc | 43 +-- kernel/src/glue/v4-x86/space.cc | 7 - kernel/src/glue/v4-x86/space.h | 2 - kernel/src/glue/v4-x86/thread.cc | 13 +- kernel/src/glue/v4-x86/x32/config.h | 1 - kernel/src/glue/v4-x86/x32/hvm-vmx.cc | 19 +- kernel/src/glue/v4-x86/x32/init.cc | 17 +- kernel/src/glue/v4-x86/x32/space.h | 1 + kernel/src/glue/v4-x86/x32/tcb.h | 8 +- kernel/src/glue/v4-x86/x32/trap.S | 6 +- kernel/src/glue/v4-x86/x64/config.h | 3 +- kernel/src/glue/v4-x86/x64/init.cc | 25 +- kernel/src/kdb/init.h | 4 +- kernel/src/kdb/tracebuffer.h | 7 +- user/apps/bench/pingpong/amd64.h | 3 - user/apps/bench/pingpong/crt0-ia32.S | 2 +- user/apps/bench/pingpong/ia32.h | 2 - user/apps/bench/pingpong/pingpong.cc | 61 +--- user/apps/bench/pingpong/powerpc.h | 2 +- user/apps/l4test/sig0.cc | 2 +- user/include/l4/amd64/specials.h | 31 ++ user/include/l4/amd64/tracebuffer.h | 243 ++++---------- user/include/l4/ia32/specials.h | 44 ++- user/include/l4/ia32/tracebuffer.h | 296 ++++-------------- user/include/l4/kip.h | 22 +- user/include/l4/powerpc/specials.h | 21 ++ user/include/l4/tracebuffer.h | 164 +++++++--- user/lib/io/Makefile.in | 8 +- user/lib/io/amd64-putc.cc | 121 ------- user/lib/io/{ia32-putc.cc => amd64.cc} | 96 +++++- user/lib/io/{amd64-port.h => amd64.h} | 0 user/lib/io/ia32-getc.cc | 104 ------ user/lib/io/{amd64-getc.cc => ia32.cc} | 124 +++++++- user/lib/io/{ia32-port.h => ia32.h} | 0 user/lib/io/{powerpc-io.cc => powerpc.cc} | 9 +- user/lib/io/{powerpc-port.h => powerpc.h} | 0 .../io/{powerpc64-putc.cc => powerpc64.cc} | 8 + user/lib/l4/Makefile.in | 9 +- user/lib/l4/{amd64-syscalls.c => amd64.cc} | 8 +- .../lib/{io/powerpc64-getc.cc => l4/debug.cc} | 62 ++-- user/lib/l4/{ia32-syscall-init.cc => ia32.cc} | 0 .../lib/l4/{powerpc-syscalls.c => powerpc.cc} | 6 +- .../l4/{powerpc64-syscalls.c => powerpc64.cc} | 0 user/serv/sigma0/Makefile.in | 3 +- user/util/kickstart/Makefile.in | 2 +- 56 files changed, 757 insertions(+), 977 deletions(-) delete mode 100644 user/lib/io/amd64-putc.cc rename user/lib/io/{ia32-putc.cc => amd64.cc} (58%) rename user/lib/io/{amd64-port.h => amd64.h} (100%) delete mode 100644 user/lib/io/ia32-getc.cc rename user/lib/io/{amd64-getc.cc => ia32.cc} (53%) rename user/lib/io/{ia32-port.h => ia32.h} (100%) rename user/lib/io/{powerpc-io.cc => powerpc.cc} (97%) rename user/lib/io/{powerpc-port.h => powerpc.h} (100%) rename user/lib/io/{powerpc64-putc.cc => powerpc64.cc} (91%) rename user/lib/l4/{amd64-syscalls.c => amd64.cc} (93%) rename user/lib/{io/powerpc64-getc.cc => l4/debug.cc} (52%) rename user/lib/l4/{ia32-syscall-init.cc => ia32.cc} (100%) rename user/lib/l4/{powerpc-syscalls.c => powerpc.cc} (95%) rename user/lib/l4/{powerpc64-syscalls.c => powerpc64.cc} (100%) diff --git a/kernel/kdb/generic/tracebuffer.cc b/kernel/kdb/generic/tracebuffer.cc index 622894af..b32a28ca 100644 --- a/kernel/kdb/generic/tracebuffer.cc +++ b/kernel/kdb/generic/tracebuffer.cc @@ -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; } diff --git a/kernel/src/api/v4/space.cc b/kernel/src/api/v4/space.cc index b6ef882a..b904c705 100644 --- a/kernel/src/api/v4/space.cc +++ b/kernel/src/api/v4/space.cc @@ -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); } + diff --git a/kernel/src/arch/powerpc/page.h b/kernel/src/arch/powerpc/page.h index 919a3e41..0b419b0e 100644 --- a/kernel/src/arch/powerpc/page.h +++ b/kernel/src/arch/powerpc/page.h @@ -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 diff --git a/kernel/src/arch/powerpc/softhvm.h b/kernel/src/arch/powerpc/softhvm.h index 06482456..8459ff28 100644 --- a/kernel/src/arch/powerpc/softhvm.h +++ b/kernel/src/arch/powerpc/softhvm.h @@ -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 diff --git a/kernel/src/arch/powerpc/tracebuffer.h b/kernel/src/arch/powerpc/tracebuffer.h index 0bfb40c1..cc82f1c9 100644 --- a/kernel/src/arch/powerpc/tracebuffer.h +++ b/kernel/src/arch/powerpc/tracebuffer.h @@ -31,7 +31,7 @@ #include #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(); diff --git a/kernel/src/arch/x86/tracebuffer.h b/kernel/src/arch/x86/tracebuffer.h index ff020f57..64ffcfc2 100644 --- a/kernel/src/arch/x86/tracebuffer.h +++ b/kernel/src/arch/x86/tracebuffer.h @@ -34,13 +34,6 @@ #include INC_ARCH(cpu.h) #include -#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__ */ diff --git a/kernel/src/generic/debug.h b/kernel/src/generic/debug.h index ea938e4f..a86a3bab 100644 --- a/kernel/src/generic/debug.h +++ b/kernel/src/generic/debug.h @@ -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) diff --git a/kernel/src/glue/v4-powerpc/init.cc b/kernel/src/glue/v4-powerpc/init.cc index 02eb1b12..b86e221b 100644 --- a/kernel/src/glue/v4-powerpc/init.cc +++ b/kernel/src/glue/v4-powerpc/init.cc @@ -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 ) { diff --git a/kernel/src/glue/v4-powerpc/space-swtlb.cc b/kernel/src/glue/v4-powerpc/space-swtlb.cc index ea408e69..f77040fd 100644 --- a/kernel/src/glue/v4-powerpc/space-swtlb.cc +++ b/kernel/src/glue/v4-powerpc/space-swtlb.cc @@ -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; diff --git a/kernel/src/glue/v4-powerpc/space.cc b/kernel/src/glue/v4-powerpc/space.cc index 675117fc..02ef551e 100644 --- a/kernel/src/glue/v4-powerpc/space.cc +++ b/kernel/src/glue/v4-powerpc/space.cc @@ -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; diff --git a/kernel/src/glue/v4-powerpc/space.h b/kernel/src/glue/v4-powerpc/space.h index 4333dec4..aab8c1b5 100644 --- a/kernel/src/glue/v4-powerpc/space.h +++ b/kernel/src/glue/v4-powerpc/space.h @@ -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; }; diff --git a/kernel/src/glue/v4-x86/init.cc b/kernel/src/glue/v4-x86/init.cc index 7a248dca..e223576c 100644 --- a/kernel/src/glue/v4-x86/init.cc +++ b/kernel/src/glue/v4-x86/init.cc @@ -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 diff --git a/kernel/src/glue/v4-x86/space.cc b/kernel/src/glue/v4-x86/space.cc index 2aa324db..0a3820cc 100644 --- a/kernel/src/glue/v4-x86/space.cc +++ b/kernel/src/glue/v4-x86/space.cc @@ -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[]; diff --git a/kernel/src/glue/v4-x86/space.h b/kernel/src/glue/v4-x86/space.h index 6080fc47..5d39a0f5 100644 --- a/kernel/src/glue/v4-x86/space.h +++ b/kernel/src/glue/v4-x86/space.h @@ -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)); diff --git a/kernel/src/glue/v4-x86/thread.cc b/kernel/src/glue/v4-x86/thread.cc index 4550f2e0..2052a3dc 100644 --- a/kernel/src/glue/v4-x86/thread.cc +++ b/kernel/src/glue/v4-x86/thread.cc @@ -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) ); } diff --git a/kernel/src/glue/v4-x86/x32/config.h b/kernel/src/glue/v4-x86/x32/config.h index 463f7872..b8ebb6f0 100644 --- a/kernel/src/glue/v4-x86/x32/config.h +++ b/kernel/src/glue/v4-x86/x32/config.h @@ -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) diff --git a/kernel/src/glue/v4-x86/x32/hvm-vmx.cc b/kernel/src/glue/v4-x86/x32/hvm-vmx.cc index e29b1ca7..609e84a9 100644 --- a/kernel/src/glue/v4-x86/x32/hvm-vmx.cc +++ b/kernel/src/glue/v4-x86/x32/hvm-vmx.cc @@ -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 ); } diff --git a/kernel/src/glue/v4-x86/x32/init.cc b/kernel/src/glue/v4-x86/x32/init.cc index c032ac22..c04ec76d 100644 --- a/kernel/src/glue/v4-x86/x32/init.cc +++ b/kernel/src/glue/v4-x86/x32/init.cc @@ -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" ); diff --git a/kernel/src/glue/v4-x86/x32/space.h b/kernel/src/glue/v4-x86/x32/space.h index cbf150c7..336bb1cc 100644 --- a/kernel/src/glue/v4-x86/x32/space.h +++ b/kernel/src/glue/v4-x86/x32/space.h @@ -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 diff --git a/kernel/src/glue/v4-x86/x32/tcb.h b/kernel/src/glue/v4-x86/x32/tcb.h index ffa0838c..673de284 100644 --- a/kernel/src/glue/v4-x86/x32/tcb.h +++ b/kernel/src/glue/v4-x86/x32/tcb.h @@ -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" diff --git a/kernel/src/glue/v4-x86/x32/trap.S b/kernel/src/glue/v4-x86/x32/trap.S index 4356ddba..1d07791d 100644 --- a/kernel/src/glue/v4-x86/x32/trap.S +++ b/kernel/src/glue/v4-x86/x32/trap.S @@ -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 diff --git a/kernel/src/glue/v4-x86/x64/config.h b/kernel/src/glue/v4-x86/x64/config.h index 2f098115..5d32d5ed 100644 --- a/kernel/src/glue/v4-x86/x64/config.h +++ b/kernel/src/glue/v4-x86/x64/config.h @@ -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 */ diff --git a/kernel/src/glue/v4-x86/x64/init.cc b/kernel/src/glue/v4-x86/x64/init.cc index 49caafa8..42871cad 100644 --- a/kernel/src/glue/v4-x86/x64/init.cc +++ b/kernel/src/glue/v4-x86/x64/init.cc @@ -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 - } /** diff --git a/kernel/src/kdb/init.h b/kernel/src/kdb/init.h index f3937def..e61d978f 100644 --- a/kernel/src/kdb/init.h +++ b/kernel/src/kdb/init.h @@ -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 diff --git a/kernel/src/kdb/tracebuffer.h b/kernel/src/kdb/tracebuffer.h index 7660b344..c8587b2f 100644 --- a/kernel/src/kdb/tracebuffer.h +++ b/kernel/src/kdb/tracebuffer.h @@ -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) diff --git a/user/apps/bench/pingpong/amd64.h b/user/apps/bench/pingpong/amd64.h index 74ef10a9..5d6627c2 100644 --- a/user/apps/bench/pingpong/amd64.h +++ b/user/apps/bench/pingpong/amd64.h @@ -31,9 +31,6 @@ ********************************************************************/ #include -#undef L4_TRACEBUFFER -#include - #include L4_COMPAT_H_LOCATION diff --git a/user/apps/bench/pingpong/crt0-ia32.S b/user/apps/bench/pingpong/crt0-ia32.S index 45f58188..462b264f 100644 --- a/user/apps/bench/pingpong/crt0-ia32.S +++ b/user/apps/bench/pingpong/crt0-ia32.S @@ -1,6 +1,6 @@ /********************************************************************* * - * Copyright (C) 2003, Karlsruhe University + * Copyright (C) 2003, 2010, Karlsruhe University * * File path: bench/pingpong/crt0-ia32.S * Description: diff --git a/user/apps/bench/pingpong/ia32.h b/user/apps/bench/pingpong/ia32.h index 89ea2d1f..8c8b2ddf 100644 --- a/user/apps/bench/pingpong/ia32.h +++ b/user/apps/bench/pingpong/ia32.h @@ -32,8 +32,6 @@ ********************************************************************/ #include -#define L4_TRACEBUFFER - #define HAVE_HANDLE_ARCH_PAGEFAULT #define HAVE_READ_CYCLES #define HAVE_ARCH_IPC diff --git a/user/apps/bench/pingpong/pingpong.cc b/user/apps/bench/pingpong/pingpong.cc index ba3f930e..0eb59f62 100644 --- a/user/apps/bench/pingpong/pingpong.cc +++ b/user/apps/bench/pingpong/pingpong.cc @@ -38,35 +38,6 @@ #include #include -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 +#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 (;;) { diff --git a/user/apps/bench/pingpong/powerpc.h b/user/apps/bench/pingpong/powerpc.h index 51f77f46..2248aeb0 100644 --- a/user/apps/bench/pingpong/powerpc.h +++ b/user/apps/bench/pingpong/powerpc.h @@ -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 diff --git a/user/apps/l4test/sig0.cc b/user/apps/l4test/sig0.cc index 6bc03bc0..645ca732 100644 --- a/user/apps/l4test/sig0.cc +++ b/user/apps/l4test/sig0.cc @@ -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); diff --git a/user/include/l4/amd64/specials.h b/user/include/l4/amd64/specials.h index fefee21e..35bcb23e 100644 --- a/user/include/l4/amd64/specials.h +++ b/user/include/l4/amd64/specials.h @@ -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__ */ diff --git a/user/include/l4/amd64/tracebuffer.h b/user/include/l4/amd64/tracebuffer.h index 15db400c..6dff48a8 100644 --- a/user/include/l4/amd64/tracebuffer.h +++ b/user/include/l4/amd64/tracebuffer.h @@ -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__ */ diff --git a/user/include/l4/ia32/specials.h b/user/include/l4/ia32/specials.h index f29bb5c6..7d733154 100644 --- a/user/include/l4/ia32/specials.h +++ b/user/include/l4/ia32/specials.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 * 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__ */ diff --git a/user/include/l4/ia32/tracebuffer.h b/user/include/l4/ia32/tracebuffer.h index a893a685..29691726 100644 --- a/user/include/l4/ia32/tracebuffer.h +++ b/user/include/l4/ia32/tracebuffer.h @@ -30,245 +30,69 @@ #ifndef __L4__IA32__TRACEBUFFER_H__ #define __L4__IA32__TRACEBUFFER_H__ -#include +#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 - -#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__ */ diff --git a/user/include/l4/kip.h b/user/include/l4/kip.h index 87ead47d..4ea2abd4 100644 --- a/user/include/l4/kip.h +++ b/user/include/l4/kip.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 * 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 { diff --git a/user/include/l4/powerpc/specials.h b/user/include/l4/powerpc/specials.h index 046bf922..db199f58 100644 --- a/user/include/l4/powerpc/specials.h +++ b/user/include/l4/powerpc/specials.h @@ -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__ */ + diff --git a/user/include/l4/tracebuffer.h b/user/include/l4/tracebuffer.h index e0406dd7..2af57935 100644 --- a/user/include/l4/tracebuffer.h +++ b/user/include/l4/tracebuffer.h @@ -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 -#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__ */ diff --git a/user/lib/io/Makefile.in b/user/lib/io/Makefile.in index 6178344c..e12aeaca 100644 --- a/user/lib/io/Makefile.in +++ b/user/lib/io/Makefile.in @@ -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 diff --git a/user/lib/io/amd64-putc.cc b/user/lib/io/amd64-putc.cc deleted file mode 100644 index 92394f1d..00000000 --- a/user/lib/io/amd64-putc.cc +++ /dev/null @@ -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 -#include - -#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 diff --git a/user/lib/io/ia32-putc.cc b/user/lib/io/amd64.cc similarity index 58% rename from user/lib/io/ia32-putc.cc rename to user/lib/io/amd64.cc index c8a0baa3..c30f7fe7 100644 --- a/user/lib/io/ia32-putc.cc +++ b/user/lib/io/amd64.cc @@ -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 #include -#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 diff --git a/user/lib/io/amd64-port.h b/user/lib/io/amd64.h similarity index 100% rename from user/lib/io/amd64-port.h rename to user/lib/io/amd64.h diff --git a/user/lib/io/ia32-getc.cc b/user/lib/io/ia32-getc.cc deleted file mode 100644 index 4c0a2ca9..00000000 --- a/user/lib/io/ia32-getc.cc +++ /dev/null @@ -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 -#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 diff --git a/user/lib/io/amd64-getc.cc b/user/lib/io/ia32.cc similarity index 53% rename from user/lib/io/amd64-getc.cc rename to user/lib/io/ia32.cc index e88d7f6f..2750951b 100644 --- a/user/lib/io/amd64-getc.cc +++ b/user/lib/io/ia32.cc @@ -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 #include -#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; diff --git a/user/lib/io/ia32-port.h b/user/lib/io/ia32.h similarity index 100% rename from user/lib/io/ia32-port.h rename to user/lib/io/ia32.h diff --git a/user/lib/io/powerpc-io.cc b/user/lib/io/powerpc.cc similarity index 97% rename from user/lib/io/powerpc-io.cc rename to user/lib/io/powerpc.cc index 0c7e915e..e18656b9 100644 --- a/user/lib/io/powerpc-io.cc +++ b/user/lib/io/powerpc.cc @@ -2,7 +2,7 @@ * * Copyright (C) 2010, Karlsruhe Institute of Technology * - * Filename: powerpc-io.cc + * Filename: powerpc.cc * Author: Jan Stoess * Description: * @@ -48,14 +48,12 @@ extern "C" void putc( int c ) __attribute__ ((weak, alias("__l4_putc"))); #if defined(CONFIG_COMPORT) #include -#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; diff --git a/user/lib/io/powerpc-port.h b/user/lib/io/powerpc.h similarity index 100% rename from user/lib/io/powerpc-port.h rename to user/lib/io/powerpc.h diff --git a/user/lib/io/powerpc64-putc.cc b/user/lib/io/powerpc64.cc similarity index 91% rename from user/lib/io/powerpc64-putc.cc rename to user/lib/io/powerpc64.cc index e3553419..a8d51d7c 100644 --- a/user/lib/io/powerpc64-putc.cc +++ b/user/lib/io/powerpc64.cc @@ -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(); +} diff --git a/user/lib/l4/Makefile.in b/user/lib/l4/Makefile.in index 4de09fb1..c6cbf49e 100644 --- a/user/lib/l4/Makefile.in +++ b/user/lib/l4/Makefile.in @@ -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 diff --git a/user/lib/l4/amd64-syscalls.c b/user/lib/l4/amd64.cc similarity index 93% rename from user/lib/l4/amd64-syscalls.c rename to user/lib/l4/amd64.cc index 098b3237..8033c4e3 100644 --- a/user/lib/l4/amd64-syscalls.c +++ b/user/lib/l4/amd64.cc @@ -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); diff --git a/user/lib/io/powerpc64-getc.cc b/user/lib/l4/debug.cc similarity index 52% rename from user/lib/io/powerpc64-getc.cc rename to user/lib/l4/debug.cc index 2055e4a3..77c5d76e 100644 --- a/user/lib/io/powerpc64-getc.cc +++ b/user/lib/l4/debug.cc @@ -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 + * 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 +#include -#include -#include +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; +} diff --git a/user/lib/l4/ia32-syscall-init.cc b/user/lib/l4/ia32.cc similarity index 100% rename from user/lib/l4/ia32-syscall-init.cc rename to user/lib/l4/ia32.cc diff --git a/user/lib/l4/powerpc-syscalls.c b/user/lib/l4/powerpc.cc similarity index 95% rename from user/lib/l4/powerpc-syscalls.c rename to user/lib/l4/powerpc.cc index 8600666a..e85e020c 100644 --- a/user/lib/l4/powerpc-syscalls.c +++ b/user/lib/l4/powerpc.cc @@ -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) diff --git a/user/lib/l4/powerpc64-syscalls.c b/user/lib/l4/powerpc64.cc similarity index 100% rename from user/lib/l4/powerpc64-syscalls.c rename to user/lib/l4/powerpc64.cc diff --git a/user/serv/sigma0/Makefile.in b/user/serv/sigma0/Makefile.in index ce330392..0e8fab38 100644 --- a/user/serv/sigma0/Makefile.in +++ b/user/serv/sigma0/Makefile.in @@ -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 diff --git a/user/util/kickstart/Makefile.in b/user/util/kickstart/Makefile.in index 27221d76..52261ba2 100644 --- a/user/util/kickstart/Makefile.in +++ b/user/util/kickstart/Makefile.in @@ -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 ##