Handle rdtscp
[akaros.git] / kern / arch / i686 / arch.h
index f9e812c..0dd4383 100644 (file)
@@ -1,18 +1,22 @@
 #ifndef ROS_INC_ARCH_H
 #define ROS_INC_ARCH_H
 
+#include <ros/arch/arch.h>
 #include <ros/common.h>
 #include <arch/x86.h>
 #include <arch/trap.h>
 #include <arch/apic.h>
 
 /* Arch Constants */
-#define MAX_NUM_CPUS                           255
 #define HW_CACHE_ALIGN                          64
+/* Top of the kernel virtual mapping area (KERNBASE) */
+/* For sanity reasons, I don't plan to map the top page */
+#define KERN_VMAP_TOP                          0xfffff000
 
 static __inline void breakpoint(void) __attribute__((always_inline));
 static __inline void invlpg(void *SNT addr) __attribute__((always_inline));
 static __inline void tlbflush(void) __attribute__((always_inline));
+static __inline void icache_flush_page(void* va, void* kva) __attribute__((always_inline));
 static __inline uint64_t read_tsc(void) __attribute__((always_inline));
 static __inline uint64_t read_tsc_serialized(void) __attribute__((always_inline));
 static __inline void enable_irq(void) __attribute__((always_inline));
@@ -23,16 +27,18 @@ static __inline void cpu_relax(void) __attribute__((always_inline));
 static __inline void cpu_halt(void) __attribute__((always_inline));
 static __inline void clflush(uintptr_t* addr) __attribute__((always_inline));
 static __inline int irq_is_enabled(void) __attribute__((always_inline));
-static __inline int get_hw_coreid(int coreid);
+static __inline int get_hw_coreid(uint32_t coreid);
 static __inline int hw_core_id(void) __attribute__((always_inline));
 static __inline int get_os_coreid(int hw_coreid);
 static __inline int core_id(void) __attribute__((always_inline));
 static __inline void cache_flush(void) __attribute__((always_inline));
 static __inline void reboot(void) __attribute__((always_inline)) __attribute__((noreturn));
 
+/* in trap.c */
+void send_ipi(uint32_t os_coreid, uint8_t vector);
+/* in cpuinfo.c */
 void print_cpuinfo(void);
 void show_mapping(uintptr_t start, size_t size);
-void backtrace(void);
 
 /* declared in smp.c */
 int hw_coreid_lookup[MAX_NUM_CPUS];
@@ -58,6 +64,12 @@ tlbflush(void)
        __asm __volatile("movl %0,%%cr3" : : "r" (cr3));
 }
 
+static __inline void
+icache_flush_page(void* va, void* kva)
+{
+       // x86 handles self-modifying code (mostly) without SW support
+}
+
 static __inline uint64_t
 read_tsc(void)
 {
@@ -66,11 +78,20 @@ read_tsc(void)
        return tsc;
 }
 
+/* non-core-id reporting style (it is in ecx) */
+static __inline uint64_t
+read_tscp(void)
+{
+       uint64_t tsc;
+       __asm __volatile("rdtscp" : "=A" (tsc) : : "ecx");
+       return tsc;
+}
+
 static __inline uint64_t 
 read_tsc_serialized(void)
 {
     uint64_t tsc;
-       cpuid(0, 0, 0, 0, 0);
+       cpuid(0x0, 0x0, 0, 0, 0, 0);
        tsc = read_tsc();
        return tsc;
 }
@@ -122,10 +143,12 @@ cpu_relax(void)
        __cpu_relax();
 }
 
+/* This doesn't atomically enable interrupts and then halt, like we want, so
+ * x86 needs to use a custom helper in the irq handler in trap.c. */
 static __inline void
 cpu_halt(void)
 {
-       asm volatile("hlt" : : : "memory");
+       asm volatile("sti; hlt" : : : "memory");
 }
 
 static __inline void
@@ -142,7 +165,7 @@ irq_is_enabled(void)
 
 /* os_coreid -> hw_coreid */
 static __inline int
-get_hw_coreid(int coreid)
+get_hw_coreid(uint32_t coreid)
 {
        return hw_coreid_lookup[coreid];
 }