# 1 "apic.cc" # 1 "apic.h" 1 # 1 "types.h" 1 # 1 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 1 3 # 61 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 3 typedef int ptrdiff_t; typedef unsigned int size_t; typedef unsigned int wint_t; # 317 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 3 # 7 "types.h" 2 typedef unsigned char unsigned8; typedef signed char signed8; typedef unsigned short unsigned16; typedef signed short signed16; typedef unsigned int unsigned32; typedef signed int signed32; typedef unsigned long long int unsigned64; typedef signed long long int signed64; typedef unsigned char Unsigned8; typedef signed char Signed8; typedef unsigned short Unsigned16; typedef signed short Signed16; typedef unsigned int Unsigned32; typedef signed int Signed32; typedef unsigned long long int Unsigned64; typedef signed long long int Signed64; typedef signed32 smword_t; typedef unsigned32 mword_t; typedef Signed32 Smword; typedef Unsigned32 Mword; typedef Unsigned32 vm_offset_t; typedef Unsigned32 addr_t; typedef Unsigned32 Address; typedef Unsigned32 vm_size_t; typedef Unsigned64 cpu_time_t; typedef Unsigned64 Cpu_time; typedef unsigned32 dword_t; typedef unsigned16 word_t; typedef unsigned8 byte_t; typedef struct { unsigned32 low, high; } l4_low_high_t; typedef struct { addr_t low, high; } l4_addr_range_t; typedef smword_t ssize_t; # 6 "apic.h" 2 class apic { public: typedef enum { APIC_NONE, APIC_P6, APIC_P4, APIC_K7 } apic_type_t; static bool ignore_invalid_reg_access; private: apic(); apic(const apic&); static bool present; static const addr_t io_base; static unsigned timer_divisor; static apic_type_t type; static unsigned frequency_khz; static unsigned max_lvt; public: static unsigned get_frequency_khz(); static unsigned reg_read(unsigned reg); static void reg_write(unsigned reg, unsigned val); static void timer_enable_irq(); static void timer_disable_irq(); static int timer_is_irq_enabled(); static void irq_ack(); static int is_present(); static int cpu_type(); static int have_pcint(); static void set_perf_nmi(); static void init(); private: static unsigned timer_reg_read(); static void timer_reg_write(unsigned val); static int test_cpu(); static int test_present(); static void timer_set_divisor(unsigned newdiv); static int get_maxlvt(); static int check_working(); static void soft_enable(); static void err_enable(); static void activate_by_io(); static void activate_by_msr(); static int check_still_getting_irqs(); static int try_to_activate(); static void calibrate_timer(); }; extern unsigned apic_spurious_interrupt_bug_cnt; extern unsigned apic_spurious_interrupt_cnt; extern unsigned apic_error_cnt; extern "C" void apic_error_interrupt(struct thread_ret_regs_t *ret_regs); inline unsigned apic::get_frequency_khz() { return frequency_khz; } inline unsigned apic::reg_read(unsigned reg) { return *((volatile unsigned*)(io_base + reg)); } inline void apic::reg_write(unsigned reg, unsigned val) { *((volatile unsigned*)(io_base + reg)) = val; } inline void apic::timer_enable_irq() { unsigned tmp_val; tmp_val = reg_read(0x320 ); tmp_val &= ~((1<<16) ); reg_write(0x320 , tmp_val); } inline void apic::timer_disable_irq() { unsigned tmp_val; tmp_val = reg_read(0x320 ); tmp_val |= (1<<16) ; reg_write(0x320 , tmp_val); } inline int apic::timer_is_irq_enabled() { return ~reg_read(0x320 ) & (1<<16) ; } inline void apic::irq_ack() { reg_read(0xF0 ); reg_write(0xB0 , 0); } inline int apic::is_present() { return present; } inline int apic::cpu_type() { return type; } # 3 "apic.cc" 2 # 1 "apic_i.h" 1 # 1 "../lib/minilibc/include/cstdio" 1 # 1 "../lib/minilibc/include/stdio.h" 1 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/cdefs.h" 1 # 4 "../lib/minilibc/include/stdio.h" 2 # 1 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 1 3 # 342 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 3 # 5 "../lib/minilibc/include/stdio.h" 2 # 1 "../lib/minilibc/include/mini_defs.h" 1 # 6 "../lib/minilibc/include/stdio.h" 2 extern "C" { int putchar(int c); int puts(const char *s); int printf(const char *format, ...) __attribute__((format(printf,1,2))); int sprintf(char *str, const char *format, ...) __attribute__((format(printf,2,3))); int snprintf(char *str, size_t size, const char *format, ...) __attribute__((format(printf,3,4))); int asprintf(char **ptr, const char* format, ...) __attribute__((format(printf,2,3))); # 1 "../lib/minilibc/include/stdarg.h" 1 # 15 "../lib/minilibc/include/stdarg.h" # 1 "../lib/minilibc/include/stdarg-cruft.h" 1 # 24 "../lib/minilibc/include/stdarg-cruft.h" # 278 "../lib/minilibc/include/stdarg-cruft.h" typedef char* va_list; # 19 "../lib/minilibc/include/stdarg.h" 2 # 22 "../lib/minilibc/include/stdio.h" 2 int vprintf(const char *format, va_list ap) __attribute__((format(printf,1,0))); int vsprintf(char *str, const char *format, va_list ap) __attribute__((format(printf,2,0))); int vsnprintf(char *str, size_t size, const char *format, va_list ap) __attribute__((format(printf,3,0))); typedef int FILE; int getchar(void); char *gets(char *s) ; char *fgets(char *s, int size, FILE *stream); int vscanf(const char *format, va_list ap) __attribute__((format(scanf,1,0))); int vsscanf(const char *str, const char *format, va_list ap) __attribute__((format(scanf,2,0))); int sscanf(const char *str, const char *format, ...); } # 6 "../lib/minilibc/include/cstdio" 2 # 28 "../lib/minilibc/include/cstdio" # 6 "apic_i.h" 2 # 1 "../lib/minilibc/include/cstdlib" 1 # 1 "../lib/minilibc/include/stdlib.h" 1 # 1 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 1 3 # 342 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 3 # 5 "../lib/minilibc/include/stdlib.h" 2 extern "C" { int atexit(void (*function)(void)); double strtod(const char *nptr, char **endptr); long int strtol(const char *nptr, char **endptr, int base); unsigned long int strtoul(const char *nptr, char **endptr, int base); extern int __ltostr(char *s, unsigned int size, unsigned long i, unsigned int base, int UpCase); extern int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec); __extension__ long long int strtoll(const char *nptr, char **endptr, int base); __extension__ unsigned long long int strtoull(const char *nptr, char **endptr, int base); __extension__ int __lltostr(char *s, unsigned int size, unsigned long long i, unsigned int base, int UpCase); int atoi(const char *nptr); long int atol(const char *nptr); double atof(const char *nptr); void exit(int status) __attribute__((noreturn)); void abort(void); typedef struct { int quot,rem; } div_t; div_t div(int numer, int denom) __attribute__((const)); typedef struct { long int quot,rem; } ldiv_t; ldiv_t ldiv(long int numer, long int denom) __attribute__((const)); typedef struct { long long int quot,rem; } lldiv_t; lldiv_t lldiv(long long int numer, long long int denom) __attribute__((const)); int abs(int i) __attribute__((const)); long int labs(long int i) __attribute__((const)); __extension__ long long int llabs(long long int i) __attribute__((const)); } # 6 "../lib/minilibc/include/cstdlib" 2 namespace std { # 31 "../lib/minilibc/include/cstdlib" inline long abs(long i) { return labs(i); } inline long long abs(long long i) { return llabs(i); } inline ldiv_t div( long i, long j ) { return ldiv(i,j); } inline lldiv_t div( long long i, long long j ) { return lldiv(i,j); } }; # 7 "apic_i.h" 2 # 1 "../lib/minilibc/include/cstring" 1 # 1 "../lib/minilibc/include/string.h" 1 # 1 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 1 3 # 342 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 3 # 5 "../lib/minilibc/include/string.h" 2 extern "C" { char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n); void *memccpy(void *dest, const void *src, int c, size_t n); void *memcpy(void *dest, const void *src, size_t n); void *memmove(void *dest, const void *src, size_t n); int memccmp(const void *s1, const void *s2, int c, size_t n); int memcmp(const void *s1, const void *s2, size_t n); int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); int strcasecmp(const char *s1, const char *s2); int strncasecmp(const char *s1, const char *s2, size_t n); size_t strlen(const char *s); char *strstr(const char *haystack, const char *needle); char *strdup(const char *s); char *strchr(const char *s, int c); char *strrchr(const char *s, int c); char *strcat(char *dest, const char *src); char *strncat(char *dest, const char *src, size_t n); size_t strspn(const char *s, const char *_accept); size_t strcspn(const char *s, const char *reject); char *strpbrk(const char *s, const char *_accept); char *strsep(char **stringp, const char *delim); void* memset(void *s, int c, size_t n); void* memchr(const void *s, int c, size_t n); int strcoll(const char *s1, const char *s2); } # 6 "../lib/minilibc/include/cstring" 2 namespace std { # 68 "../lib/minilibc/include/cstring" }; # 8 "apic_i.h" 2 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/pio.h" 1 # 9 "apic_i.h" 2 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/pc/pic.h" 1 extern "C" { extern void pic_init(unsigned char master_base, unsigned char slave_base); extern void pic_disable_irq(unsigned char irq); extern void pic_enable_irq(unsigned char irq); } # 10 "apic_i.h" 2 # 1 "cpu.h" 1 class Cpu { private: static unsigned cpu_sysenter_stack asm ("CPU_SYSENTER_STACK"); static unsigned cpu_version; static unsigned cpu_apic; static unsigned cpu_features asm ("CPU_FEATURES"); static char cpu_vendor[13]; public: static void set_sysenter_stack(unsigned stackptr); static const char * vendor(); static unsigned int family(); static unsigned int model(); static unsigned int stepping(); static unsigned int apic(); static unsigned int features(); static void identify(); static void init(void); private: static void bochs_tweaks(); static void wrmsr(unsigned ecx, unsigned eax, unsigned edx); static void cpuid(unsigned mode, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx); }; inline void Cpu::set_sysenter_stack(unsigned stackptr) { cpu_sysenter_stack = stackptr; } # 12 "apic_i.h" 2 # 1 "globals.h" 1 # 1 "../lib/minilibc/include/cassert" 1 # 1 "../lib/minilibc/include/assert.h" 1 extern "C" { void __assert_fail (const char *__assertion, const char *__file, unsigned int __line, const char *__function) __attribute__ ((__noreturn__)); } # 6 "../lib/minilibc/include/cassert" 2 # 6 "globals.h" 2 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/multiboot.h" 1 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/types.h" 1 typedef unsigned int natural_t; typedef int integer_t; typedef natural_t vm_offset_t; typedef natural_t vm_size_t; typedef signed char signed8_t; typedef signed short signed16_t; typedef signed long signed32_t; typedef signed long long signed64_t; typedef unsigned char unsigned8_t; typedef unsigned short unsigned16_t; typedef unsigned long unsigned32_t; typedef unsigned long long unsigned64_t; typedef float float32_t; typedef double float64_t; # 24 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/multiboot.h" 2 struct multiboot_header { unsigned magic; unsigned flags; unsigned checksum; vm_offset_t header_addr; vm_offset_t load_addr; vm_offset_t load_end_addr; vm_offset_t bss_end_addr; vm_offset_t entry; }; struct multiboot_info { unsigned flags; vm_size_t mem_lower; vm_size_t mem_upper; unsigned char boot_device[4]; vm_offset_t cmdline; unsigned mods_count; vm_offset_t mods_addr; union { struct { vm_size_t tabsize; vm_size_t strsize; vm_offset_t addr; unsigned reserved; } a; struct { unsigned num; vm_size_t size; vm_offset_t addr; unsigned shndx; } e; } syms; vm_size_t mmap_count; vm_offset_t mmap_addr; }; struct multiboot_module { vm_offset_t mod_start; vm_offset_t mod_end; vm_offset_t string; unsigned reserved; }; struct AddrRangeDesc { unsigned long size; unsigned long BaseAddrLow; unsigned long BaseAddrHigh; unsigned long LengthLow; unsigned long LengthHigh; unsigned long Type; }; # 10 "globals.h" 2 class Context; class Thread; class Space; extern Thread *sigma0_thread, *kernel_thread, *nil_thread; extern Space *sigma0; extern bool running; # 39 "globals.h" Context *context_of(const void *ptr); Context *current(); # 1 "config.h" 1 # 1 "../globalconfig.h" 1 # 6 "config.h" 2 # 1 "l4_types.h" 1 typedef struct { mword_t msg_deceited:1; mword_t fpage_received:1; mword_t msg_redirected:1; mword_t src_inside:1; mword_t snd_error:1; mword_t error_code:3; mword_t strings:5; mword_t dwords:19; } l4_msgdope_struct_t; typedef struct { mword_t rcv_exp:4; mword_t snd_exp:4; mword_t rcv_pfault:4; mword_t snd_pfault:4; mword_t snd_man:8; mword_t rcv_man:8; } l4_timeout_struct_t; typedef struct { mword_t version_low:10; mword_t lthread:7; mword_t task:11; mword_t version_high:4; mword_t site:17; mword_t chief:11; mword_t nest:4; } l4_threadid_struct_t; typedef union { unsigned64 raw; l4_low_high_t lh; l4_threadid_struct_t id; } l4_threadid_t; typedef l4_threadid_t l4_taskid_t; typedef struct { mword_t intr:8; unsigned8 zero[7]; } l4_intrid_struct_t; typedef union { unsigned64 raw; l4_low_high_t lh; l4_intrid_struct_t id; } l4_intrid_t; typedef struct { mword_t grant: 1; mword_t write: 1; mword_t size: 7; mword_t zero: 3; mword_t page: (32) -12; } l4_fpage_struct_t; typedef struct { mword_t grant: 1; mword_t zero1: 1; mword_t iosize: 6; mword_t zero2: 4; mword_t iopage: 16; mword_t f: (32) -28; } l4_iofpage_struct_t; typedef union { mword_t fpage; l4_fpage_struct_t fp; l4_iofpage_struct_t iofp; } l4_fpage_t; typedef struct { mword_t snd_base; l4_fpage_t fpage; } l4_snd_fpage_t; typedef union { mword_t msgdope; mword_t as_int; mword_t raw; l4_msgdope_struct_t md; } l4_msgdope_t; typedef struct { mword_t snd_size; mword_t snd_str; mword_t rcv_size; mword_t rcv_str; } l4_strdope_t; typedef union { mword_t timeout; mword_t as_int; mword_t raw; l4_timeout_struct_t to; } l4_timeout_t; typedef union { struct { mword_t d:1; mword_t m:1; mword_t addr: (32) -2; } sd; mword_t as_int; mword_t raw; } l4_send_desc_t; typedef union { struct { mword_t o:1; mword_t m:1; mword_t addr: (32) -2; } rd; mword_t as_int; mword_t raw; } l4_recv_desc_t; typedef struct { mword_t prio:8; mword_t small:8; mword_t zero:4; mword_t time_exp:4; mword_t time_man:8; } l4_sched_param_struct_t; typedef union { mword_t sched_param; l4_sched_param_struct_t sp; } l4_sched_param_t; int l4_is_invalid_sched_param(l4_sched_param_t sp); int l4_is_nil_id(l4_threadid_t id); int l4_is_invalid_id(l4_threadid_t id); l4_fpage_t l4_fpage(unsigned long address, unsigned int size, unsigned char write, unsigned char grant); l4_fpage_t l4_iofpage(unsigned port, unsigned int size, unsigned char grant); int l4_is_io_page_fault(unsigned address); l4_threadid_t get_taskid(l4_threadid_t t); int thread_equal(l4_threadid_t t1,l4_threadid_t t2); int task_equal(l4_threadid_t t1,l4_threadid_t t2); void l4_make_taskid_from_irq(int irq, l4_threadid_t *t); inline int l4_is_invalid_sched_param(l4_sched_param_t sp) { return sp.sched_param == 0xffffffff; } inline int l4_is_nil_id(l4_threadid_t id) { return id.lh.low == 0; } inline int l4_is_invalid_id(l4_threadid_t id) { return id.lh.low == 0xffffffff; } inline l4_fpage_t l4_fpage(unsigned long address, unsigned int size, unsigned char write, unsigned char grant) { /* OPENC++ return ((l4_fpage_t){fp:{grant, write, size, 0, (address & (~((0x1000) - 1)) ) >> 12 }}); */ } inline l4_fpage_t l4_iofpage(unsigned port, unsigned int size, unsigned char grant) { /* OPENC++ return ((l4_fpage_t){iofp:{grant, 0, size, 0, port, 0xf}}); */ } inline int l4_is_io_page_fault(unsigned address) { l4_fpage_t t; t.fpage = address; return(t.iofp.f == 0xf); } inline l4_threadid_t get_taskid(l4_threadid_t t) { t.id.lthread = 0; return t; } inline int thread_equal(l4_threadid_t t1,l4_threadid_t t2) { if((t1.lh.low != t2.lh.low) || (t1.lh.high != t2.lh.high)) return 0; return 1; } inline int task_equal(l4_threadid_t t1,l4_threadid_t t2) { if ( ((t1.lh.low & 0xfffe03ff ) == (t2.lh.low & 0xfffe03ff )) && (t1.lh.high == t2.lh.high) ) return 1; else return 0; } inline void l4_make_taskid_from_irq(int irq, l4_threadid_t *t) { t->lh.low = irq+1; t->lh.high = 0; } # 8 "config.h" 2 # 1 "../kern/config_tcbsize.h" 1 # 10 "config.h" 2 class config { public: static const unsigned kernel_version_id = 0x01004444; static const unsigned kernel_mem_per_cent = 20; static const unsigned thread_block_size = (0x800) ; static const unsigned thread_block_mask = (thread_block_size - 1) | ~((thread_block_size << (11+7)) - 1); static const unsigned thread_block_id_factor = thread_block_size/0x400; static const bool conservative = false ; static const bool monitor_page_faults = conservative; static const bool deceit_bit_disables_switch = false ; static const bool fine_grained_cputime = false ; static bool irq_ack_in_kernel; static bool esc_hack; static bool serial_esc; static bool watchdog; static bool apic; static unsigned tbuf_entries; static const bool profiling = false ; static const int profiling_rate = 100; static const int profile_irq = 0; static const unsigned kernel_taskno = 0; static const l4_threadid_t kernel_id; static const unsigned kernel_prio = 1; static const unsigned kernel_mcp = 255; static const unsigned sigma0_taskno = 2; static const l4_threadid_t sigma0_id; static const unsigned sigma0_prio = 0x10; static const unsigned sigma0_mcp = 0; static const unsigned boot_taskno = 4; static const l4_threadid_t boot_id; static const unsigned boot_prio = 0x10; static const unsigned boot_mcp = 255; static const int default_time_slice = 10; private: public: static const char *const kernel_version_string;/*ANNOTATOR = "Welcome to Fiasco!\n" "DD-L4/x86 microkernel (C) 1998-2002 TU Dresden - " "Feb 4 2003" " - gcc: " "2" "." "95";*/ static const mword_t CPAGE_SHIFT = 12; static const mword_t CPAGE_SIZE = 1 << CPAGE_SHIFT; static const bool backward_compatibility = true ; static const bool scheduling_using_pit = false ; static const bool hlt_works_ok = true ; static const bool getchar_does_hlt = true ; static const bool pic_prio_modify = true ; static const bool enable_io_protection = false ; static const unsigned microsec_per_tick = 976LL; static unsigned const default_console_uart = 2; static unsigned const default_console_uart_baudrate = 115200; public: static void init(); }; # 57 "globals.h" 2 inline Context *context_of(const void *ptr) { return reinterpret_cast (reinterpret_cast(ptr) & ~(config::thread_block_size - 1)); } inline Context *current() { void* esp; __asm__ __volatile__ ("movl %%esp, %0" : "=q" (esp)); return context_of (esp); } # 13 "apic_i.h" 2 # 1 "irq.h" 1 # 1 "sender.h" 1 class Receiver; class Sender { public: virtual void ipc_receiver_ready() = 0; private: l4_threadid_t _id; Receiver* _send_partner; Sender* sender_next, * sender_prev; friend class jdb; friend class jdb_thread_list; public: l4_threadid_t id() const; Receiver* receiver() const; bool in_sender_list(); protected: Sender(const l4_threadid_t& id); explicit Sender(const l4_threadid_t& id, int ); void set_receiver(Receiver* receiver); void sender_enqueue(Sender **r); void sender_dequeue(Sender **r); }; # 1 "cpu_lock.h" 1 class Cpu_lock { public: Cpu_lock(); bool test() const; void lock(); void clear(); bool test_and_set(); void set(bool state); private: Cpu_lock (const Cpu_lock&); }; extern Cpu_lock cpu_lock; # 1 "../lib/libk/processor.h" 1 # 1 "../lib/libk/ia32/processor-arch.h" 1 # 1 "std_macros.h" 1 # 1 "../globalconfig.h" 1 # 6 "std_macros.h" 2 # 7 "../lib/libk/ia32/processor-arch.h" 2 namespace Proc { typedef Unsigned32 Status; inline void cli() { asm volatile (" cli \n"); } inline Status cli_save() { Status ret; asm volatile (" pushfl \n" " popl %0 \n" " cli \n" : "=r"(ret) ); return ret; } inline bool interrupts() { Status ret; asm volatile (" pushfl \n" " popl %0 \n" : "=r"(ret) ); return ret & 0x0200; } inline void sti() { asm volatile (" sti \n"); } inline void sti_restore( Status st ) { asm volatile (" testl $0x0200, %0 \n" " jz 1f \n" " sti \n" " 1: \n" : : "r"(st) ); } }; # 6 "../lib/libk/processor.h" 2 namespace Proc { void cli(); void sti(); bool interrupts(); Status cli_save(); void sti_restore( Status ); }; # 39 "cpu_lock.h" 2 inline bool Cpu_lock::test_and_set() { bool ret = test(); lock(); return ret; } inline void Cpu_lock::set(bool state) { if (state) lock(); else clear(); } inline void Cpu_lock::lock() { Proc::cli(); } inline void Cpu_lock::clear() { Proc::sti(); } inline bool Cpu_lock::test() const { return ! Proc::interrupts(); } # 102 "sender.h" 2 # 1 "lock_guard.h" 1 template class Lock_guard { LOCK *_lock; public: Lock_guard(LOCK *l); ~Lock_guard(); }; template inline Lock_guard::Lock_guard(LOCK *l) : _lock(l) { if (_lock->test_and_set() != false) _lock = 0; } template inline Lock_guard::~Lock_guard() { if (_lock) _lock->clear(); } # 103 "sender.h" 2 inline l4_threadid_t Sender::id() const { return _id; } inline Receiver* Sender::receiver() const { return _send_partner; } inline bool Sender::in_sender_list() { return sender_next; } inline Sender::Sender(const l4_threadid_t& id) : _id (id), sender_next (0) {} inline Sender::Sender(const l4_threadid_t& id, int ) : _id (id) {} inline void Sender::set_receiver(Receiver* receiver) { _send_partner = receiver; } inline void Sender::sender_enqueue(Sender **r) { Lock_guard guard (&cpu_lock); if (! in_sender_list()) { if (*r) { sender_next = *r; sender_prev = sender_next->sender_prev; sender_prev->sender_next = this; sender_next->sender_prev = this; } else { *r = sender_prev = sender_next = this; } } } inline void Sender::sender_dequeue(Sender **r) { Lock_guard guard (&cpu_lock); if (in_sender_list()) { if (sender_next == this) { ((void) (( *r == this ) ? 0 : (__assert_fail ("*r == this", "sender.h", 218, ((const char *) 0) ), 0))) ; *r = 0; } else { if (*r == this) *r = sender_next; sender_prev->sender_next = sender_next; sender_next->sender_prev = sender_prev; } sender_next = 0; } } # 6 "irq.h" 2 class Receiver; class irq_t : public Sender { public: static const unsigned irq_max = 17; virtual bool alloc(Receiver *t, bool ack_in_kernel) = 0; virtual bool free(Receiver *t) = 0; private: irq_t(); irq_t(irq_t&); protected: Receiver *_irq_thread; int _queued; bool _ack_in_kernel; public: explicit irq_t(unsigned irqnum); virtual void ipc_receiver_ready(); void maybe_acknowledge(); void maybe_enable(); private: int consume(); }; extern unsigned pic_mask_master; extern unsigned pic_mask_slave; extern "C" void fast_ret_from_irq(void); void save_disable_irqs(void); void restore_irqs(void); void irq_ack(char irqnum); void irq_disable(unsigned irqnum); void irq_disable_in_cli(unsigned irqnum); void irq_enable(unsigned irqnum); void irq_enable_in_cli(unsigned irqnum); void set_timer_vector_run(void); void set_timer_vector_stop(void); # 1 "atomic.h" 1 extern "C" void cas_error_type_with_bad_size_used(void); /*ANNOTATOR: no template functions template< typename Type > bool up_cas( Type *ptr, Type oldval, Type newval ); template< typename Type > bool smp_cas( Type *ptr, Type oldval, Type newval ); template< typename Type > bool up_cas2( Type *ptr, Type *oldval, Type *newval ); template< typename Type > bool smp_cas2( Type *ptr, Type *oldval, Type *newval ); */ bool up_cas_unsave( Mword *ptr, Mword oldval, Mword newval ); bool smp_cas_unsave( Mword *ptr, Mword oldval, Mword newval ); bool up_cas2_unsave( Mword *ptr, Mword *oldval, Mword *newval ); bool smp_cas2_unsave( Mword *ptr, Mword *oldval, Mword *newval ); bool up_tas( Mword *l ); bool smp_tas( Mword *l ); /* ANNOTATOR: no template functions template< typename Type > inline bool up_cas( Type *ptr, Type oldval, Type newval ) { if( ( sizeof(Type) ) != ( sizeof(Mword) ) ) cas_error_type_with_bad_size_used() ; return up_cas_unsave(reinterpret_cast(ptr), *reinterpret_cast(&oldval), *reinterpret_cast(&newval)); } template< typename Type > inline bool smp_cas( Type *ptr, Type oldval, Type newval ) { if( ( sizeof(Type) ) != ( sizeof(Mword) ) ) cas_error_type_with_bad_size_used() ; return smp_cas_unsave(reinterpret_cast(ptr), *reinterpret_cast(&oldval), *reinterpret_cast(&newval)); } template< typename Type > inline bool up_cas2( Type *ptr, Type *oldval, Type *newval ) { if( ( sizeof(Type) ) != ( (sizeof(Mword)*2) ) ) cas_error_type_with_bad_size_used() ; return up_cas2_unsave(reinterpret_cast(ptr), reinterpret_cast(oldval), reinterpret_cast(newval)); } template< typename Type > inline bool smp_cas2( Type *ptr, Type *oldval, Type *newval ) { if( ( sizeof(Type) ) != ( (sizeof(Mword)*2) ) ) cas_error_type_with_bad_size_used() ; return smp_cas2_unsave(reinterpret_cast(ptr), reinterpret_cast(oldval), reinterpret_cast(newval)); } */ inline bool up_cas_unsave( Mword *ptr, Mword oldval, Mword newval ) { Mword tmp; asm volatile ("cmpxchgl %1,%2" : "=a" (tmp) : "r" (newval), "m" (*ptr), "0" (oldval) : "memory"); return tmp == oldval; } inline bool smp_cas_unsave( Mword *ptr, Mword oldval, Mword newval ) { return up_cas_unsave(ptr,oldval,newval); } inline bool up_cas2_unsave( Mword *ptr, Mword *oldval, Mword *newval ) { char ret; asm volatile ("cmpxchg8b %3 ; sete %%cl" : "=c" (ret), "=a" (* oldval), "=d" (*(oldval+1)) : "m" (*ptr) , "1" (* oldval), "2" (*(oldval+1)), "b" (* newval), "0" (*(newval+1)) : "memory"); return ret; } inline bool smp_cas2_unsave( Mword *ptr, Mword *oldval, Mword *newval ) { return up_cas2_unsave(ptr,oldval,newval); } inline bool up_tas( Mword *l ) { Mword tmp; asm volatile ("xchg %0,%1" : "=r" (tmp) : "m" (*l), "0" (1) : "memory"); return tmp; } inline bool smp_tas( Mword *l ) { return up_tas(l); } # 101 "irq.h" 2 inline void irq_ack(char irqnum) { /* OPENC++ if (irqnum >= 8) { ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( 0x20 )) , "Nd" ((unsigned short)( (0xa0 + 0x00 ) ))); }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( 0x08 | 0x02 | 0x01 )) , "Nd" ((unsigned short)( (0xa0 + 0x00 ) ))); }) ; if (({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0xa0 + 0x00 ) ))); _tmp__; }) ) return; } ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( 0x20 )) , "Nd" ((unsigned short)( (0x20 + 0x00 ) ))); }) ; */ } inline void irq_disable_in_cli(unsigned irqnum) { /* OPENC++ if (irqnum < 8) ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); _tmp__; }) | (1 << irqnum) )) , "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); }) ; else ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); _tmp__; }) | (1 << (irqnum-8)) )) , "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); }) ; */ } inline void irq_t::maybe_acknowledge() { if (_ack_in_kernel) { unsigned irqnum = id().lh.low - 1; irq_disable_in_cli(irqnum); irq_ack(irqnum); } } inline void irq_enable(unsigned irqnum) { Proc::Status flags = Proc::cli_save(); /* OPENC++ if (irqnum < 8) ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); _tmp__; }) & ~(1 << irqnum) )) , "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); }) ; else ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); _tmp__; }) & ~(1 << (irqnum-8)) )) , "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); }) ; */ Proc::sti_restore(flags); } inline void irq_t::maybe_enable() { if (_ack_in_kernel) { unsigned irqnum = id().lh.low - 1; irq_enable(irqnum); } } inline void irq_disable(unsigned irqnum) { Proc::Status flags = Proc::cli_save(); /* OPENC++ if (irqnum < 8) ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); _tmp__; }) | (1 << irqnum) )) , "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); }) ; else ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); _tmp__; }) | (1 << (irqnum-8)) )) , "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); }) ; */ Proc::sti_restore(flags); } inline void irq_enable_in_cli(unsigned irqnum) { /* OPENC++ if (irqnum < 8) ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); _tmp__; }) & ~(1 << irqnum) )) , "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); }) ; else ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); _tmp__; }) & ~(1 << (irqnum-8)) )) , "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); }) ; */ } # 14 "apic_i.h" 2 # 1 "kmem.h" 1 # 1 "kip.h" 1 typedef struct { mword_t magic; mword_t version; mword_t offset_version_strings; mword_t reserved; mword_t init_default_kdebug, default_kdebug_exception, __unknown, default_kdebug_end; mword_t sigma0_esp, sigma0_eip; l4_low_high_t sigma0_memory; mword_t sigma1_esp, sigma1_eip; l4_low_high_t sigma1_memory; mword_t root_esp, root_eip; l4_low_high_t root_memory; mword_t l4_config; mword_t reserved2; mword_t kdebug_config; mword_t kdebug_permission; l4_low_high_t main_memory; l4_low_high_t reserved0, reserved1; l4_low_high_t semi_reserved; l4_low_high_t dedicated[4]; volatile cpu_time_t clock; } l4_kernel_info_t; # 7 "kmem.h" 2 # 1 "../lib/minilibc/include/cstddef" 1 # 1 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 1 3 # 342 "/usr/lib/gcc-lib/i386-linux/2.95.4/include/stddef.h" 3 # 6 "../lib/minilibc/include/cstddef" 2 namespace std { }; # 9 "kmem.h" 2 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/paging.h" 1 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/page.h" 1 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/page.h" 1 # 42 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/page.h" 2 # 35 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/paging.h" 2 # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/proc_reg.h" 1 extern inline unsigned get_eflags() { unsigned eflags; asm volatile("pushf ; popl %0" : "=r" (eflags)); return eflags; } extern inline void set_eflags(unsigned eflags) { asm volatile("pushl %0 ; popf" : : "r" (eflags) : "memory"); } extern inline void cli() { asm volatile ("cli" : : : "memory"); } extern inline void sti() { asm volatile ("sti" : : : "memory"); } extern inline void cld() { asm("cld"); } extern inline void clts() { asm("clts"); } extern inline unsigned short get_cs() { unsigned short cs; asm volatile("movw %%cs,%w0" : "=r" (cs)); return cs; } extern inline unsigned short get_ds() { unsigned short ds; asm volatile("movw %%ds,%w0" : "=r" (ds)); return ds; } extern inline void set_ds(unsigned short ds) { asm volatile("movw %w0,%%ds" : : "r" (ds)); } extern inline unsigned short get_es() { unsigned short es; asm volatile("movw %%es,%w0" : "=r" (es)); return es; } extern inline void set_es(unsigned short es) { asm volatile("movw %w0,%%es" : : "r" (es)); } extern inline unsigned short get_fs() { unsigned short fs; asm volatile("movw %%fs,%w0" : "=r" (fs)); return fs; } extern inline void set_fs(unsigned short fs) { asm volatile("movw %w0,%%fs" : : "r" (fs)); } extern inline unsigned short get_gs() { unsigned short gs; asm volatile("movw %%gs,%w0" : "=r" (gs)); return gs; } extern inline void set_gs(unsigned short gs) { asm volatile("movw %w0,%%gs" : : "r" (gs)); } extern inline unsigned short get_ss() { unsigned short ss; asm volatile("movw %%ss,%w0" : "=r" (ss)); return ss; } extern inline void set_ss(unsigned short ss) { asm volatile("movw %w0,%%ss" : : "r" (ss)); } # 118 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/paging.h" 2 typedef unsigned int pt_entry_t; typedef unsigned int pd_entry_t; extern inline void paging_enable(vm_offset_t pdir) { /* OPENC++ ({ register unsigned int _temp__ = ( pdir ); asm volatile("mov %0, %%cr3" : : "r" (_temp__)); }) ; asm volatile("movl %0,%%cr0 \n\t" "jmp 1f \n\t" "1: \n\t" : : "r" (({ register unsigned int _temp__; asm volatile("mov %%cr0, %0" : "=r" (_temp__)); _temp__; }) | 0x80000000 )); */} # 14 "kmem.h" 2 # 1 "kern_types.h" 1 template< typename _Ty > struct P_ptr { public: typedef _Ty *Raw_type; typedef vm_offset_t Unsigned_type; P_ptr< _Ty > &operator ++ () { ++__ptr; return *this; } P_ptr< _Ty > &operator -- () { --__ptr; return *this; } P_ptr< _Ty > operator ++ (int) { return P_ptr(__ptr++); } P_ptr< _Ty > operator -- (int) { return P_ptr(__ptr--); } P_ptr< _Ty > operator + ( smword_t pd ) const { return P_ptr(__ptr + pd); } P_ptr< _Ty > operator - ( smword_t pd ) const { return P_ptr(__ptr - pd); } P_ptr< _Ty > &operator += ( smword_t pd ) { __ptr += pd; return *this; } P_ptr< _Ty > &operator -= ( smword_t pd ) { __ptr -= pd; return *this; } P_ptr< _Ty > operator & ( mword_t o ) { return (_Ty*)((mword_t)__ptr & o); } bool operator == ( P_ptr const &o ) const { return (void*)__ptr == (void*)o.__ptr; } bool operator != ( P_ptr const &o ) const { return (void*)__ptr != (void*)o.__ptr; } bool is_null() const { return __ptr == (void*)(-1); } bool is_invalid() const { return __ptr == (void*)(-1); } _Ty* get_raw() const { return __ptr; } Unsigned_type get_unsigned() const { return (Unsigned_type)__ptr; } P_ptr to_void() const { return P_ptr((void*)__ptr); } P_ptr< _Ty > operator = (_Ty *o) { return P_ptr(__ptr= o); } P_ptr< _Ty > operator = (P_ptr<_Ty> const &o) { return P_ptr(__ptr= o.__ptr); } template< typename _To > static P_ptr cast( P_ptr< _To > const &o) { return P_ptr<_Ty>(static_cast<_Ty*>(o.get_raw())); } explicit P_ptr( mword_t addr ) : __ptr((_Ty*)addr) {} P_ptr( _Ty *p = (_Ty*)(-1) ) : __ptr(p) {} template< typename _To > P_ptr( P_ptr<_To> const &o ) : __ptr(o.get_raw()) {} private: _Ty *__ptr; }; # 16 "kmem.h" 2 # 1 "../kern/config_gdt.h" 1 # 20 "kmem.h" 2 # 1 "../kern/ia32/linker_syms.h" 1 extern "C" { extern char _start, _etext, _sstack, _stack, _edata, _end; extern char _physmem_1; extern char _tcbs_1; extern char _iobitmap_1; extern char _unused1_1, _unused2_1, _unused3_1, _unused4_io_1; extern char _ipc_window0_1, _ipc_window1_1; extern char _service; } # 30 "kmem.h" 2 struct x86_gate; struct x86_tss; struct x86_desc; void *operator new(size_t); void operator delete(void *block); class kmem { public: static l4_kernel_info_t *info(); private: friend class Vmem_alloc; public: static const vm_offset_t mem_phys = reinterpret_cast(&_physmem_1); static const vm_offset_t mem_tcbs = reinterpret_cast(&_tcbs_1); static const vm_offset_t mem_user_max = 0xc0000000; static const vm_offset_t io_bitmap = reinterpret_cast(&_iobitmap_1); static const vm_offset_t service_page = reinterpret_cast(&_service); static const vm_offset_t local_apic_page = service_page; static const vm_offset_t jdb_adapter_page = local_apic_page + 0x1000; static const vm_offset_t tbuf_status_page = jdb_adapter_page + 0x1000; static const vm_offset_t tbuf_buffer_area = service_page + 0x200000; static const vm_offset_t ipc_window0 = reinterpret_cast(&_ipc_window0_1); static const vm_offset_t ipc_window1 = reinterpret_cast(&_ipc_window1_1); static pt_entry_t *jdb_adapter_pt; enum { gdt_tss = (0x08) , gdt_code_kernel = (0x10) , gdt_data_kernel = (0x18) , gdt_code_user = (0x20) , gdt_data_user = (0x28) , gdt_max = (0x30) }; /*ANNOTATOR template< typename _Ty > static _Ty *phys_to_virt( P_ptr<_Ty> ); */ protected: static pd_entry_t *kdir; static pd_entry_t cpu_global; private: friend class kdb; friend class jdb; friend class profile; kmem(); kmem(const kmem&); static vm_offset_t mem_max, _himem; static const pd_entry_t flag_global = 0x200; static x86_gate *kidt; static x86_tss volatile *tss asm ("KMEM_TSS"); static x86_desc *gdt; static l4_kernel_info_t *kinfo; static byte_t * io_bitmap_delimiter; public: static vm_offset_t virt_to_phys(const void *addr); static void * linear_virt_to_phys(const void *addr); static void *phys_to_virt(vm_offset_t addr); static void dir_init(pd_entry_t *d); static void tlb_flush(vm_offset_t addr); static void tlb_flush(); static vm_offset_t ipc_window(unsigned win); static const pd_entry_t *dir(); static pd_entry_t pde_global(); static x86_gate *idt(); static vm_offset_t himem(); static vm_offset_t volatile *kernel_esp(); static vm_offset_t io_bitmap_delimiter_page(void); static void init(); }; # 1 "/home/sr21/src/l4/kernel/fiasco/src/lib/kern/include/flux/x86/tss.h" 1 struct x86_tss { int back_link; int esp0; int ss0; int esp1; int ss1; int esp2; int ss2; int cr3; int eip; int eflags; int eax; int ecx; int edx; int ebx; int esp; int ebp; int esi; int edi; int es; int cs; int ss; int ds; int fs; int gs; int ldt; unsigned short trace_trap; unsigned short io_bit_map_offset; }; # 208 "kmem.h" 2 inline void *kmem::phys_to_virt(vm_offset_t addr) { return reinterpret_cast(addr + mem_phys); } inline void kmem::tlb_flush(vm_offset_t addr) { /*OPENC++ asm volatile ("invlpg %0" : : "m" (*(char*)addr) : "memory");*/ } inline void kmem::tlb_flush() { /*OPENC++ ({ register unsigned int _temp__ = ( ({ register unsigned int _temp__; asm("mov %%cr3, %0" : "=r" (_temp__)); _temp__; }) ); asm volatile("mov %0, %%cr3" : : "r" (_temp__)); }) ;*/ } inline vm_offset_t kmem::ipc_window(unsigned win) { if (win == 0) return ipc_window0; return ipc_window1; } inline const pd_entry_t *kmem::dir() { return kdir; } inline pd_entry_t kmem::pde_global() { return cpu_global; } inline x86_gate *kmem::idt() { return kidt; } inline vm_offset_t kmem::himem() { return _himem; } inline vm_offset_t volatile *kmem::kernel_esp() { return reinterpret_cast(& tss->esp0); } inline vm_offset_t kmem::io_bitmap_delimiter_page(void) { return reinterpret_cast(io_bitmap_delimiter); } /*ANNOTATOR template< typename _Ty > inline _Ty *kmem::phys_to_virt( P_ptr<_Ty> addr) { return reinterpret_cast<_Ty *>(addr.get_unsigned() + mem_phys); }*/ inline l4_kernel_info_t *kmem::info() { return kinfo; } # 16 "apic_i.h" 2 # 1 "../lib/minilibc/include/panic.h" 1 extern "C" { void panic (const char *format, ...) __attribute__ ((__noreturn__)); } # 17 "apic_i.h" 2 # 1 "../kern/ia32/regdefs.h" 1 # 19 "apic_i.h" 2 # 1 "thread_regs.h" 1 struct thread_user_regs_t { unsigned ecx; unsigned edx; unsigned esi; unsigned edi; unsigned ebx; unsigned ebp; unsigned eax; public: l4_threadid_t * thread_esi_edi(); l4_threadid_t * thread_ebx_ebp(); l4_low_high_t * hilo_ecx_edx(); }; struct thread_ret_regs_t { unsigned eip; unsigned short cs, __csu; unsigned eflags; unsigned esp; unsigned short ss, __ssu; }; struct thread_regs_t : public thread_user_regs_t, public thread_ret_regs_t { }; inline l4_threadid_t * thread_user_regs_t::thread_esi_edi() { return reinterpret_cast(&esi); } inline l4_threadid_t * thread_user_regs_t::thread_ebx_ebp() { return reinterpret_cast(&ebx); } inline l4_low_high_t * thread_user_regs_t::hilo_ecx_edx() { return reinterpret_cast(&ecx); } # 20 "apic_i.h" 2 inline unsigned apic::timer_reg_read() { return reg_read(0x390 ); } inline void apic::timer_reg_write(unsigned val) { reg_read(0x380 ); reg_write(0x380 , val/timer_divisor); } inline int apic::test_cpu() { if ( !(Cpu::features() & 0x00000020 ) || !(Cpu::features() & 0x00000010 )) return 0; if (!memcmp(Cpu::vendor(), "GenuineIntel", 12)) { if (Cpu::family() == 15) { type = APIC_P4; return 1; } else if (Cpu::family() >= 6) { type = APIC_P6; return 1; } } if (!memcmp(Cpu::vendor(), "AuthenticAMD", 12) && Cpu::family() >= 6) { type = APIC_K7; return 1; } return 0; } inline int apic::test_present() { return Cpu::features() & 0x00000200 ; } # 4 "apic.cc" 2 # 89 "kern/apic.cpp" # 91 "kern/apic.cpp" unsigned apic_spurious_interrupt_bug_cnt; # 93 "kern/apic.cpp" unsigned apic_spurious_interrupt_cnt; # 94 "kern/apic.cpp" unsigned apic_error_cnt; # 95 "kern/apic.cpp" unsigned apic_io_base; # 96 "kern/apic.cpp" bool apic::ignore_invalid_reg_access = false; # 98 "kern/apic.cpp" bool apic::present = 0; # 99 "kern/apic.cpp" const addr_t apic::io_base = kmem::local_apic_page; # 100 "kern/apic.cpp" unsigned apic::timer_divisor = 1; # 101 "kern/apic.cpp" apic::apic_type_t apic::type = APIC_NONE; # 102 "kern/apic.cpp" unsigned apic::frequency_khz; # 103 "kern/apic.cpp" unsigned apic::max_lvt; # 219 "kern/apic.cpp" void apic::timer_set_divisor(unsigned newdiv) { int i; int div = -1; int divval = newdiv; unsigned tmp_value; static int divisor_tab[8] = { 0xB , 0x0 , 0x1 , 0x2 , 0x3 , 0x8 , 0x9 , 0xA }; for (i=0; i<8; i++) { if (divval & 1) { if (divval & ~1) { printf("bad APIC divisor %d\n", newdiv); return; } div = divisor_tab[i]; break; } divval >>= 1; } if (div != -1) { timer_divisor = newdiv; tmp_value = reg_read(0x3E0 ); tmp_value &= ~0x1F; tmp_value |= div; reg_write(0x3E0 , tmp_value); } } # 259 "kern/apic.cpp" int apic::get_maxlvt() { unsigned ver_reg = reg_read(0x30 ); /* OPENC++: added pair of parens */ return ((( ver_reg ))&0xF0) ? ((( ver_reg )>>16)&0xFF) : 2; } # 270 "kern/apic.cpp" int apic::check_working() { unsigned long long tsc, tsc_until; timer_disable_irq(); timer_set_divisor(1); timer_reg_write(0x10000000); asm volatile ("rdtsc" : "=A" (tsc_until)); tsc_until += 0x100; do { if (timer_reg_read() != 0x10000000) return 1; asm volatile ("rdtsc" : "=A" (tsc)); } while (tsc < tsc_until); return 0; } # 295 "kern/apic.cpp" void apic::soft_enable() { unsigned tmp_val; tmp_val = reg_read(0xF0 ); tmp_val |= (1<<8); tmp_val &= ~(1<<9); tmp_val &= ~0xff; tmp_val |= 0x3f; reg_write(0xF0 , tmp_val); } # 310 "kern/apic.cpp" void apic::err_enable() { if ((( reg_read(0x30 ) )&0xF0) ) { unsigned tmp_val, before, after; if (max_lvt > 3) reg_write(0x280 , 0); before = reg_read(0x280 ); tmp_val = reg_read(0x370 ); tmp_val &= 0xfffeff00; tmp_val |= 0x0000003e; reg_write(0x370 , tmp_val); if (max_lvt > 3) reg_write(0x280 , 0); after = reg_read(0x280 ); printf("APIC ESR value before/after enabling: %08x/%08x\n", before, after); } } # 336 "kern/apic.cpp" void apic::activate_by_io() { unsigned tmp_val; Proc::Status flags = Proc::cli_save(); char old_master /*OPENC++= 0({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); _tmp__; }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( 0xff )) , "Nd" ((unsigned short)( (0x20 + 0x01 ) )));})*/; char old_slaves /*OPENC++= ({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); _tmp__; }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( 0xff )) , "Nd" ((unsigned short)( (0xa0 + 0x01 )))); })*/ ; soft_enable(); tmp_val = reg_read(0x350 ); tmp_val &= 0xfffe5800; tmp_val |= 0x00000700; reg_write(0x350 , tmp_val); tmp_val = reg_read(0x360 ); tmp_val &= 0xfffe5800; tmp_val |= 0x00000400; reg_write(0x360 , tmp_val); /*OPENC++ ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( old_slaves )) , "Nd" ((unsigned short)( (0xa0 + 0x01 ) ))); }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( old_master )) , "Nd" ((unsigned short)( (0x20 + 0x01 ) ))); }) ;*/ Proc::sti_restore(flags); } # 374 "kern/apic.cpp" void apic::activate_by_msr() { unsigned long low; unsigned long high; asm volatile(".byte 0xf; .byte 0x32\n" :"=a" (low), "=d" (high) :"c" (0x1b ) ); low |= 0x800; low &= 0x00000fff; low |= (io_base & 0xfffff000); asm volatile(".byte 0xf; .byte 0x30\n" : :"c" (0x1b ), "a" (low), "d" (high) ); Cpu::identify(); } # 433 "kern/apic.cpp" int apic::check_still_getting_irqs() { unsigned long long tsc, tsc_until; unsigned long long clock_start = kmem::info()->clock; asm volatile ("rdtsc" : "=A" (tsc_until)); tsc_until += 0x01000000; do { if (kmem::info()->clock != clock_start) return 1; asm volatile ("rdtsc" : "=A" (tsc)); } while (tsc < tsc_until); return 0; } # 457 "kern/apic.cpp" int apic::try_to_activate() { activate_by_msr(); if ( test_present() && check_working()) { printf("APIC disabled, re-enabling... "); activate_by_io(); if (check_still_getting_irqs()) { printf("sucessful!\n"); return 1; } panic("unsuccessful!\n"); } return 0; } # 494 "kern/apic.cpp" int apic::have_pcint() { return (present && (max_lvt >= 4)); } # 501 "kern/apic.cpp" void apic::set_perf_nmi() { if (have_pcint()) reg_write(0x340 , 0x400); else panic("Trying to set LVTPC"); } # 511 "kern/apic.cpp" void apic::calibrate_timer() { unsigned calibrate_latch = (1193180 / 20); unsigned calibrate_time = 50; timer_disable_irq(); timer_set_divisor(1); timer_reg_write(1000000000); /*OPENC++ ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( (({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( 0x61 ))); _tmp__; }) & ~0x02) | 0x01 )) , "Nd" ((unsigned short)( 0x61 ))); }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( 0xb0 )) , "Nd" ((unsigned short)( 0x43 ))); }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( calibrate_latch & 0xff )) , "Nd" ((unsigned short)( 0x42 ))); }) ; ({ asm volatile("outb %b0, %w1" : : "a" ((unsigned char)( calibrate_latch >> 8 )) , "Nd" ((unsigned short)( 0x42 ))); }) ; */ { unsigned long count; unsigned long tt1, tt2; unsigned long result; tt1 = timer_reg_read(); count = 0; /*OPENC++ do { count++; } while ((({ unsigned char _tmp__; asm volatile("inb %w1, %b0" : "=a" (_tmp__) : "Nd" ((unsigned short)( 0x61 ))); _tmp__; }) & 0x20) == 0);*/ tt2 = timer_reg_read(); result = (tt1-tt2)*timer_divisor; if (count <= 1) goto bad_ctc; if (result <= calibrate_time) goto bad_ctc; __asm__ ("divl %1" :"=a" (result) :"r" (calibrate_time), "0" (result), "d" (0)); frequency_khz = result; return; } bad_ctc: frequency_khz = 0; } # 567 "kern/apic.cpp" extern "C" void apic_error_interrupt(struct thread_ret_regs_t *ret_regs) { unsigned err1, err2; err1 = apic::reg_read(0x280 ); apic::reg_write(0x280 , 0); err2 = apic::reg_read(0x280 ); apic::irq_ack(); cpu_lock.clear(); if (err1 == 0x80 || err2 == 0x80) { if (apic::ignore_invalid_reg_access) return; printf("APIC invalid register access error at %08x\n", ret_regs->eip); return; } apic_error_cnt++; printf("APIC error %08x(%08x)\n", err1, err2); } # 595 "kern/apic.cpp" void apic::init() { if (present = test_cpu()) { if ((present = test_present() && check_working())) { activate_by_msr(); soft_enable(); } else present = try_to_activate(); } if (present) { max_lvt = get_maxlvt(); apic_io_base = kmem::local_apic_page; calibrate_timer(); printf("Found Local APIC version 0x%02x id 0x%02x\n", (( reg_read(0x30 ) )&0xFF) , ((( reg_read(0x20 ) )>>24)&0x0F) ); err_enable(); } else { panic("Local APIC not found"); } }