2003-05-03 20:03:26 +04:00
|
|
|
/*
|
2006-02-01 19:09:05 +03:00
|
|
|
* Copyright 2002-2006, Haiku Inc. All rights reserved.
|
2005-03-17 20:06:56 +03:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Copyright 2002, Travis Geiselbrecht. All rights reserved.
|
|
|
|
* Distributed under the terms of the NewOS License.
|
|
|
|
*/
|
2002-07-09 16:24:59 +04:00
|
|
|
#ifndef _KERNEL_CPU_H
|
|
|
|
#define _KERNEL_CPU_H
|
|
|
|
|
|
|
|
|
2009-08-03 16:39:56 +04:00
|
|
|
#include <setjmp.h>
|
|
|
|
|
2013-11-18 07:55:25 +04:00
|
|
|
#include <int.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <smp.h>
|
|
|
|
#include <timer.h>
|
2007-02-05 04:46:28 +03:00
|
|
|
#include <arch/cpu.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2013-12-18 02:26:37 +04:00
|
|
|
#include <scheduler.h>
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2010-06-26 02:16:10 +04:00
|
|
|
struct kernel_args;
|
2011-01-11 00:54:38 +03:00
|
|
|
|
|
|
|
namespace BKernel {
|
|
|
|
struct Thread;
|
|
|
|
}
|
|
|
|
|
|
|
|
using BKernel::Thread;
|
2009-12-11 22:06:57 +03:00
|
|
|
|
|
|
|
|
2013-10-02 03:19:17 +04:00
|
|
|
typedef enum cpu_topology_level {
|
|
|
|
CPU_TOPOLOGY_SMT,
|
|
|
|
CPU_TOPOLOGY_CORE,
|
|
|
|
CPU_TOPOLOGY_PACKAGE,
|
|
|
|
//
|
|
|
|
CPU_TOPOLOGY_LEVELS
|
|
|
|
} cpu_topology_level;
|
|
|
|
|
2013-10-21 03:33:35 +04:00
|
|
|
typedef struct cpu_topology_node {
|
|
|
|
cpu_topology_level level;
|
|
|
|
|
|
|
|
int id;
|
|
|
|
|
|
|
|
cpu_topology_node** children;
|
|
|
|
int children_count;
|
|
|
|
} cpu_topology_node;
|
|
|
|
|
2013-10-02 03:19:17 +04:00
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
/* CPU local data structure */
|
|
|
|
|
2006-04-30 02:38:19 +04:00
|
|
|
typedef struct cpu_ent {
|
2009-12-11 22:06:57 +03:00
|
|
|
int cpu_num;
|
2005-12-12 20:04:36 +03:00
|
|
|
|
2006-04-30 02:38:19 +04:00
|
|
|
// thread.c: used to force a reschedule at quantum expiration time
|
2013-11-12 07:42:12 +04:00
|
|
|
bool preempted;
|
2009-12-11 22:06:57 +03:00
|
|
|
timer quantum_timer;
|
2006-02-01 23:03:55 +03:00
|
|
|
|
2006-04-30 02:38:19 +04:00
|
|
|
// keeping track of CPU activity
|
2013-12-20 04:31:32 +04:00
|
|
|
seqlock active_time_lock;
|
2009-12-11 22:06:57 +03:00
|
|
|
bigtime_t active_time;
|
2013-11-18 04:50:37 +04:00
|
|
|
bigtime_t irq_time;
|
|
|
|
bigtime_t interrupt_time;
|
2009-12-11 22:06:57 +03:00
|
|
|
bigtime_t last_kernel_time;
|
|
|
|
bigtime_t last_user_time;
|
2009-08-03 16:39:56 +04:00
|
|
|
|
2013-11-29 06:27:00 +04:00
|
|
|
int32 ici_counter;
|
|
|
|
|
2009-08-03 16:39:56 +04:00
|
|
|
// used in the kernel debugger
|
2009-12-11 22:06:57 +03:00
|
|
|
addr_t fault_handler;
|
|
|
|
addr_t fault_handler_stack_pointer;
|
|
|
|
jmp_buf fault_jump_buffer;
|
|
|
|
|
2011-01-11 00:54:38 +03:00
|
|
|
Thread* running_thread;
|
2011-06-12 04:00:23 +04:00
|
|
|
Thread* previous_thread;
|
2009-12-11 22:06:57 +03:00
|
|
|
bool invoke_scheduler;
|
|
|
|
bool disabled;
|
2008-10-17 20:53:31 +04:00
|
|
|
|
2013-10-02 03:19:17 +04:00
|
|
|
// CPU topology information
|
|
|
|
int topology_id[CPU_TOPOLOGY_LEVELS];
|
2013-10-03 01:48:03 +04:00
|
|
|
int cache_id[CPU_MAX_CACHE_LEVEL];
|
2013-10-02 03:19:17 +04:00
|
|
|
|
2013-11-18 07:55:25 +04:00
|
|
|
// IRQs assigned to this CPU
|
|
|
|
struct list irqs;
|
|
|
|
spinlock irqs_lock;
|
|
|
|
|
2007-02-05 04:46:28 +03:00
|
|
|
// arch-specific stuff
|
2013-11-18 07:55:25 +04:00
|
|
|
arch_cpu_info arch;
|
2013-11-25 03:35:15 +04:00
|
|
|
} cpu_ent CACHE_LINE_ALIGN;
|
2005-12-12 20:04:36 +03:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2010-06-26 02:16:10 +04:00
|
|
|
extern cpu_ent gCPU[];
|
2013-10-16 20:39:25 +04:00
|
|
|
extern uint32 gCPUCacheLevelCount;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2004-10-21 05:41:29 +04:00
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2007-02-19 03:11:24 +03:00
|
|
|
status_t cpu_preboot_init_percpu(struct kernel_args *args, int curr_cpu);
|
2004-10-21 05:41:29 +04:00
|
|
|
status_t cpu_init(struct kernel_args *args);
|
2010-06-26 02:16:10 +04:00
|
|
|
status_t cpu_init_percpu(struct kernel_args *ka, int curr_cpu);
|
2004-10-21 05:41:29 +04:00
|
|
|
status_t cpu_init_post_vm(struct kernel_args *args);
|
The short story: we now have MTRR support on Intel and AMD CPUs (the latter
has not yet been tested, though - I'll do this after this commit):
* Removed the arch_memory_type stuff from vm_area; since there are only 8 memory
ranges on x86, it's simply overkill. The MTRR code now remembers the area ID
and finds the MTRR that way (it could also iterate over the existing MTRRs).
* Introduced some post_modules() init functions.
* If the other x86 CPUs out there don't differ a lot, MTRR functionality might
be put back into the kernel.
* x86_write_msr() was broken, it wrote the 64 bit number with the 32 bit words
switched - it took me some time (and lots of #GPs) to figure that one out.
* Removed the macro read_ebp() and introduced a function x86_read_ebp()
(it's not really a time critical call).
* Followed the Intel docs on how to change MTRRs (symmetrically on all CPUs
with caches turned off).
* Asking for memory types will automatically change the requested length to
a power of two - note that BeOS seems to behave in the same, although that's
not really very clean.
* fixed MTRRs are ignored for now - we should make sure at least, though,
that they are identical on all CPUs (or turn them off, even though I'd
prefer the BIOS stuff to be uncacheable, which we don't enforce yet, though).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15528 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-12-13 19:34:29 +03:00
|
|
|
status_t cpu_init_post_modules(struct kernel_args *args);
|
2006-02-01 23:03:55 +03:00
|
|
|
bigtime_t cpu_get_active_time(int32 cpu);
|
2020-09-10 23:24:43 +03:00
|
|
|
uint64 cpu_frequency(int32 cpu);
|
2004-10-21 05:41:29 +04:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
cpu_ent *get_cpu_struct(void);
|
2006-02-01 19:09:05 +03:00
|
|
|
extern inline cpu_ent *get_cpu_struct(void) { return &gCPU[smp_get_current_cpu()]; }
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2013-10-21 03:33:35 +04:00
|
|
|
status_t cpu_build_topology_tree(void);
|
2013-12-18 01:08:18 +04:00
|
|
|
const cpu_topology_node* get_cpu_topology(void);
|
2013-10-21 03:33:35 +04:00
|
|
|
|
2013-12-18 02:26:37 +04:00
|
|
|
void cpu_set_scheduler_mode(enum scheduler_mode mode);
|
|
|
|
|
|
|
|
status_t increase_cpu_performance(int delta);
|
2013-10-30 03:48:07 +04:00
|
|
|
status_t decrease_cpu_performance(int delta);
|
|
|
|
|
2013-11-26 02:50:27 +04:00
|
|
|
void cpu_idle(void);
|
|
|
|
void cpu_wait(int32* variable, int32 test);
|
|
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
cpu_pause(void)
|
|
|
|
{
|
|
|
|
arch_cpu_pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-17 20:06:56 +03:00
|
|
|
void _user_clear_caches(void *address, size_t length, uint32 flags);
|
2006-02-01 19:09:05 +03:00
|
|
|
bool _user_cpu_enabled(int32 cpu);
|
|
|
|
status_t _user_set_cpu_enabled(int32 cpu, bool enabled);
|
2005-03-17 20:06:56 +03:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-05-03 20:03:26 +04:00
|
|
|
#endif /* _KERNEL_CPU_H */
|