1 /* Kernel specific structures and functions 2 ** 3 ** Distributed under the terms of the Haiku License. 4 */ 5 #ifndef _OS_H 6 #define _OS_H 7 8 9 #include <SupportDefs.h> 10 #include <StorageDefs.h> 11 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /*-------------------------------------------------------------*/ 18 /* System constants */ 19 20 #define B_OS_NAME_LENGTH 32 21 #define B_PAGE_SIZE 4096 22 #define B_INFINITE_TIMEOUT (9223372036854775807LL) 23 24 enum { 25 B_TIMEOUT = 8, /* relative timeout */ 26 B_RELATIVE_TIMEOUT = 8, /* fails after a relative timeout with B_WOULD_BLOCK */ 27 B_ABSOLUTE_TIMEOUT = 16, /* fails after an absolute timeout with B_WOULD BLOCK */ 28 }; 29 30 /*-------------------------------------------------------------*/ 31 /* Types */ 32 33 typedef int32 area_id; 34 typedef int32 port_id; 35 typedef int32 sem_id; 36 typedef int32 team_id; 37 typedef int32 thread_id; 38 39 40 /*-------------------------------------------------------------*/ 41 /* Areas */ 42 43 typedef struct area_info { 44 area_id area; 45 char name[B_OS_NAME_LENGTH]; 46 size_t size; 47 uint32 lock; 48 uint32 protection; 49 team_id team; 50 uint32 ram_size; 51 uint32 copy_count; 52 uint32 in_count; 53 uint32 out_count; 54 void *address; 55 } area_info; 56 57 /* area locking */ 58 #define B_NO_LOCK 0 59 #define B_LAZY_LOCK 1 60 #define B_FULL_LOCK 2 61 #define B_CONTIGUOUS 3 62 #define B_LOMEM 4 63 64 /* address spec for create_area(), and clone_area() */ 65 #define B_ANY_ADDRESS 0 66 #define B_EXACT_ADDRESS 1 67 #define B_BASE_ADDRESS 2 68 #define B_CLONE_ADDRESS 3 69 #define B_ANY_KERNEL_ADDRESS 4 70 71 /* area protection */ 72 #define B_READ_AREA 1 73 #define B_WRITE_AREA 2 74 75 extern area_id create_area(const char *name, void **start_addr, uint32 addr_spec, 76 size_t size, uint32 lock, uint32 protection); 77 extern area_id clone_area(const char *name, void **dest_addr, uint32 addr_spec, 78 uint32 protection, area_id source); 79 extern area_id find_area(const char *name); 80 extern area_id area_for(void *address); 81 extern status_t delete_area(area_id id); 82 extern status_t resize_area(area_id id, size_t new_size); 83 extern status_t set_area_protection(area_id id, uint32 new_protection); 84 85 /* system private, use macros instead */ 86 extern status_t _get_area_info(area_id id, area_info *areaInfo, size_t size); 87 extern status_t _get_next_area_info(team_id team, int32 *cookie, area_info *areaInfo, size_t size); 88 89 #define get_area_info(id, ainfo) \ 90 _get_area_info((id), (ainfo),sizeof(*(ainfo))) 91 #define get_next_area_info(team, cookie, ainfo) \ 92 _get_next_area_info((team), (cookie), (ainfo), sizeof(*(ainfo))) 93 94 95 /*-------------------------------------------------------------*/ 96 /* Ports */ 97 98 typedef struct port_info { 99 port_id port; 100 team_id team; 101 char name[B_OS_NAME_LENGTH]; 102 int32 capacity; /* queue depth */ 103 int32 queue_count; /* # msgs waiting to be read */ 104 int32 total_count; /* total # msgs read so far */ 105 } port_info; 106 107 extern port_id create_port(int32 capacity, const char *name); 108 extern port_id find_port(const char *name); 109 extern status_t read_port(port_id port, int32 *code, void *buffer, size_t bufferSize); 110 extern status_t read_port_etc(port_id port, int32 *code, void *buffer, size_t bufferSize, 111 uint32 flags, bigtime_t timeout); 112 extern status_t write_port(port_id port, int32 code, const void *buffer, size_t bufferSize); 113 extern status_t write_port_etc(port_id port, int32 code, const void *buffer, size_t bufferSize, 114 uint32 flags, bigtime_t timeout); 115 extern status_t close_port(port_id port); 116 extern status_t delete_port(port_id port); 117 118 extern ssize_t port_buffer_size(port_id port); 119 extern ssize_t port_buffer_size_etc(port_id port, uint32 flags, bigtime_t timeout); 120 extern ssize_t port_count(port_id port); 121 extern status_t set_port_owner(port_id port, team_id team); 122 123 /* system private, use the macros instead */ 124 extern status_t _get_port_info(port_id port, port_info *portInfo, size_t portInfoSize); 125 extern status_t _get_next_port_info(team_id team, int32 *cookie, port_info *portInfo, 126 size_t portInfoSize); 127 128 #define get_port_info(port, info) \ 129 _get_port_info((port), (info), sizeof(*(info))) 130 #define get_next_port_info(team, cookie, info) \ 131 _get_next_port_info((team), (cookie), (info), sizeof(*(info))) 132 133 134 /*-------------------------------------------------------------*/ 135 /* Semaphores */ 136 137 typedef struct sem_info { 138 sem_id sem; 139 team_id team; 140 char name[B_OS_NAME_LENGTH]; 141 int32 count; 142 thread_id latest_holder; 143 } sem_info; 144 145 /* semaphore flags */ 146 enum { 147 B_CAN_INTERRUPT = 1, /* acquisition of the semaphore can be interrupted (system use only) */ 148 B_CHECK_PERMISSION = 4, /* ownership will be checked (system use only) */ 149 150 /* release_sem_etc() only flags */ 151 B_DO_NOT_RESCHEDULE = 2, /* thread is not rescheduled */ 152 B_RELEASE_ALL = 8, /* all waiting threads will be woken up, count will be zeroed */ 153 B_RELEASE_IF_WAITING_ONLY = 16, /* release count only if there are any threads waiting */ 154 }; 155 156 extern sem_id create_sem(int32 count, const char *name); 157 extern status_t delete_sem(sem_id id); 158 extern status_t acquire_sem(sem_id id); 159 extern status_t acquire_sem_etc(sem_id id, int32 count, uint32 flags, bigtime_t timeout); 160 extern status_t release_sem(sem_id id); 161 extern status_t release_sem_etc(sem_id id, int32 count, uint32 flags); 162 extern status_t get_sem_count(sem_id id, int32 *threadCount); 163 extern status_t set_sem_owner(sem_id id, team_id team); 164 165 /* system private, use the macros instead */ 166 extern status_t _get_sem_info(sem_id id, struct sem_info *info, size_t infoSize); 167 extern status_t _get_next_sem_info(team_id team, int32 *cookie, struct sem_info *info, 168 size_t infoSize); 169 170 #define get_sem_info(sem, info) \ 171 _get_sem_info((sem), (info), sizeof(*(info))) 172 173 #define get_next_sem_info(team, cookie, info) \ 174 _get_next_sem_info((team), (cookie), (info), sizeof(*(info))) 175 176 177 /*-------------------------------------------------------------*/ 178 /* Teams */ 179 180 typedef struct { 181 team_id team; 182 int32 thread_count; 183 int32 image_count; 184 int32 area_count; 185 thread_id debugger_nub_thread; 186 port_id debugger_nub_port; 187 int32 argc; 188 char args[64]; 189 uid_t uid; 190 gid_t gid; 191 } team_info; 192 193 #define B_CURRENT_TEAM 0 194 #define B_SYSTEM_TEAM 2 195 196 extern status_t kill_team(team_id team); 197 /* see also: send_signal() */ 198 199 /* system private, use macros instead */ 200 extern status_t _get_team_info(team_id id, team_info *info, size_t size); 201 extern status_t _get_next_team_info(int32 *cookie, team_info *info, size_t size); 202 203 #define get_team_info(id, info) \ 204 _get_team_info((id), (info), sizeof(*(info))) 205 206 #define get_next_team_info(cookie, info) \ 207 _get_next_team_info((cookie), (info), sizeof(*(info))) 208 209 /* team usage info */ 210 211 typedef struct { 212 bigtime_t user_time; 213 bigtime_t kernel_time; 214 } team_usage_info; 215 216 /* system private, use macros instead */ 217 extern status_t _get_team_usage_info(team_id team, int32 who, team_usage_info *tui, size_t size); 218 219 #define get_team_usage_info(team, who, info) \ 220 _get_team_usage_info((team), (who), (info), sizeof(*(info))) 221 222 /*-------------------------------------------------------------*/ 223 /* Threads */ 224 225 typedef enum { 226 B_THREAD_RUNNING = 1, 227 B_THREAD_READY, 228 B_THREAD_RECEIVING, 229 B_THREAD_ASLEEP, 230 B_THREAD_SUSPENDED, 231 B_THREAD_WAITING 232 } thread_state; 233 234 typedef struct { 235 thread_id thread; 236 team_id team; 237 char name[B_OS_NAME_LENGTH]; 238 thread_state state; 239 int32 priority; 240 sem_id sem; 241 bigtime_t user_time; 242 bigtime_t kernel_time; 243 void *stack_base; 244 void *stack_end; 245 } thread_info; 246 247 #define B_IDLE_PRIORITY 0 248 #define B_LOWEST_ACTIVE_PRIORITY 1 249 #define B_LOW_PRIORITY 5 250 #define B_NORMAL_PRIORITY 10 251 #define B_DISPLAY_PRIORITY 15 252 #define B_URGENT_DISPLAY_PRIORITY 20 253 #define B_REAL_TIME_DISPLAY_PRIORITY 100 254 #define B_URGENT_PRIORITY 110 255 #define B_REAL_TIME_PRIORITY 120 256 257 #define B_FIRST_REAL_TIME_PRIORITY B_REAL_TIME_DISPLAY_PRIORITY 258 #define B_MIN_PRIORITY B_IDLE_PRIORITY 259 #define B_MAX_PRIORITY B_REAL_TIME_PRIORITY 260 261 #define B_SYSTEM_TIMEBASE 0 262 263 typedef int32 (*thread_func) (void *); 264 #define thread_entry thread_func /* thread_entry is for backward compatibility only! Use thread_func */ 265 266 extern thread_id spawn_thread(thread_func, const char *name, int32 priority, void *data); 267 extern status_t kill_thread(thread_id thread); 268 extern status_t resume_thread(thread_id thread); 269 extern status_t suspend_thread(thread_id thread); 270 271 extern status_t rename_thread(thread_id thread, const char *newName); 272 extern status_t set_thread_priority (thread_id thread, int32 newPriority); 273 extern void exit_thread(status_t status); 274 extern status_t wait_for_thread (thread_id thread, status_t *threadReturnValue); 275 extern status_t on_exit_thread(void (*callback)(void *), void *data); 276 277 #if __INTEL__ && !_KERNEL_MODE && !_NO_INLINE_ASM 278 static inline thread_id 279 find_thread(const char *name) { 280 extern thread_id _kfind_thread_(const char *name); 281 if (!name) { 282 thread_id thread; 283 __asm__ __volatile__ ( 284 "movl %%fs:4, %%eax \n\t" 285 : "=a"(thread) ); 286 return thread; 287 } 288 return _kfind_thread_(name); 289 } 290 #else 291 extern thread_id find_thread(const char *name); 292 #endif 293 294 extern status_t send_data(thread_id thread, int32 code, const void *buffer, size_t buffer_size); 295 extern status_t receive_data(thread_id *sender, void *buffer, size_t buffer_size); 296 extern bool has_data(thread_id thread); 297 298 extern status_t snooze(bigtime_t amount); 299 extern status_t snooze_etc(bigtime_t amount, int timeBase, uint32 flags); 300 extern status_t snooze_until(bigtime_t time, int timeBase); 301 302 /* system private, use macros instead */ 303 extern status_t _get_thread_info(thread_id id, thread_info *info, size_t size); 304 extern status_t _get_next_thread_info(team_id team, int32 *cookie, thread_info *info, size_t size); 305 306 #define get_thread_info(id, info) \ 307 _get_thread_info((id), (info), sizeof(*(info))) 308 309 #define get_next_thread_info(team, cookie, info) \ 310 _get_next_thread_info((team), (cookie), (info), sizeof(*(info))) 311 312 313 /*-------------------------------------------------------------*/ 314 /* Time */ 315 316 extern uint32 real_time_clock(void); 317 extern void set_real_time_clock(uint32 secs_since_jan1_1970); 318 extern bigtime_t real_time_clock_usecs(void); 319 extern status_t set_timezone(char *timezone); 320 extern bigtime_t system_time(void); /* time since booting in microseconds */ 321 322 323 /*-------------------------------------------------------------*/ 324 /* Alarm */ 325 326 enum { 327 B_ONE_SHOT_ABSOLUTE_ALARM = 1, 328 B_ONE_SHOT_RELATIVE_ALARM, 329 B_PERIODIC_ALARM /* "when" specifies the period */ 330 }; 331 332 extern bigtime_t set_alarm(bigtime_t when, uint32 flags); 333 334 335 /*-------------------------------------------------------------*/ 336 /* Debugger */ 337 338 extern void debugger(const char *message); 339 340 /* 341 calling this function with a non-zero value will cause your thread 342 to receive signals for any exceptional conditions that occur (i.e. 343 you'll get SIGSEGV for data access exceptions, SIGFPE for floating 344 point errors, SIGILL for illegal instructions, etc). 345 346 to re-enable the default debugger pass a zero. 347 */ 348 extern const int disable_debugger(int state); 349 350 351 /*-------------------------------------------------------------*/ 352 /* System information */ 353 354 #if __INTEL__ 355 # define B_MAX_CPU_COUNT 8 356 #elif __POWERPC__ 357 # define B_MAX_CPU_COUNT 8 358 #endif 359 360 #define OBOS_CPU_TYPES 361 362 typedef enum cpu_types { 363 // ToDo: add latest models 364 365 /* Motorola/IBM */ 366 B_CPU_PPC_601 = 1, 367 B_CPU_PPC_603 = 2, 368 B_CPU_PPC_603e = 3, 369 B_CPU_PPC_604 = 4, 370 B_CPU_PPC_604e = 5, 371 B_CPU_PPC_750 = 6, 372 B_CPU_PPC_686 = 13, 373 374 /* Intel */ 375 B_CPU_INTEL_X86 = 0x1000, 376 B_CPU_INTEL_PENTIUM = 0x1051, 377 B_CPU_INTEL_PENTIUM75, 378 B_CPU_INTEL_PENTIUM_486_OVERDRIVE, 379 B_CPU_INTEL_PENTIUM_MMX, 380 B_CPU_INTEL_PENTIUM_MMX_MODEL_4 = B_CPU_INTEL_PENTIUM_MMX, 381 B_CPU_INTEL_PENTIUM_MMX_MODEL_8 = 0x1058, 382 B_CPU_INTEL_PENTIUM75_486_OVERDRIVE, 383 B_CPU_INTEL_PENTIUM_PRO = 0x1061, 384 B_CPU_INTEL_PENTIUM_II = 0x1063, 385 B_CPU_INTEL_PENTIUM_II_MODEL_3 = 0x1063, 386 B_CPU_INTEL_PENTIUM_II_MODEL_5 = 0x1065, 387 B_CPU_INTEL_CELERON = 0x1066, 388 B_CPU_INTEL_PENTIUM_III = 0x1067, 389 B_CPU_INTEL_PENTIUM_III_MODEL_8 = 0x1068, 390 #ifdef OBOS_CPU_TYPES 391 B_CPU_INTEL_PENTIUM_M = 0x1069, 392 B_CPU_INTEL_PENTIUM_III_MODEL_11 = 0x106b, 393 B_CPU_INTEL_PENTIUM_IV = 0x10f0, 394 B_CPU_INTEL_PENTIUM_IV_MODEL1, 395 B_CPU_INTEL_PENTIUM_IV_MODEL2, 396 B_CPU_INTEL_PENTIUM_IV_XEON = 0x0F27, 397 #endif 398 399 /* AMD */ 400 B_CPU_AMD_X86 = 0x1100, 401 B_CPU_AMD_K5_MODEL0 = 0x1150, 402 B_CPU_AMD_K5_MODEL1, 403 B_CPU_AMD_K5_MODEL2, 404 B_CPU_AMD_K5_MODEL3, 405 B_CPU_AMD_K6_MODEL6 = 0x1156, 406 B_CPU_AMD_K6_MODEL7 = 0x1157, 407 B_CPU_AMD_K6_MODEL8 = 0x1158, 408 B_CPU_AMD_K6_2 = 0x1158, 409 B_CPU_AMD_K6_MODEL9 = 0x1159, 410 B_CPU_AMD_K6_III = 0x1159, 411 #ifdef OBOS_CPU_TYPES 412 B_CPU_AMD_K6_III_MODEL2 = 0x115D, 413 #endif 414 415 B_CPU_AMD_ATHLON_MODEL1 = 0x1161, 416 #ifdef OBOS_CPU_TYPES 417 B_CPU_AMD_ATHLON_MODEL2 = 0x1162, 418 419 B_CPU_AMD_DURON = 0x1163, 420 421 B_CPU_AMD_ATHLON_THUNDERBIRD = 0x1164, 422 B_CPU_AMD_ATHLON_XP = 0x1166, 423 B_CPU_AMD_ATHLON_XP_MODEL2, 424 B_CPU_AMD_ATHLON_XP_MODEL3, 425 B_CPU_AMD_ATHLON_XP_MODEL_BARTON = 0x116A, 426 427 /* According to "Revision guide for AMD Athlon 64 428 and AMD Opteron Processors" (25759.pdf) */ 429 430 B_CPU_AMD_ATHLON_64 = 0x11F4, 431 B_CPU_AMD_OPTERON, 432 B_CPU_AMD_ATHLON_64_MODEL2 = 0x11F7, 433 B_CPU_AMD_ATHLON_64_MODEL3, 434 B_CPU_AMD_ATHLON_64_MODEL4 = 0x11FB, 435 B_CPU_AMD_ATHLON_64_MODEL5, 436 B_CPU_AMD_ATHLON_64_MODEL6 = 0x11FE, 437 B_CPU_AMD_ATHLON_64_MODEL7, 438 #endif 439 440 /* VIA */ 441 B_CPU_CYRIX_X86 = 0x1200, 442 B_CPU_CYRIX_GXm = 0x1254, 443 B_CPU_CYRIX_6x86MX = 0x1260, 444 445 /* others */ 446 B_CPU_IDT_X86 = 0x1300, 447 B_CPU_IDT_WINCHIP_C6 = 0x1354, 448 B_CPU_IDT_WINCHIP_2 = 0x1358, 449 450 B_CPU_RISE_X86 = 0x1400, 451 B_CPU_RISE_mP6 = 0x1450, 452 453 #ifdef OBOS_CPU_TYPES 454 B_CPU_NATIONAL_X86 = 0x1500, 455 B_CPU_NATIONAL_GEODE_GX1 = 0x1554, 456 #endif 457 458 /* For compatibility */ 459 B_CPU_AMD_29K = 14, 460 B_CPU_X86, 461 B_CPU_MC6502, 462 B_CPU_Z80, 463 B_CPU_ALPHA, 464 B_CPU_MIPS, 465 B_CPU_HPPA, 466 B_CPU_M68K, 467 B_CPU_ARM, 468 B_CPU_SH, 469 B_CPU_SPARC, 470 } cpu_type; 471 472 #define B_CPU_X86_VENDOR_MASK 0x1F00 473 474 #ifdef __INTEL__ 475 typedef union { 476 struct { 477 uint32 max_eax; 478 char vendorid[12]; 479 } eax_0; 480 481 struct { 482 uint32 stepping : 4; 483 uint32 model : 4; 484 uint32 family : 4; 485 uint32 type : 2; 486 uint32 reserved_0 : 18; 487 488 uint32 reserved_1; 489 uint32 features; 490 uint32 reserved_2; 491 } eax_1; 492 493 struct { 494 uint8 call_num; 495 uint8 cache_descriptors[15]; 496 } eax_2; 497 498 struct { 499 uint32 reserved[2]; 500 uint32 serial_number_high; 501 uint32 serial_number_low; 502 } eax_3; 503 504 char as_chars[16]; 505 506 struct { 507 uint32 eax; 508 uint32 ebx; 509 uint32 edx; 510 uint32 ecx; 511 } regs; 512 } cpuid_info; 513 514 extern status_t get_cpuid(cpuid_info* info, uint32 eax_register, uint32 cpu_num); 515 #endif 516 517 518 typedef enum platform_types { 519 B_BEBOX_PLATFORM = 0, 520 B_MAC_PLATFORM, 521 B_AT_CLONE_PLATFORM, 522 B_ENIAC_PLATFORM, 523 B_APPLE_II_PLATFORM, 524 B_CRAY_PLATFORM, 525 B_LISA_PLATFORM, 526 B_TI_994A_PLATFORM, 527 B_TIMEX_SINCLAIR_PLATFORM, 528 B_ORAC_1_PLATFORM, 529 B_HAL_PLATFORM, 530 B_BESM_6_PLATFORM, 531 B_MK_61_PLATFORM, 532 B_NINTENDO_64_PLATFORM 533 } platform_type; 534 535 typedef struct { 536 bigtime_t active_time; /* usec of doing useful work since boot */ 537 } cpu_info; 538 539 540 typedef int32 machine_id[2]; /* unique machine ID */ 541 542 typedef struct { 543 machine_id id; /* unique machine ID */ 544 bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */ 545 546 int32 cpu_count; /* number of cpus */ 547 enum cpu_types cpu_type; /* type of cpu */ 548 int32 cpu_revision; /* revision # of cpu */ 549 cpu_info cpu_infos[B_MAX_CPU_COUNT]; /* info about individual cpus */ 550 int64 cpu_clock_speed; /* processor clock speed (Hz) */ 551 int64 bus_clock_speed; /* bus clock speed (Hz) */ 552 enum platform_types platform_type; /* type of machine we're on */ 553 554 int32 max_pages; /* total # physical pages */ 555 int32 used_pages; /* # physical pages in use */ 556 int32 page_faults; /* # of page faults */ 557 int32 max_sems; 558 int32 used_sems; 559 int32 max_ports; 560 int32 used_ports; 561 int32 max_threads; 562 int32 used_threads; 563 int32 max_teams; 564 int32 used_teams; 565 566 char kernel_name[B_FILE_NAME_LENGTH]; /* name of kernel */ 567 char kernel_build_date[B_OS_NAME_LENGTH]; /* date kernel built */ 568 char kernel_build_time[B_OS_NAME_LENGTH]; /* time kernel built */ 569 int64 kernel_version; /* version of this kernel */ 570 571 bigtime_t _busy_wait_time; /* reserved for Be */ 572 int32 pad[4]; /* just in case... */ 573 } system_info; 574 575 /* system private, use macro instead */ 576 extern status_t _get_system_info (system_info *returned_info, size_t size); 577 578 #define get_system_info(info) \ 579 _get_system_info((info), sizeof(*(info))) 580 581 extern int32 is_computer_on(void); 582 extern double is_computer_on_fire(void); 583 584 #ifdef __cplusplus 585 } 586 #endif 587 588 #endif /* _OS_H */ 589