1564cba31SAxel Dörfler/*
2df213cedSAxel Dörfler * Copyright 2002-2006, Haiku Inc. All rights reserved.
3a36a94daSAxel Dörfler * Distributed under the terms of the MIT License.
4a36a94daSAxel Dörfler *
5a36a94daSAxel Dörfler * Copyright 2002, Travis Geiselbrecht. All rights reserved.
6a36a94daSAxel Dörfler * Distributed under the terms of the NewOS License.
7a36a94daSAxel Dörfler */
852a38012Sejakowatz#ifndef _KERNEL_CPU_H
952a38012Sejakowatz#define _KERNEL_CPU_H
1052a38012Sejakowatz
1152a38012Sejakowatz
12ea2abd11SIngo Weinhold#include <setjmp.h>
13ea2abd11SIngo Weinhold
14d897a478SPawel Dziepak#include <int.h>
1552a38012Sejakowatz#include <smp.h>
1652a38012Sejakowatz#include <timer.h>
17dcdc4f4bSTravis Geiselbrecht#include <arch/cpu.h>
1852a38012Sejakowatz
191b06228fSPawel Dziepak#include <scheduler.h>
201b06228fSPawel Dziepak
2152a38012Sejakowatz
2245bd7bb3SIngo Weinholdstruct kernel_args;
234535495dSIngo Weinhold
244535495dSIngo Weinholdnamespace BKernel {
254535495dSIngo Weinhold	struct Thread;
264535495dSIngo Weinhold}
274535495dSIngo Weinhold
284535495dSIngo Weinholdusing BKernel::Thread;
29b4be7c90SIngo Weinhold
30b4be7c90SIngo Weinhold
318ec89732SPawel Dziepaktypedef enum cpu_topology_level {
328ec89732SPawel Dziepak	CPU_TOPOLOGY_SMT,
338ec89732SPawel Dziepak	CPU_TOPOLOGY_CORE,
348ec89732SPawel Dziepak	CPU_TOPOLOGY_PACKAGE,
358ec89732SPawel Dziepak	//
368ec89732SPawel Dziepak	CPU_TOPOLOGY_LEVELS
378ec89732SPawel Dziepak} cpu_topology_level;
388ec89732SPawel Dziepak
39343c4896SPawel Dziepaktypedef struct cpu_topology_node {
40343c4896SPawel Dziepak	cpu_topology_level	level;
41343c4896SPawel Dziepak
42343c4896SPawel Dziepak	int					id;
43343c4896SPawel Dziepak
44343c4896SPawel Dziepak	cpu_topology_node**	children;
45343c4896SPawel Dziepak	int					children_count;
46343c4896SPawel Dziepak} cpu_topology_node;
47343c4896SPawel Dziepak
488ec89732SPawel Dziepak
49564cba31SAxel Dörfler/* CPU local data structure */
50564cba31SAxel Dörfler
5117fee3eaSMichael Lotztypedef struct cpu_ent {
52b4be7c90SIngo Weinhold	int				cpu_num;
537c0a9357SAxel Dörfler
5417fee3eaSMichael Lotz	// thread.c: used to force a reschedule at quantum expiration time
55829f8363SPawel Dziepak	bool			preempted;
56b4be7c90SIngo Weinhold	timer			quantum_timer;
57d14aab0dSAxel Dörfler
5817fee3eaSMichael Lotz	// keeping track of CPU activity
59b258298cSPawel Dziepak	seqlock			active_time_lock;
60b4be7c90SIngo Weinhold	bigtime_t		active_time;
61955c7edeSPawel Dziepak	bigtime_t		irq_time;
62955c7edeSPawel Dziepak	bigtime_t		interrupt_time;
63b4be7c90SIngo Weinhold	bigtime_t		last_kernel_time;
64b4be7c90SIngo Weinhold	bigtime_t		last_user_time;
65ea2abd11SIngo Weinhold
663514fd77SPawel Dziepak	int32			ici_counter;
673514fd77SPawel Dziepak
68ea2abd11SIngo Weinhold	// used in the kernel debugger
69b4be7c90SIngo Weinhold	addr_t			fault_handler;
70b4be7c90SIngo Weinhold	addr_t			fault_handler_stack_pointer;
71b4be7c90SIngo Weinhold	jmp_buf			fault_jump_buffer;
72b4be7c90SIngo Weinhold
734535495dSIngo Weinhold	Thread*			running_thread;
7424df6592SIngo Weinhold	Thread*			previous_thread;
75b4be7c90SIngo Weinhold	bool			invoke_scheduler;
76b4be7c90SIngo Weinhold	bool			disabled;
7778c90d44SIngo Weinhold
788ec89732SPawel Dziepak	// CPU topology information
798ec89732SPawel Dziepak	int				topology_id[CPU_TOPOLOGY_LEVELS];
8036cc64a9SPawel Dziepak	int				cache_id[CPU_MAX_CACHE_LEVEL];
818ec89732SPawel Dziepak
82d897a478SPawel Dziepak	// IRQs assigned to this CPU
83d897a478SPawel Dziepak	struct list		irqs;
84d897a478SPawel Dziepak	spinlock		irqs_lock;
85d897a478SPawel Dziepak
86dcdc4f4bSTravis Geiselbrecht	// arch-specific stuff
87d897a478SPawel Dziepak	arch_cpu_info 	arch;
880e94a12fSPawel Dziepak} cpu_ent CACHE_LINE_ALIGN;
897c0a9357SAxel Dörfler
9052a38012Sejakowatz
9145bd7bb3SIngo Weinholdextern cpu_ent gCPU[];
92cf863a50SPawel Dziepakextern uint32 gCPUCacheLevelCount;
9352a38012Sejakowatz
94b0d8e689SAxel Dörfler
95564cba31SAxel Dörfler#ifdef __cplusplus
96564cba31SAxel Dörflerextern "C" {
97564cba31SAxel Dörfler#endif
9852a38012Sejakowatz
99badc7b67STravis Geiselbrechtstatus_t cpu_preboot_init_percpu(struct kernel_args *args, int curr_cpu);
100b0d8e689SAxel Dörflerstatus_t cpu_init(struct kernel_args *args);
10145bd7bb3SIngo Weinholdstatus_t cpu_init_percpu(struct kernel_args *ka, int curr_cpu);
102b0d8e689SAxel Dörflerstatus_t cpu_init_post_vm(struct kernel_args *args);
10351a3c450SAxel Dörflerstatus_t cpu_init_post_modules(struct kernel_args *args);
104d14aab0dSAxel Dörflerbigtime_t cpu_get_active_time(int32 cpu);
105b0d8e689SAxel Dörfler
10652a38012Sejakowatzcpu_ent *get_cpu_struct(void);
107df213cedSAxel Dörflerextern inline cpu_ent *get_cpu_struct(void) { return &gCPU[smp_get_current_cpu()]; }
10852a38012Sejakowatz
109343c4896SPawel Dziepakstatus_t cpu_build_topology_tree(void);
1104fcbac58SPawel Dziepakconst cpu_topology_node* get_cpu_topology(void);
111343c4896SPawel Dziepak
1121b06228fSPawel Dziepakvoid cpu_set_scheduler_mode(enum scheduler_mode mode);
1131b06228fSPawel Dziepak
1141b06228fSPawel Dziepakstatus_t increase_cpu_performance(int delta);
11522d82482SPawel Dziepakstatus_t decrease_cpu_performance(int delta);
11622d82482SPawel Dziepak
1177db89e8dSPawel Dziepakvoid cpu_idle(void);
1187db89e8dSPawel Dziepakvoid cpu_wait(int32* variable, int32 test);
1197db89e8dSPawel Dziepak
1207db89e8dSPawel Dziepak
1217db89e8dSPawel Dziepakstatic inline void
1227db89e8dSPawel Dziepakcpu_pause(void)
1237db89e8dSPawel Dziepak{
1247db89e8dSPawel Dziepak	arch_cpu_pause();
1257db89e8dSPawel Dziepak}
1267db89e8dSPawel Dziepak
1277db89e8dSPawel Dziepak
128a36a94daSAxel Dörflervoid _user_clear_caches(void *address, size_t length, uint32 flags);
129df213cedSAxel Dörflerbool _user_cpu_enabled(int32 cpu);
130df213cedSAxel Dörflerstatus_t _user_set_cpu_enabled(int32 cpu, bool enabled);
131a36a94daSAxel Dörfler
13252a38012Sejakowatz#ifdef __cplusplus
13352a38012Sejakowatz}
13452a38012Sejakowatz#endif
13552a38012Sejakowatz
136564cba31SAxel Dörfler#endif	/* _KERNEL_CPU_H */
137