1 /*
2 * Copyright 2002-2006, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Copyright 2002, Travis Geiselbrecht. All rights reserved.
6 * Distributed under the terms of the NewOS License.
7 */
8 #ifndef _KERNEL_CPU_H
9 #define _KERNEL_CPU_H
10
11
12 #include <setjmp.h>
13
14 #include <int.h>
15 #include <smp.h>
16 #include <timer.h>
17 #include <arch/cpu.h>
18
19 #include <scheduler.h>
20
21
22 struct kernel_args;
23
24 namespace BKernel {
25 struct Thread;
26 }
27
28 using BKernel::Thread;
29
30
31 typedef enum cpu_topology_level {
32 CPU_TOPOLOGY_SMT,
33 CPU_TOPOLOGY_CORE,
34 CPU_TOPOLOGY_PACKAGE,
35 //
36 CPU_TOPOLOGY_LEVELS
37 } cpu_topology_level;
38
39 typedef struct cpu_topology_node {
40 cpu_topology_level level;
41
42 int id;
43
44 cpu_topology_node** children;
45 int children_count;
46 } cpu_topology_node;
47
48
49 /* CPU local data structure */
50
51 typedef struct CACHE_LINE_ALIGN cpu_ent {
52 int cpu_num;
53
54 // thread.c: used to force a reschedule at quantum expiration time
55 bool preempted;
56 timer quantum_timer;
57
58 // keeping track of CPU activity
59 seqlock active_time_lock;
60 bigtime_t active_time;
61 bigtime_t irq_time;
62 bigtime_t interrupt_time;
63 bigtime_t last_kernel_time;
64 bigtime_t last_user_time;
65
66 int32 ici_counter;
67
68 // used in the kernel debugger
69 addr_t fault_handler;
70 addr_t fault_handler_stack_pointer;
71 jmp_buf fault_jump_buffer;
72
73 Thread* running_thread;
74 Thread* previous_thread;
75 bool invoke_scheduler;
76 bool disabled;
77
78 // CPU topology information
79 int topology_id[CPU_TOPOLOGY_LEVELS];
80 int cache_id[CPU_MAX_CACHE_LEVEL];
81
82 // IRQs assigned to this CPU
83 struct list irqs;
84 spinlock irqs_lock;
85
86 // arch-specific stuff
87 arch_cpu_info arch;
88 } cpu_ent;
89
90
91 extern cpu_ent gCPU[];
92 extern uint32 gCPUCacheLevelCount;
93 extern CPUSet gCPUEnabled;
94
95
96 #ifdef __cplusplus
97 extern "C" {
98 #endif
99
100 status_t cpu_preboot_init_percpu(struct kernel_args *args, int curr_cpu);
101 status_t cpu_init(struct kernel_args *args);
102 status_t cpu_init_percpu(struct kernel_args *ka, int curr_cpu);
103 status_t cpu_init_post_vm(struct kernel_args *args);
104 status_t cpu_init_post_modules(struct kernel_args *args);
105 bigtime_t cpu_get_active_time(int32 cpu);
106 uint64 cpu_frequency(int32 cpu);
107
108 cpu_ent *get_cpu_struct(void);
get_cpu_struct(void)109 extern inline cpu_ent *get_cpu_struct(void) { return &gCPU[smp_get_current_cpu()]; }
110
111 status_t cpu_build_topology_tree(void);
112 const cpu_topology_node* get_cpu_topology(void);
113
114 void cpu_set_scheduler_mode(enum scheduler_mode mode);
115
116 status_t increase_cpu_performance(int delta);
117 status_t decrease_cpu_performance(int delta);
118
119 void cpu_idle(void);
120 void cpu_wait(int32* variable, int32 test);
121
122
123 static inline void
cpu_pause(void)124 cpu_pause(void)
125 {
126 arch_cpu_pause();
127 }
128
129
130 void _user_clear_caches(void *address, size_t length, uint32 flags);
131 bool _user_cpu_enabled(int32 cpu);
132 status_t _user_set_cpu_enabled(int32 cpu, bool enabled);
133
134 #ifdef __cplusplus
135 }
136 #endif
137
138 #endif /* _KERNEL_CPU_H */
139