1/* 2 * Copyright 2002-2008, Axel D��rfler, axeld@pinc-software.de. 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 9/* This file contains the cpu functions (init, etc). */ 10 11 12#include <cpu.h> 13#include <arch/cpu.h> 14 15#include <string.h> 16 17#include <boot/kernel_args.h> 18#include <thread_types.h> 19#include <util/AutoLock.h> 20 21 22/* global per-cpu structure */ 23cpu_ent gCPU[MAX_BOOT_CPUS]; 24 25static spinlock sSetCpuLock; 26 27 28status_t 29cpu_init(kernel_args *args) 30{ 31 return arch_cpu_init(args); 32} 33 34 35status_t 36cpu_init_percpu(kernel_args *args, int curr_cpu) 37{ 38 return arch_cpu_init_percpu(args, curr_cpu); 39} 40 41 42status_t 43cpu_init_post_vm(kernel_args *args) 44{ 45 return arch_cpu_init_post_vm(args); 46} 47 48 49status_t 50cpu_init_post_modules(kernel_args *args) 51{ 52 return arch_cpu_init_post_modules(args); 53} 54 55 56status_t 57cpu_preboot_init_percpu(kernel_args *args, int curr_cpu) 58{ 59 // set the cpu number in the local cpu structure so that 60 // we can use it for get_current_cpu 61 memset(&gCPU[curr_cpu], 0, sizeof(gCPU[curr_cpu])); 62 gCPU[curr_cpu].cpu_num = curr_cpu; 63 64 return arch_cpu_preboot_init_percpu(args, curr_cpu); 65} 66 67 68bigtime_t 69cpu_get_active_time(int32 cpu) 70{ 71 if (cpu < 0 || cpu > smp_get_num_cpus()) 72 return 0; 73 74 // We need to grab the scheduler lock here, because the thread activity 75 // time is not maintained atomically (because there is no need to). 76 77 InterruptsSpinLocker schedulerLocker(gSchedulerLock); 78 79 return gCPU[cpu].active_time; 80} 81 82 83void 84clear_caches(void *address, size_t length, uint32 flags) 85{ 86 // ToDo: implement me! 87} 88 89 90// #pragma mark - 91 92 93void 94_user_clear_caches(void *address, size_t length, uint32 flags) 95{ 96 clear_caches(address, length, flags); 97} 98 99 100bool 101_user_cpu_enabled(int32 cpu) 102{ 103 if (cpu < 0 || cpu >= smp_get_num_cpus()) 104 return false; 105 106 return !gCPU[cpu].disabled; 107} 108 109 110status_t 111_user_set_cpu_enabled(int32 cpu, bool enabled) 112{ 113 status_t status = B_OK; 114 cpu_status state; 115 int32 i, count; 116 117 if (cpu < 0 || cpu >= smp_get_num_cpus()) 118 return B_BAD_VALUE; 119 120 // We need to lock here to make sure that no one can disable 121 // the last CPU 122 123 state = disable_interrupts(); 124 acquire_spinlock(&sSetCpuLock); 125 126 if (!enabled) { 127 // check if this is the last CPU to be disabled 128 for (i = 0, count = 0; i < smp_get_num_cpus(); i++) { 129 if (!gCPU[i].disabled) 130 count++; 131 } 132 133 if (count == 1) 134 status = B_NOT_ALLOWED; 135 } 136 137 if (status == B_OK) 138 gCPU[cpu].disabled = !enabled; 139 140 release_spinlock(&sSetCpuLock); 141 restore_interrupts(state); 142 return status; 143} 144 145