Merge branch 'master' into sam460ex
This commit is contained in:
commit
95540b8a19
@ -7,7 +7,7 @@ HAIKU_BOOT_PLATFORM = raspberrypi_arm ;
|
|||||||
# Various hardcoded addresses
|
# Various hardcoded addresses
|
||||||
#
|
#
|
||||||
|
|
||||||
HAIKU_BOARD_LOADER_BASE = 0x32000000 ;
|
HAIKU_BOARD_LOADER_BASE = 0x0 ;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Flash image
|
# Flash image
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
Setting up the Haiku boot partition
|
Setting up the Haiku boot partition
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
partition 1 -- FAT32, bootable flag, type 'c'
|
partition 1 -- FAT32, bootable flag, type 'c'
|
||||||
partition 2 -- BeFS, Haiku filesystem, type 'eb'
|
partition 2 -- BeFS, Haiku filesystem, type 'eb'
|
||||||
@ -7,7 +8,7 @@ The boot partition must contain the following files to boot Haiku:
|
|||||||
* bootcode.bin : 2nd stage bootloader, starts with SDRAM disabled
|
* bootcode.bin : 2nd stage bootloader, starts with SDRAM disabled
|
||||||
* loader.bin : 3rd stage bootloader, starts with SDRAM enabled
|
* loader.bin : 3rd stage bootloader, starts with SDRAM enabled
|
||||||
* start.elf: The GPU binary firmware image, provided by the foundation.
|
* start.elf: The GPU binary firmware image, provided by the foundation.
|
||||||
* kernel.img: Haiku Loader (haiku_loader)
|
* haiku_loader: Haiku Loader
|
||||||
* config.txt: A configuration file read by the GPU.
|
* config.txt: A configuration file read by the GPU.
|
||||||
|
|
||||||
Optional files:
|
Optional files:
|
||||||
@ -20,4 +21,13 @@ Additional GPU firmware images, rename over start.elf to use them:
|
|||||||
- this is the default
|
- this is the default
|
||||||
* arm224_start.elf : 224M ARM, 32M GPU split
|
* arm224_start.elf : 224M ARM, 32M GPU split
|
||||||
- (use this for Linux only with no 3D or video processing.
|
- (use this for Linux only with no 3D or video processing.
|
||||||
Its enough for the 1080p framebuffer, but not much else)
|
Enough for the 1080p framebuffer, but not much else)
|
||||||
|
|
||||||
|
Building
|
||||||
|
-------------------------------------
|
||||||
|
jam -q -sHAIKU_BOOT_BOARD=raspberry_pi -sHAIKU_BOOT_PLATFORM=raspberrypi_arm haiku_loader
|
||||||
|
|
||||||
|
config.txt options
|
||||||
|
-------------------------------------
|
||||||
|
kernel=haiku_loader
|
||||||
|
disable_commandline_tags=1
|
||||||
|
@ -60,10 +60,6 @@ load_symbols true
|
|||||||
#acpi false
|
#acpi false
|
||||||
# ACPI support, enabled by default
|
# ACPI support, enabled by default
|
||||||
|
|
||||||
#acpi_avoid_full_init true
|
|
||||||
# Avoids running _INI and _STA methods and final object initialization,
|
|
||||||
# which may be used to for debugging ACPI issues, false by default
|
|
||||||
|
|
||||||
#disable_ioapic true
|
#disable_ioapic true
|
||||||
# Disables IO-APIC support, enabled by default
|
# Disables IO-APIC support, enabled by default
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2004-2012, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -27,6 +28,58 @@ int32 get_rounded_cpu_speed(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if __INTEL__
|
||||||
|
/*! Tries to parse an Intel CPU ID string to match our usual naming scheme.
|
||||||
|
Note, this function is not thread safe, and must only be called once
|
||||||
|
at a time.
|
||||||
|
*/
|
||||||
|
static const char*
|
||||||
|
parse_intel(const char* name)
|
||||||
|
{
|
||||||
|
static char buffer[49];
|
||||||
|
|
||||||
|
// ignore initial spaces
|
||||||
|
int index = 0;
|
||||||
|
for (; name[index] != '\0'; index++) {
|
||||||
|
if (name[index] != ' ')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore vendor
|
||||||
|
for (; name[index] != '\0'; index++) {
|
||||||
|
if (name[index] == ' ') {
|
||||||
|
index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse model
|
||||||
|
int outIndex = 0;
|
||||||
|
for (; name[index] != '\0'; index++) {
|
||||||
|
if (!strncmp(&name[index], "(R)", 3)) {
|
||||||
|
outIndex += strlcpy(&buffer[outIndex], "®",
|
||||||
|
sizeof(buffer) - outIndex);
|
||||||
|
index += 2;
|
||||||
|
} else if (!strncmp(&name[index], "(TM)", 4)) {
|
||||||
|
outIndex += strlcpy(&buffer[outIndex], "™",
|
||||||
|
sizeof(buffer) - outIndex);
|
||||||
|
index += 3;
|
||||||
|
} else if (!strncmp(&name[index], " CPU", 4)) {
|
||||||
|
// Cut out the CPU string
|
||||||
|
index += 3;
|
||||||
|
} else if (!strncmp(&name[index], " @", 2)) {
|
||||||
|
// Cut off the remainder
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
buffer[outIndex++] = name[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[outIndex] = '\0';
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
get_cpu_vendor_string(enum cpu_types type)
|
get_cpu_vendor_string(enum cpu_types type)
|
||||||
{
|
{
|
||||||
@ -61,7 +114,7 @@ get_cpu_vendor_string(enum cpu_types type)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef __INTEL__
|
#ifdef __INTEL__
|
||||||
/* Parameter 'name' needs to point to an allocated array of 49 characters. */
|
/*! Parameter 'name' needs to point to an allocated array of 49 characters. */
|
||||||
void
|
void
|
||||||
get_cpuid_model_string(char *name)
|
get_cpuid_model_string(char *name)
|
||||||
{
|
{
|
||||||
@ -345,6 +398,11 @@ get_cpu_model_string(system_info *info)
|
|||||||
#endif /* __INTEL__ */
|
#endif /* __INTEL__ */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) {
|
||||||
|
// Fallback to manual parsing of the model string
|
||||||
|
get_cpuid_model_string(cpuidName);
|
||||||
|
return parse_intel(cpuidName);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,18 +88,14 @@ acpi_std_ops(int32 op,...)
|
|||||||
ACPI_STATUS status;
|
ACPI_STATUS status;
|
||||||
ACPI_OBJECT arg;
|
ACPI_OBJECT arg;
|
||||||
ACPI_OBJECT_LIST parameter;
|
ACPI_OBJECT_LIST parameter;
|
||||||
uint32 flags;
|
|
||||||
void *settings;
|
void *settings;
|
||||||
bool acpiDisabled = false;
|
bool acpiDisabled = false;
|
||||||
bool acpiAvoidFullInit = false;
|
|
||||||
AcpiGbl_CopyDsdtLocally = true;
|
AcpiGbl_CopyDsdtLocally = true;
|
||||||
|
|
||||||
settings = load_driver_settings("kernel");
|
settings = load_driver_settings("kernel");
|
||||||
if (settings != NULL) {
|
if (settings != NULL) {
|
||||||
acpiDisabled = !get_driver_boolean_parameter(settings, "acpi",
|
acpiDisabled = !get_driver_boolean_parameter(settings, "acpi",
|
||||||
true, true);
|
true, true);
|
||||||
acpiAvoidFullInit = get_driver_boolean_parameter(settings,
|
|
||||||
"acpi_avoid_full_init", false, false);
|
|
||||||
unload_driver_settings(settings);
|
unload_driver_settings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,10 +182,6 @@ acpi_std_ops(int32 op,...)
|
|||||||
|
|
||||||
AcpiEvaluateObject(NULL, "\\_PIC", ¶meter, NULL);
|
AcpiEvaluateObject(NULL, "\\_PIC", ¶meter, NULL);
|
||||||
|
|
||||||
flags = acpiAvoidFullInit ?
|
|
||||||
ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT :
|
|
||||||
ACPI_FULL_INITIALIZATION;
|
|
||||||
|
|
||||||
// FreeBSD seems to pass in the above flags here as
|
// FreeBSD seems to pass in the above flags here as
|
||||||
// well but specs don't define ACPI_NO_DEVICE_INIT
|
// well but specs don't define ACPI_NO_DEVICE_INIT
|
||||||
// and ACPI_NO_OBJECT_INIT here.
|
// and ACPI_NO_OBJECT_INIT here.
|
||||||
@ -200,7 +192,7 @@ acpi_std_ops(int32 op,...)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = AcpiInitializeObjects(flags);
|
status = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
ERROR("AcpiInitializeObjects failed (%s)\n",
|
ERROR("AcpiInitializeObjects failed (%s)\n",
|
||||||
AcpiFormatException(status));
|
AcpiFormatException(status));
|
||||||
|
@ -1640,6 +1640,7 @@ status_t
|
|||||||
init_ipv6()
|
init_ipv6()
|
||||||
{
|
{
|
||||||
mutex_init(&sRawSocketsLock, "raw sockets");
|
mutex_init(&sRawSocketsLock, "raw sockets");
|
||||||
|
mutex_init(&sFragmentLock, "IPv4 Fragments");
|
||||||
mutex_init(&sMulticastGroupsLock, "IPv6 multicast groups");
|
mutex_init(&sMulticastGroupsLock, "IPv6 multicast groups");
|
||||||
mutex_init(&sReceivingProtocolLock, "IPv6 receiving protocols");
|
mutex_init(&sReceivingProtocolLock, "IPv6 receiving protocols");
|
||||||
|
|
||||||
@ -1685,6 +1686,7 @@ err2:
|
|||||||
err1:
|
err1:
|
||||||
mutex_destroy(&sReceivingProtocolLock);
|
mutex_destroy(&sReceivingProtocolLock);
|
||||||
mutex_destroy(&sMulticastGroupsLock);
|
mutex_destroy(&sMulticastGroupsLock);
|
||||||
|
mutex_destroy(&sFragmentLock);
|
||||||
mutex_destroy(&sRawSocketsLock);
|
mutex_destroy(&sRawSocketsLock);
|
||||||
TRACE("init_ipv6: error %s", strerror(status));
|
TRACE("init_ipv6: error %s", strerror(status));
|
||||||
return status;
|
return status;
|
||||||
@ -1709,6 +1711,7 @@ uninit_ipv6()
|
|||||||
mutex_unlock(&sReceivingProtocolLock);
|
mutex_unlock(&sReceivingProtocolLock);
|
||||||
|
|
||||||
mutex_destroy(&sMulticastGroupsLock);
|
mutex_destroy(&sMulticastGroupsLock);
|
||||||
|
mutex_destroy(&sFragmentLock);
|
||||||
mutex_destroy(&sRawSocketsLock);
|
mutex_destroy(&sRawSocketsLock);
|
||||||
mutex_destroy(&sReceivingProtocolLock);
|
mutex_destroy(&sReceivingProtocolLock);
|
||||||
|
|
||||||
|
@ -999,7 +999,6 @@ AboutView::_CreateCreditsView()
|
|||||||
"Ithamar R. Adema\n"
|
"Ithamar R. Adema\n"
|
||||||
"Bruno G. Albuquerque\n"
|
"Bruno G. Albuquerque\n"
|
||||||
"Stephan Aßmus\n"
|
"Stephan Aßmus\n"
|
||||||
"Salvatore Benedetto\n"
|
|
||||||
"Stefano Ceccherini\n"
|
"Stefano Ceccherini\n"
|
||||||
"Rudolf Cornelissen\n"
|
"Rudolf Cornelissen\n"
|
||||||
"Alexandre Deckner\n"
|
"Alexandre Deckner\n"
|
||||||
@ -1010,25 +1009,19 @@ AboutView::_CreateCreditsView()
|
|||||||
"René Gollent\n"
|
"René Gollent\n"
|
||||||
"Bryce Groff\n"
|
"Bryce Groff\n"
|
||||||
"Colin Günther\n"
|
"Colin Günther\n"
|
||||||
"Karsten Heimrich\n"
|
|
||||||
"Fredrik Holmqvist\n"
|
"Fredrik Holmqvist\n"
|
||||||
"Philippe Houdoin\n"
|
"Philippe Houdoin\n"
|
||||||
"Maurice Kalinowski\n"
|
|
||||||
"Euan Kirkhope\n"
|
|
||||||
"Ryan Leavengood\n"
|
"Ryan Leavengood\n"
|
||||||
"Michael Lotz\n"
|
"Michael Lotz\n"
|
||||||
"Brecht Machiels\n"
|
|
||||||
"Matt Madia\n"
|
"Matt Madia\n"
|
||||||
"Scott McCreary\n"
|
"Scott McCreary\n"
|
||||||
"David McPaul\n"
|
"David McPaul\n"
|
||||||
"Wim van der Meer\n"
|
|
||||||
"Fredrik Modéen\n"
|
"Fredrik Modéen\n"
|
||||||
"Marcus Overhagen\n"
|
"Marcus Overhagen\n"
|
||||||
"Michael Pfeiffer\n"
|
"Michael Pfeiffer\n"
|
||||||
"François Revol\n"
|
"François Revol\n"
|
||||||
"Philippe Saint-Pierre\n"
|
"Philippe Saint-Pierre\n"
|
||||||
"John Scipione\n"
|
"John Scipione\n"
|
||||||
"Andrej Spielmann\n"
|
|
||||||
"Jonas Sundström\n"
|
"Jonas Sundström\n"
|
||||||
"Oliver Tappe\n"
|
"Oliver Tappe\n"
|
||||||
"Gerasim Troeglazov\n"
|
"Gerasim Troeglazov\n"
|
||||||
@ -1046,13 +1039,19 @@ AboutView::_CreateCreditsView()
|
|||||||
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey);
|
fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey);
|
||||||
fCreditsView->Insert(
|
fCreditsView->Insert(
|
||||||
"Andrew Bachmann\n"
|
"Andrew Bachmann\n"
|
||||||
|
"Salvatore Benedetto\n"
|
||||||
"Tyler Dauwalder\n"
|
"Tyler Dauwalder\n"
|
||||||
"Daniel Furrer\n"
|
"Daniel Furrer\n"
|
||||||
"Andre Alves Garzia\n"
|
"Andre Alves Garzia\n"
|
||||||
|
"Karsten Heimrich\n"
|
||||||
"Erik Jaesler\n"
|
"Erik Jaesler\n"
|
||||||
|
"Maurice Kalinowski\n"
|
||||||
|
"Euan Kirkhope\n"
|
||||||
"Marcin Konicki\n"
|
"Marcin Konicki\n"
|
||||||
"Waldemar Kornewald\n"
|
"Waldemar Kornewald\n"
|
||||||
"Thomas Kurschel\n"
|
"Thomas Kurschel\n"
|
||||||
|
"Brecht Machiels\n"
|
||||||
|
"Wim van der Meer\n"
|
||||||
"Frans Van Nispen\n"
|
"Frans Van Nispen\n"
|
||||||
"Adi Oanca\n"
|
"Adi Oanca\n"
|
||||||
"Michael Phipps\n"
|
"Michael Phipps\n"
|
||||||
@ -1060,6 +1059,7 @@ AboutView::_CreateCreditsView()
|
|||||||
"David Reid\n"
|
"David Reid\n"
|
||||||
"Hugo Santos\n"
|
"Hugo Santos\n"
|
||||||
"Alexander G. M. Smith\n"
|
"Alexander G. M. Smith\n"
|
||||||
|
"Andrej Spielmann\n"
|
||||||
"Bryan Varner\n"
|
"Bryan Varner\n"
|
||||||
"Nathan Whitehorn\n"
|
"Nathan Whitehorn\n"
|
||||||
"Michael Wilber\n"
|
"Michael Wilber\n"
|
||||||
@ -1096,8 +1096,10 @@ AboutView::_CreateCreditsView()
|
|||||||
"Michael Davidson\n"
|
"Michael Davidson\n"
|
||||||
"David Dengg\n"
|
"David Dengg\n"
|
||||||
"John Drinkwater\n"
|
"John Drinkwater\n"
|
||||||
|
"Yongcong Du\n"
|
||||||
"Cian Duffy\n"
|
"Cian Duffy\n"
|
||||||
"Vincent Duvert\n"
|
"Vincent Duvert\n"
|
||||||
|
"Pawel Dziepak\n"
|
||||||
"Mikael Eiman\n"
|
"Mikael Eiman\n"
|
||||||
"Fredrik Ekdahl\n"
|
"Fredrik Ekdahl\n"
|
||||||
"Joshua R. Elsasser\n"
|
"Joshua R. Elsasser\n"
|
||||||
@ -1112,7 +1114,9 @@ AboutView::_CreateCreditsView()
|
|||||||
"Deyan Genovski\n"
|
"Deyan Genovski\n"
|
||||||
"Pete Goodeve\n"
|
"Pete Goodeve\n"
|
||||||
"Lucian Adrian Grijincu\n"
|
"Lucian Adrian Grijincu\n"
|
||||||
|
"Jessica Hamilton\n"
|
||||||
"Sean Healy\n"
|
"Sean Healy\n"
|
||||||
|
"Andreas Henriksson\n"
|
||||||
"Matthijs Hollemans\n"
|
"Matthijs Hollemans\n"
|
||||||
"Mathew Hounsell\n"
|
"Mathew Hounsell\n"
|
||||||
"Morgan Howe\n"
|
"Morgan Howe\n"
|
||||||
@ -1163,20 +1167,22 @@ AboutView::_CreateCreditsView()
|
|||||||
"Jeremy Rand\n"
|
"Jeremy Rand\n"
|
||||||
"Hartmut Reh\n"
|
"Hartmut Reh\n"
|
||||||
"Daniel Reinhold\n"
|
"Daniel Reinhold\n"
|
||||||
|
"Sergei Reznikov\n"
|
||||||
"Chris Roberts\n"
|
"Chris Roberts\n"
|
||||||
"Samuel Rodríguez Pérez\n"
|
"Samuel Rodríguez Pérez\n"
|
||||||
"Thomas Roell\n"
|
"Thomas Roell\n"
|
||||||
"Rafael Romo\n"
|
"Rafael Romo\n"
|
||||||
"Ralf Schülke\n"
|
"Ralf Schülke\n"
|
||||||
"Reznikov Sergei\n"
|
|
||||||
"Zousar Shaker\n"
|
"Zousar Shaker\n"
|
||||||
"Caitlin Shaw\n"
|
"Caitlin Shaw\n"
|
||||||
|
"Alex Smith\n"
|
||||||
"Geoffry Song\n"
|
"Geoffry Song\n"
|
||||||
"Daniel Switkin\n"
|
"Daniel Switkin\n"
|
||||||
"Atsushi Takamatsu\n"
|
"Atsushi Takamatsu\n"
|
||||||
"James Urquhart\n"
|
"James Urquhart\n"
|
||||||
"Jason Vandermark\n"
|
"Jason Vandermark\n"
|
||||||
"Sandor Vroemisse\n"
|
"Sandor Vroemisse\n"
|
||||||
|
"Jürgen Wall\n"
|
||||||
"Denis Washington\n"
|
"Denis Washington\n"
|
||||||
"Ulrich Wimboeck\n"
|
"Ulrich Wimboeck\n"
|
||||||
"Johannes Wischert\n"
|
"Johannes Wischert\n"
|
||||||
@ -1188,7 +1194,7 @@ AboutView::_CreateCreditsView()
|
|||||||
"Zhao Shuai\n");
|
"Zhao Shuai\n");
|
||||||
fCreditsView->Insert(
|
fCreditsView->Insert(
|
||||||
B_TRANSLATE("\n" B_UTF8_ELLIPSIS
|
B_TRANSLATE("\n" B_UTF8_ELLIPSIS
|
||||||
" and probably some more we forgot to mention (sorry!)"
|
"and probably some more we forgot to mention (sorry!)"
|
||||||
"\n\n"));
|
"\n\n"));
|
||||||
|
|
||||||
fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange);
|
fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange);
|
||||||
@ -1256,11 +1262,12 @@ AboutView::_CreateCreditsView()
|
|||||||
fCreditsView->Insert(
|
fCreditsView->Insert(
|
||||||
B_TRANSLATE("The BeGeistert team\n"));
|
B_TRANSLATE("The BeGeistert team\n"));
|
||||||
fCreditsView->Insert(
|
fCreditsView->Insert(
|
||||||
B_TRANSLATE("Google & their Google Summer of Code program\n"));
|
B_TRANSLATE("Google and their Google Summer of Code and Google Code In "
|
||||||
|
"programs\n"));
|
||||||
fCreditsView->Insert(
|
fCreditsView->Insert(
|
||||||
B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n"));
|
B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n"));
|
||||||
fCreditsView->Insert(
|
fCreditsView->Insert(
|
||||||
B_TRANSLATE("... and the many people making donations!\n\n"));
|
B_TRANSLATE(B_UTF8_ELLIPSIS "and the many people making donations!\n\n"));
|
||||||
|
|
||||||
// copyrights for various projects we use
|
// copyrights for various projects we use
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2004-2012, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Copyright (c) 2002, Carlos Hasan, for Haiku.
|
* Copyright 2002, Carlos Hasan.
|
||||||
*
|
*
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*/
|
*/
|
||||||
@ -15,8 +15,8 @@
|
|||||||
#include <cpu_type.h>
|
#include <cpu_type.h>
|
||||||
|
|
||||||
|
|
||||||
// ToDo: -disable_cpu_sn option is not yet implemented
|
// TODO: -disable_cpu_sn option is not yet implemented
|
||||||
// ToDo: most of this file should go into an architecture dependent source file
|
// TODO: most of this file should go into an architecture dependent source file
|
||||||
#ifdef __INTEL__
|
#ifdef __INTEL__
|
||||||
|
|
||||||
struct cache_description {
|
struct cache_description {
|
||||||
@ -196,8 +196,8 @@ print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info)
|
|||||||
if (cacheDescriptors[i] == 0x40) {
|
if (cacheDescriptors[i] == 0x40) {
|
||||||
printf("\tNo integrated L%u cache\n",
|
printf("\tNo integrated L%u cache\n",
|
||||||
type >= B_CPU_INTEL_PENTIUM_IV
|
type >= B_CPU_INTEL_PENTIUM_IV
|
||||||
&& (type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86 ?
|
&& (type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86
|
||||||
3 : 2);
|
? 3 : 2);
|
||||||
} else
|
} else
|
||||||
printf("\t%s\n", sIntelCacheDescriptions[j].description);
|
printf("\t%s\n", sIntelCacheDescriptions[j].description);
|
||||||
break;
|
break;
|
||||||
@ -242,7 +242,8 @@ print_level2_cache(uint32 reg, const char *name)
|
|||||||
{
|
{
|
||||||
uint32 size = (reg >> 16) & 0xffff;
|
uint32 size = (reg >> 16) & 0xffff;
|
||||||
uint32 ways = (reg >> 12) & 0xf;
|
uint32 ways = (reg >> 12) & 0xf;
|
||||||
uint32 linesPerTag = (reg >> 8) & 0xf; // intel does not define this
|
uint32 linesPerTag = (reg >> 8) & 0xf;
|
||||||
|
// intel does not define this
|
||||||
uint32 lineSize = reg & 0xff;
|
uint32 lineSize = reg & 0xff;
|
||||||
|
|
||||||
printf("\t%s: %lu KB, ", name, size);
|
printf("\t%s: %lu KB, ", name, size);
|
||||||
@ -295,12 +296,14 @@ print_cache_desc(int32 cpu)
|
|||||||
print_level2_cache(info.regs.ecx, "L2 cache");
|
print_level2_cache(info.regs.ecx, "L2 cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_intel_cache_desc(int32 cpu)
|
print_intel_cache_desc(int32 cpu)
|
||||||
{
|
{
|
||||||
cpuid_info info;
|
cpuid_info info;
|
||||||
|
|
||||||
// A second parameters needs to be passed to CPUID which determines the cache level to query
|
// A second parameters needs to be passed to CPUID which determines the
|
||||||
|
// cache level to query
|
||||||
get_cpuid(&info, 0x00000004, cpu);
|
get_cpuid(&info, 0x00000004, cpu);
|
||||||
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
@ -459,24 +462,31 @@ print_features(uint32 features)
|
|||||||
#ifdef __INTEL__
|
#ifdef __INTEL__
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_processor_signature(system_info *sys_info, cpuid_info *info, const char *prefix)
|
print_processor_signature(system_info *sys_info, cpuid_info *info,
|
||||||
|
const char *prefix)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) {
|
if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) {
|
||||||
printf("\t%s%sype %lu, family %lu, model %u, stepping %lu, features 0x%08lx\n",
|
printf("\t%s%sype %lu, family %lu, model %lu, stepping %lu, features "
|
||||||
prefix ? prefix : "", prefix && prefix[0] ? "t" : "T",
|
"0x%08lx\n", prefix ? prefix : "", prefix && prefix[0] ? "t" : "T",
|
||||||
info->eax_1.type,
|
info->eax_1.type,
|
||||||
info->eax_1.family + (info->eax_1.family == 0xf ? info->eax_1.extended_family : 0),
|
info->eax_1.family + (info->eax_1.family == 0xf
|
||||||
info->eax_1.model + (info->eax_1.model == 0xf ? info->eax_1.extended_model << 4 : 0),
|
? info->eax_1.extended_family : 0),
|
||||||
|
info->eax_1.model + (info->eax_1.model == 0xf
|
||||||
|
? info->eax_1.extended_model << 4 : 0),
|
||||||
info->eax_1.stepping,
|
info->eax_1.stepping,
|
||||||
info->eax_1.features);
|
info->eax_1.features);
|
||||||
} else if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) {
|
} else if ((sys_info->cpu_type & B_CPU_x86_VENDOR_MASK)
|
||||||
|
== B_CPU_INTEL_x86) {
|
||||||
// model calculation is different for INTEL
|
// model calculation is different for INTEL
|
||||||
printf("\t%s%sype %lu, family %lu, model %u, stepping %lu, features 0x%08lx\n",
|
printf("\t%s%sype %lu, family %lu, model %lu, stepping %lu, features "
|
||||||
prefix ? prefix : "", prefix && prefix[0] ? "t" : "T",
|
"0x%08lx\n", prefix ? prefix : "", prefix && prefix[0] ? "t" : "T",
|
||||||
info->eax_1.type,
|
info->eax_1.type,
|
||||||
info->eax_1.family + (info->eax_1.family == 0xf ? info->eax_1.extended_family : 0),
|
info->eax_1.family + (info->eax_1.family == 0xf
|
||||||
info->eax_1.model + ((info->eax_1.family == 0xf || info->eax_1.family == 0x6) ? info->eax_1.extended_model << 4 : 0),
|
? info->eax_1.extended_family : 0),
|
||||||
|
info->eax_1.model
|
||||||
|
+ ((info->eax_1.family == 0xf || info->eax_1.family == 0x6)
|
||||||
|
? info->eax_1.extended_model << 4 : 0),
|
||||||
info->eax_1.stepping,
|
info->eax_1.stepping,
|
||||||
info->eax_1.features);
|
info->eax_1.features);
|
||||||
}
|
}
|
||||||
@ -500,12 +510,10 @@ dump_platform(system_info *info)
|
|||||||
static void
|
static void
|
||||||
dump_cpu(system_info *info, int32 cpu)
|
dump_cpu(system_info *info, int32 cpu)
|
||||||
{
|
{
|
||||||
/* references:
|
// References:
|
||||||
*
|
// http://grafi.ii.pw.edu.pl/gbm/x86/cpuid.html
|
||||||
* http://grafi.ii.pw.edu.pl/gbm/x86/cpuid.html
|
// http://www.sandpile.org/ia32/cpuid.htm
|
||||||
* http://www.sandpile.org/ia32/cpuid.htm
|
// http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/TN13.pdf (Duron erratum)
|
||||||
* http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/TN13.pdf (Duron erratum)
|
|
||||||
*/
|
|
||||||
|
|
||||||
cpuid_info baseInfo;
|
cpuid_info baseInfo;
|
||||||
if (get_cpuid(&baseInfo, 0, cpu) != B_OK) {
|
if (get_cpuid(&baseInfo, 0, cpu) != B_OK) {
|
||||||
@ -514,15 +522,18 @@ dump_cpu(system_info *info, int32 cpu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 maxStandardFunction = baseInfo.eax_0.max_eax;
|
int32 maxStandardFunction = baseInfo.eax_0.max_eax;
|
||||||
if (maxStandardFunction >= 500)
|
if (maxStandardFunction >= 500) {
|
||||||
maxStandardFunction = 0; /* old Pentium sample chips has cpu signature here */
|
// old Pentium sample chips has cpu signature here
|
||||||
|
maxStandardFunction = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Extended cpuid */
|
// Extended cpuid
|
||||||
|
|
||||||
cpuid_info cpuInfo;
|
cpuid_info cpuInfo;
|
||||||
get_cpuid(&cpuInfo, 0x80000000, cpu);
|
get_cpuid(&cpuInfo, 0x80000000, cpu);
|
||||||
|
|
||||||
// extended cpuid is only supported if max_eax is greater than the service id
|
// Extended cpuid is only supported if max_eax is greater than the
|
||||||
|
// service id
|
||||||
int32 maxExtendedFunction = 0;
|
int32 maxExtendedFunction = 0;
|
||||||
if (cpuInfo.eax_0.max_eax > 0x80000000)
|
if (cpuInfo.eax_0.max_eax > 0x80000000)
|
||||||
maxExtendedFunction = cpuInfo.eax_0.max_eax & 0xff;
|
maxExtendedFunction = cpuInfo.eax_0.max_eax & 0xff;
|
||||||
@ -586,7 +597,8 @@ dump_cpu(system_info *info, int32 cpu)
|
|||||||
get_cpuid(&cpuInfo, 0x80000007, cpu);
|
get_cpuid(&cpuInfo, 0x80000007, cpu);
|
||||||
print_amd_power_management_features(cpuInfo.regs.edx);
|
print_amd_power_management_features(cpuInfo.regs.edx);
|
||||||
}
|
}
|
||||||
} else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_TRANSMETA_x86)
|
} else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK)
|
||||||
|
== B_CPU_TRANSMETA_x86)
|
||||||
print_transmeta_features(cpuInfo.regs.edx);
|
print_transmeta_features(cpuInfo.regs.edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +607,8 @@ dump_cpu(system_info *info, int32 cpu)
|
|||||||
if (!strncmp(baseInfo.eax_0.vendor_id, "CyrixInstead", 12)) {
|
if (!strncmp(baseInfo.eax_0.vendor_id, "CyrixInstead", 12)) {
|
||||||
get_cpuid(&cpuInfo, 0x00000002, cpu);
|
get_cpuid(&cpuInfo, 0x00000002, cpu);
|
||||||
print_intel_cache_descriptors(info->cpu_type, &cpuInfo);
|
print_intel_cache_descriptors(info->cpu_type, &cpuInfo);
|
||||||
} else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) {
|
} else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK)
|
||||||
|
== B_CPU_INTEL_x86) {
|
||||||
// Intel does not support extended function 5 (but it does 6 hmm)
|
// Intel does not support extended function 5 (but it does 6 hmm)
|
||||||
print_intel_cache_desc(cpu);
|
print_intel_cache_desc(cpu);
|
||||||
} else {
|
} else {
|
||||||
@ -620,7 +633,8 @@ dump_cpu(system_info *info, int32 cpu)
|
|||||||
if (flagsInfo.eax_1.features & (1UL << 18)) {
|
if (flagsInfo.eax_1.features & (1UL << 18)) {
|
||||||
get_cpuid(&cpuInfo, 3, cpu);
|
get_cpuid(&cpuInfo, 3, cpu);
|
||||||
printf("Serial number: %04lx-%04lx-%04lx-%04lx-%04lx-%04lx\n",
|
printf("Serial number: %04lx-%04lx-%04lx-%04lx-%04lx-%04lx\n",
|
||||||
flagsInfo.eax_1.features >> 16, flagsInfo.eax_1.features & 0xffff,
|
flagsInfo.eax_1.features >> 16,
|
||||||
|
flagsInfo.eax_1.features & 0xffff,
|
||||||
cpuInfo.regs.edx >> 16, cpuInfo.regs.edx & 0xffff,
|
cpuInfo.regs.edx >> 16, cpuInfo.regs.edx & 0xffff,
|
||||||
cpuInfo.regs.ecx >> 16, cpuInfo.regs.edx & 0xffff);
|
cpuInfo.regs.ecx >> 16, cpuInfo.regs.edx & 0xffff);
|
||||||
}
|
}
|
||||||
@ -646,8 +660,8 @@ dump_cpus(system_info *info)
|
|||||||
snprintf(modelString, 32, "(Unknown %x)", info->cpu_type);
|
snprintf(modelString, 32, "(Unknown %x)", info->cpu_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%ld %s%s%s, revision %04lx running at %LdMHz (ID: 0x%08lx 0x%08lx)\n\n",
|
printf("%ld %s%s%s, revision %04lx running at %LdMHz (ID: 0x%08lx "
|
||||||
info->cpu_count,
|
"0x%08lx)\n\n", info->cpu_count,
|
||||||
vendor ? vendor : "", vendor ? " " : "", model,
|
vendor ? vendor : "", vendor ? " " : "", model,
|
||||||
info->cpu_revision,
|
info->cpu_revision,
|
||||||
info->cpu_clock_speed / 1000000,
|
info->cpu_clock_speed / 1000000,
|
||||||
|
@ -1,23 +1,25 @@
|
|||||||
SubDir HAIKU_TOP src preferences virtualmemory ;
|
SubDir HAIKU_TOP src preferences virtualmemory ;
|
||||||
|
|
||||||
Preference VirtualMemory :
|
UsePrivateHeaders shared system ;
|
||||||
|
|
||||||
|
Preference VirtualMemory :
|
||||||
VirtualMemory.cpp
|
VirtualMemory.cpp
|
||||||
SettingsWindow.cpp
|
SettingsWindow.cpp
|
||||||
Settings.cpp
|
Settings.cpp
|
||||||
$(DRIVER_SETTINGS)
|
$(DRIVER_SETTINGS)
|
||||||
|
|
||||||
: be $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS)
|
: be libshared.a $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS)
|
||||||
: VirtualMemory.rdef
|
: VirtualMemory.rdef
|
||||||
;
|
;
|
||||||
|
|
||||||
if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||||
SEARCH on [ FGristFiles driver_settings.c ] +=
|
SEARCH on [ FGristFiles driver_settings.c ] +=
|
||||||
[ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
[ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoCatalogs VirtualMemory :
|
DoCatalogs VirtualMemory :
|
||||||
x-vnd.Haiku-VirtualMemory
|
x-vnd.Haiku-VirtualMemory
|
||||||
:
|
:
|
||||||
VirtualMemory.cpp
|
VirtualMemory.cpp
|
||||||
SettingsWindow.cpp
|
SettingsWindow.cpp
|
||||||
;
|
;
|
||||||
|
@ -1,192 +1,213 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011, Hamish Morrison, hamish@lavabit.com
|
|
||||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de
|
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright 2010-2012 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hamish Morrison, hamish@lavabit.com
|
||||||
|
* Alexander von Gluck, kallisti5@unixzen.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#include <File.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <Path.h>
|
|
||||||
#include <Volume.h>
|
|
||||||
#include <VolumeRoster.h>
|
|
||||||
#include <driver_settings.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
static const char* kWindowSettingsFile = "VM_data";
|
#include <driver_settings.h>
|
||||||
static const char* kVirtualMemorySettings = "virtual_memory";
|
|
||||||
static const int64 kMegaByte = 1024 * 1024;
|
|
||||||
|
static const char* const kWindowSettingsFile = "virtualmemory_preferences";
|
||||||
|
static const char* const kVirtualMemorySettings = "virtual_memory";
|
||||||
|
static const off_t kMegaByte = 1024 * 1024;
|
||||||
|
static const off_t kGigaByte = kMegaByte * 1024;
|
||||||
|
|
||||||
|
|
||||||
Settings::Settings()
|
Settings::Settings()
|
||||||
:
|
|
||||||
fPositionUpdated(false)
|
|
||||||
{
|
{
|
||||||
_ReadWindowSettings();
|
fDefaultSettings.enabled = true;
|
||||||
_ReadSwapSettings();
|
fDefaultSettings.automatic = true;
|
||||||
|
|
||||||
|
system_info sysInfo;
|
||||||
|
get_system_info(&sysInfo);
|
||||||
|
|
||||||
|
fDefaultSettings.size = (off_t)sysInfo.max_pages * B_PAGE_SIZE;
|
||||||
|
if (fDefaultSettings.size <= kGigaByte) {
|
||||||
|
// Memory under 1GB? double the swap
|
||||||
|
// This matches the behaviour of the kernel
|
||||||
|
fDefaultSettings.size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fDefaultSettings.volume = dev_for_path("/boot");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Settings::~Settings()
|
void
|
||||||
|
Settings::SetSwapEnabled(bool enabled, bool revertable)
|
||||||
{
|
{
|
||||||
_WriteWindowSettings();
|
fCurrentSettings.enabled = enabled;
|
||||||
_WriteSwapSettings();
|
if (!revertable)
|
||||||
|
fInitialSettings.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::SetSwapAutomatic(bool automatic, bool revertable)
|
||||||
|
{
|
||||||
|
fCurrentSettings.automatic = automatic;
|
||||||
|
if (!revertable)
|
||||||
|
fInitialSettings.automatic = automatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::SetSwapSize(off_t size, bool revertable)
|
||||||
|
{
|
||||||
|
fCurrentSettings.size = size;
|
||||||
|
if (!revertable)
|
||||||
|
fInitialSettings.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::SetSwapVolume(dev_t volume, bool revertable)
|
||||||
|
{
|
||||||
|
fCurrentSettings.volume = volume;
|
||||||
|
if (!revertable)
|
||||||
|
fInitialSettings.volume = volume;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Settings::SetWindowPosition(BPoint position)
|
Settings::SetWindowPosition(BPoint position)
|
||||||
{
|
{
|
||||||
if (position == fWindowPosition)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fWindowPosition = position;
|
fWindowPosition = position;
|
||||||
fPositionUpdated = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
Settings::SetSwapEnabled(bool enabled)
|
Settings::ReadWindowSettings()
|
||||||
{
|
{
|
||||||
fSwapEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::SetSwapSize(off_t size)
|
|
||||||
{
|
|
||||||
fSwapSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::SetSwapVolume(BVolume &volume)
|
|
||||||
{
|
|
||||||
if (volume.Device() == SwapVolume().Device()
|
|
||||||
|| volume.InitCheck() != B_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fSwapVolume.SetTo(volume.Device());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::RevertSwapChanges()
|
|
||||||
{
|
|
||||||
fSwapEnabled = fInitialSwapEnabled;
|
|
||||||
fSwapSize = fInitialSwapSize;
|
|
||||||
fSwapVolume.SetTo(fInitialSwapVolume);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
Settings::IsRevertible()
|
|
||||||
{
|
|
||||||
return fSwapEnabled != fInitialSwapEnabled
|
|
||||||
|| fSwapSize != fInitialSwapSize
|
|
||||||
|| fSwapVolume.Device() != fInitialSwapVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Settings::_ReadWindowSettings()
|
|
||||||
{
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
BPath path;
|
BPath path;
|
||||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||||
path.Append(kWindowSettingsFile);
|
return B_ERROR;
|
||||||
BFile file;
|
|
||||||
if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK)
|
|
||||||
if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint))
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success)
|
path.Append(kWindowSettingsFile);
|
||||||
fWindowPosition.Set(-1, -1);
|
BFile file;
|
||||||
|
if (file.SetTo(path.Path(), B_READ_ONLY) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint))
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
Settings::_WriteWindowSettings()
|
Settings::WriteWindowSettings()
|
||||||
{
|
{
|
||||||
if (!fPositionUpdated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BPath path;
|
BPath path;
|
||||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK)
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK)
|
||||||
return;
|
return B_ERROR;
|
||||||
|
|
||||||
path.Append(kWindowSettingsFile);
|
path.Append(kWindowSettingsFile);
|
||||||
|
|
||||||
BFile file;
|
BFile file;
|
||||||
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) == B_OK)
|
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)
|
||||||
file.Write(&fWindowPosition, sizeof(BPoint));
|
!= B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
file.Write(&fWindowPosition, sizeof(BPoint));
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
Settings::_ReadSwapSettings()
|
Settings::ReadSwapSettings()
|
||||||
{
|
{
|
||||||
void* settings = load_driver_settings(kVirtualMemorySettings);
|
void* settings = load_driver_settings(kVirtualMemorySettings);
|
||||||
if (settings != NULL) {
|
if (settings == NULL)
|
||||||
SetSwapEnabled(get_driver_boolean_parameter(settings, "vm", false, false));
|
return kErrorSettingsNotFound;
|
||||||
const char* swapSize = get_driver_parameter(settings, "swap_size", NULL, NULL);
|
|
||||||
SetSwapSize(swapSize ? atoll(swapSize) : 0);
|
const char* enabled = get_driver_parameter(settings, "vm", NULL, NULL);
|
||||||
|
const char* automatic = get_driver_parameter(settings, "swap_auto",
|
||||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
NULL, NULL);
|
||||||
// we need to hang onto this one
|
const char* size = get_driver_parameter(settings, "swap_size", NULL, NULL);
|
||||||
fBadVolName = strdup(get_driver_parameter(settings, "swap_volume", NULL, NULL));
|
const char* volume = get_driver_parameter(settings, "swap_volume_name",
|
||||||
|
NULL, NULL);
|
||||||
BVolumeRoster volumeRoster;
|
const char* device = get_driver_parameter(settings,
|
||||||
BVolume temporaryVolume;
|
"swap_volume_device", NULL, NULL);
|
||||||
|
const char* filesystem = get_driver_parameter(settings,
|
||||||
if (fBadVolName != NULL) {
|
"swap_volume_filesystem", NULL, NULL);
|
||||||
status_t result = volumeRoster.GetNextVolume(&temporaryVolume);
|
const char* capacity = get_driver_parameter(settings,
|
||||||
char volumeName[B_FILE_NAME_LENGTH];
|
"swap_volume_capacity", NULL, NULL);
|
||||||
while (result != B_BAD_VALUE) {
|
|
||||||
temporaryVolume.GetName(volumeName);
|
if (enabled == NULL || automatic == NULL || size == NULL || device == NULL
|
||||||
if (strcmp(volumeName, fBadVolName) == 0
|
|| volume == NULL || capacity == NULL || filesystem == NULL)
|
||||||
&& temporaryVolume.IsPersistent() && volumeName[0]) {
|
return kErrorSettingsInvalid;
|
||||||
SetSwapVolume(temporaryVolume);
|
|
||||||
break;
|
off_t volCapacity = atoll(capacity);
|
||||||
}
|
|
||||||
result = volumeRoster.GetNextVolume(&temporaryVolume);
|
SetSwapEnabled(get_driver_boolean_parameter(settings,
|
||||||
|
"vm", true, false));
|
||||||
|
SetSwapAutomatic(get_driver_boolean_parameter(settings,
|
||||||
|
"swap_auto", true, false));
|
||||||
|
SetSwapSize(atoll(size));
|
||||||
|
unload_driver_settings(settings);
|
||||||
|
|
||||||
|
int32 bestScore = -1;
|
||||||
|
dev_t bestVol = -1;
|
||||||
|
|
||||||
|
BVolume vol;
|
||||||
|
fs_info volStat;
|
||||||
|
BVolumeRoster roster;
|
||||||
|
while (roster.GetNextVolume(&vol) == B_OK) {
|
||||||
|
if (!vol.IsPersistent() || vol.IsReadOnly() || vol.IsRemovable()
|
||||||
|
|| vol.IsShared())
|
||||||
|
continue;
|
||||||
|
if (fs_stat_dev(vol.Device(), &volStat) == 0) {
|
||||||
|
int32 score = 0;
|
||||||
|
if (strcmp(volume, volStat.volume_name) == 0)
|
||||||
|
score += 4;
|
||||||
|
if (strcmp(device, volStat.device_name) == 0)
|
||||||
|
score += 3;
|
||||||
|
if (volCapacity == volStat.total_blocks * volStat.block_size)
|
||||||
|
score += 2;
|
||||||
|
if (strcmp(filesystem, volStat.fsh_name) == 0)
|
||||||
|
score += 1;
|
||||||
|
if (score >= 4 && score > bestScore) {
|
||||||
|
bestVol = vol.Device();
|
||||||
|
bestScore = score;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
volumeRoster.GetBootVolume(&fSwapVolume);
|
}
|
||||||
#endif
|
|
||||||
unload_driver_settings(settings);
|
|
||||||
} else
|
|
||||||
_SetSwapNull();
|
|
||||||
|
|
||||||
#ifndef SWAP_VOLUME_IMPLEMENTED
|
SetSwapVolume(bestVol);
|
||||||
BVolumeRoster volumeRoster;
|
fInitialSettings = fCurrentSettings;
|
||||||
volumeRoster.GetBootVolume(&fSwapVolume);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fInitialSwapEnabled = fSwapEnabled;
|
if (bestVol < 0)
|
||||||
fInitialSwapSize = fSwapSize;
|
return kErrorVolumeNotFound;
|
||||||
fInitialSwapVolume = fSwapVolume.Device();
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
Settings::_WriteSwapSettings()
|
Settings::WriteSwapSettings()
|
||||||
{
|
{
|
||||||
if (!IsRevertible())
|
|
||||||
return;
|
|
||||||
|
|
||||||
BPath path;
|
BPath path;
|
||||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||||
return;
|
return B_ERROR;
|
||||||
|
|
||||||
path.Append("kernel/drivers");
|
path.Append("kernel/drivers");
|
||||||
path.Append(kVirtualMemorySettings);
|
path.Append(kVirtualMemorySettings);
|
||||||
@ -194,36 +215,62 @@ Settings::_WriteSwapSettings()
|
|||||||
BFile file;
|
BFile file;
|
||||||
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)
|
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)
|
||||||
!= B_OK)
|
!= B_OK)
|
||||||
return;
|
return B_ERROR;
|
||||||
|
|
||||||
char buffer[256];
|
fs_info info;
|
||||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
if (fs_stat_dev(SwapVolume(), &info) != 0)
|
||||||
char volumeName[B_FILE_NAME_LENGTH] = {0};
|
return B_ERROR;
|
||||||
if (SwapVolume().InitCheck() != B_NO_INIT)
|
|
||||||
SwapVolume().GetName(volumeName);
|
char buffer[1024];
|
||||||
else if (fBadVolName)
|
snprintf(buffer, sizeof(buffer), "vm %s\nswap_auto %s\nswap_size %lld\n"
|
||||||
strcpy(volumeName, fBadVolName);
|
"swap_volume_name %s\nswap_volume_device %s\n"
|
||||||
snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\nswap_volume %s\n",
|
"swap_volume_filesystem %s\nswap_volume_capacity %lld\n",
|
||||||
SwapEnabled() ? "on" : "off", SwapSize(),
|
SwapEnabled() ? "on" : "off", SwapAutomatic() ? "yes" : "no",
|
||||||
volumeName[0] ? volumeName : NULL);
|
SwapSize(), info.volume_name, info.device_name, info.fsh_name,
|
||||||
#else
|
info.total_blocks * info.block_size);
|
||||||
snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\n",
|
|
||||||
fSwapEnabled ? "on" : "off", fSwapSize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
file.Write(buffer, strlen(buffer));
|
file.Write(buffer, strlen(buffer));
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Settings::IsRevertable()
|
||||||
|
{
|
||||||
|
return SwapEnabled() != fInitialSettings.enabled
|
||||||
|
|| SwapAutomatic() != fInitialSettings.automatic
|
||||||
|
|| SwapSize() != fInitialSettings.size
|
||||||
|
|| SwapVolume() != fInitialSettings.volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Settings::_SetSwapNull()
|
Settings::RevertSwapSettings()
|
||||||
{
|
{
|
||||||
SetSwapEnabled(false);
|
SetSwapEnabled(fInitialSettings.enabled);
|
||||||
BVolumeRoster volumeRoster;
|
SetSwapAutomatic(fInitialSettings.automatic);
|
||||||
BVolume temporaryVolume;
|
SetSwapSize(fInitialSettings.size);
|
||||||
volumeRoster.GetBootVolume(&temporaryVolume);
|
SetSwapVolume(fInitialSettings.volume);
|
||||||
SetSwapVolume(temporaryVolume);
|
|
||||||
SetSwapSize(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Settings::IsDefaultable()
|
||||||
|
{
|
||||||
|
return SwapEnabled() != fDefaultSettings.enabled
|
||||||
|
|| SwapAutomatic() != fDefaultSettings.automatic
|
||||||
|
|| SwapSize() != fDefaultSettings.size
|
||||||
|
|| SwapVolume() != fDefaultSettings.volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Settings::DefaultSwapSettings(bool revertable)
|
||||||
|
{
|
||||||
|
SetSwapEnabled(fDefaultSettings.enabled);
|
||||||
|
SetSwapAutomatic(fDefaultSettings.automatic);
|
||||||
|
SetSwapSize(fDefaultSettings.size);
|
||||||
|
SetSwapVolume(fDefaultSettings.volume);
|
||||||
|
if (!revertable)
|
||||||
|
fInitialSettings = fDefaultSettings;
|
||||||
|
}
|
||||||
|
@ -1,54 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright 2010-2012 Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hamish Morrison, hamish@lavabit.com
|
||||||
|
* Alexander von Gluck, kallisti5@unixzen.com
|
||||||
*/
|
*/
|
||||||
#ifndef SETTINGS_H
|
#ifndef SETTINGS_H
|
||||||
#define SETTINGS_H
|
#define SETTINGS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <Point.h>
|
#include <Point.h>
|
||||||
#include <Volume.h>
|
|
||||||
|
|
||||||
|
static const int32 kErrorSettingsNotFound = B_ERRORS_END + 1;
|
||||||
|
static const int32 kErrorSettingsInvalid = B_ERRORS_END + 2;
|
||||||
|
static const int32 kErrorVolumeNotFound = B_ERRORS_END + 3;
|
||||||
|
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
public :
|
public:
|
||||||
Settings();
|
Settings();
|
||||||
virtual ~Settings();
|
|
||||||
|
|
||||||
BPoint WindowPosition() const { return fWindowPosition; }
|
bool SwapEnabled() const
|
||||||
void SetWindowPosition(BPoint position);
|
{ return fCurrentSettings.enabled; }
|
||||||
|
bool SwapAutomatic() const
|
||||||
|
{ return fCurrentSettings.automatic; }
|
||||||
|
off_t SwapSize() const { return fCurrentSettings.size; }
|
||||||
|
dev_t SwapVolume() { return fCurrentSettings.volume; }
|
||||||
|
BPoint WindowPosition() const { return fWindowPosition; }
|
||||||
|
|
||||||
bool SwapEnabled() const { return fSwapEnabled; }
|
|
||||||
off_t SwapSize() const { return fSwapSize; }
|
|
||||||
BVolume& SwapVolume() { return fSwapVolume; }
|
|
||||||
void SetSwapEnabled(bool enabled);
|
|
||||||
void SetSwapSize(off_t size);
|
|
||||||
void SetSwapVolume(BVolume& volume);
|
|
||||||
|
|
||||||
void RevertSwapChanges();
|
void SetSwapEnabled(bool enabled,
|
||||||
bool IsRevertible();
|
bool revertable = true);
|
||||||
|
void SetSwapAutomatic(bool automatic,
|
||||||
|
bool revertable = true);
|
||||||
|
void SetSwapSize(off_t size, bool revertable = true);
|
||||||
|
void SetSwapVolume(dev_t volume,
|
||||||
|
bool revertable = true);
|
||||||
|
void SetWindowPosition(BPoint position);
|
||||||
|
|
||||||
private:
|
status_t ReadWindowSettings();
|
||||||
void _ReadWindowSettings();
|
status_t WriteWindowSettings();
|
||||||
void _WriteWindowSettings();
|
status_t ReadSwapSettings();
|
||||||
|
status_t WriteSwapSettings();
|
||||||
|
|
||||||
void _ReadSwapSettings();
|
bool IsRevertable();
|
||||||
void _WriteSwapSettings();
|
void RevertSwapSettings();
|
||||||
|
|
||||||
void _SetSwapNull();
|
bool IsDefaultable();
|
||||||
|
void DefaultSwapSettings(bool revertable = true);
|
||||||
|
private:
|
||||||
|
struct SwapSettings {
|
||||||
|
bool enabled;
|
||||||
|
bool automatic;
|
||||||
|
off_t size;
|
||||||
|
dev_t volume;
|
||||||
|
};
|
||||||
|
|
||||||
BPoint fWindowPosition;
|
BPoint fWindowPosition;
|
||||||
|
|
||||||
bool fSwapEnabled;
|
SwapSettings fCurrentSettings;
|
||||||
off_t fSwapSize;
|
SwapSettings fInitialSettings;
|
||||||
BVolume fSwapVolume;
|
SwapSettings fDefaultSettings;
|
||||||
|
|
||||||
bool fInitialSwapEnabled;
|
|
||||||
off_t fInitialSwapSize;
|
|
||||||
dev_t fInitialSwapVolume;
|
|
||||||
|
|
||||||
bool fPositionUpdated;
|
|
||||||
const char* fBadVolName;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SETTINGS_H */
|
#endif /* SETTINGS_H */
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011, Hamish Morrison, hamish@lavabit.com
|
|
||||||
* Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de
|
* Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright 2010-2012 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hamish Morrison, hamish@lavabit.com
|
||||||
|
* Alexander von Gluck, kallisti5@unixzen.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "SettingsWindow.h"
|
#include "SettingsWindow.h"
|
||||||
#include "Settings.h"
|
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
@ -14,22 +19,25 @@
|
|||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <CheckBox.h>
|
#include <CheckBox.h>
|
||||||
#include <GroupLayout.h>
|
#include <Directory.h>
|
||||||
#include <GroupLayoutBuilder.h>
|
#include <FindDirectory.h>
|
||||||
#include <Locale.h>
|
#include <LayoutBuilder.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <MenuField.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <Screen.h>
|
||||||
|
#include <StringForSize.h>
|
||||||
#include <StringView.h>
|
#include <StringView.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Slider.h>
|
#include <Slider.h>
|
||||||
#include <PopUpMenu.h>
|
#include <system_info.h>
|
||||||
#include <MenuItem.h>
|
|
||||||
#include <MenuField.h>
|
|
||||||
#include <Screen.h>
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <Path.h>
|
|
||||||
#include <Volume.h>
|
#include <Volume.h>
|
||||||
#include <VolumeRoster.h>
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "Settings.h"
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATION_CONTEXT
|
#undef B_TRANSLATION_CONTEXT
|
||||||
#define B_TRANSLATION_CONTEXT "SettingsWindow"
|
#define B_TRANSLATION_CONTEXT "SettingsWindow"
|
||||||
@ -39,91 +47,72 @@ static const uint32 kMsgDefaults = 'dflt';
|
|||||||
static const uint32 kMsgRevert = 'rvrt';
|
static const uint32 kMsgRevert = 'rvrt';
|
||||||
static const uint32 kMsgSliderUpdate = 'slup';
|
static const uint32 kMsgSliderUpdate = 'slup';
|
||||||
static const uint32 kMsgSwapEnabledUpdate = 'swen';
|
static const uint32 kMsgSwapEnabledUpdate = 'swen';
|
||||||
|
static const uint32 kMsgSwapAutomaticUpdate = 'swat';
|
||||||
static const uint32 kMsgVolumeSelected = 'vlsl';
|
static const uint32 kMsgVolumeSelected = 'vlsl';
|
||||||
static const int64 kMegaByte = 1024 * 1024;
|
static const off_t kMegaByte = 1024 * 1024;
|
||||||
|
static dev_t gBootDev = -1;
|
||||||
|
|
||||||
class SizeSlider : public BSlider {
|
|
||||||
public:
|
|
||||||
SizeSlider(const char* name, const char* label,
|
|
||||||
BMessage* message, int32 min, int32 max, uint32 flags);
|
|
||||||
virtual ~SizeSlider();
|
|
||||||
|
|
||||||
virtual const char* UpdateText() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable BString fText;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
SizeSlider::SizeSlider(const char* name, const char* label,
|
SizeSlider::SizeSlider(const char* name, const char* label,
|
||||||
BMessage* message, int32 min, int32 max, uint32 flags)
|
BMessage* message, int32 min, int32 max, uint32 flags)
|
||||||
: BSlider(name, label, message, min, max, B_HORIZONTAL, B_BLOCK_THUMB, flags)
|
:
|
||||||
|
BSlider(name, label, message, min, max, B_HORIZONTAL,
|
||||||
|
B_BLOCK_THUMB, flags)
|
||||||
{
|
{
|
||||||
rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
|
rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
|
||||||
UseFillColor(true, &color);
|
UseFillColor(true, &color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SizeSlider::~SizeSlider()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char*
|
|
||||||
byte_string(int64 size)
|
|
||||||
{
|
|
||||||
double value = 1. * size;
|
|
||||||
static char string[256];
|
|
||||||
|
|
||||||
if (value < 1024)
|
|
||||||
snprintf(string, sizeof(string), B_TRANSLATE("%Ld B"), size);
|
|
||||||
else {
|
|
||||||
static const char *units[] = {
|
|
||||||
B_TRANSLATE_MARK("KB"),
|
|
||||||
B_TRANSLATE_MARK("MB"),
|
|
||||||
B_TRANSLATE_MARK("GB"),
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
int32 i = -1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
value /= 1024.0;
|
|
||||||
i++;
|
|
||||||
} while (value >= 1024 && units[i + 1]);
|
|
||||||
|
|
||||||
off_t rounded = off_t(value * 100LL);
|
|
||||||
snprintf(string, sizeof(string), "%g %s", rounded / 100.0,
|
|
||||||
B_TRANSLATE_NOCOLLECT(units[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
SizeSlider::UpdateText() const
|
SizeSlider::UpdateText() const
|
||||||
{
|
{
|
||||||
fText = byte_string(Value() * kMegaByte);
|
return string_for_size(Value() * kMegaByte, fText, sizeof(fText));
|
||||||
return fText.String();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class VolumeMenuItem : public BMenuItem {
|
VolumeMenuItem::VolumeMenuItem(BVolume volume, BMessage* message)
|
||||||
public:
|
:
|
||||||
VolumeMenuItem(const char* label, BMessage* message, BVolume* volume);
|
BMenuItem("", message),
|
||||||
BVolume* Volume() { return fVolume; }
|
fVolume(volume)
|
||||||
|
|
||||||
private:
|
|
||||||
BVolume* fVolume;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
VolumeMenuItem::VolumeMenuItem(const char* label, BMessage* message,
|
|
||||||
BVolume* volume)
|
|
||||||
: BMenuItem(label, message)
|
|
||||||
{
|
{
|
||||||
fVolume = volume;
|
GenerateLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VolumeMenuItem::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
if (message->what == B_NODE_MONITOR) {
|
||||||
|
int32 code;
|
||||||
|
if (message->FindInt32("opcode", &code) == B_OK)
|
||||||
|
if (code == B_ENTRY_MOVED)
|
||||||
|
GenerateLabel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VolumeMenuItem::GenerateLabel()
|
||||||
|
{
|
||||||
|
char name[B_FILE_NAME_LENGTH + 1];
|
||||||
|
fVolume.GetName(name);
|
||||||
|
|
||||||
|
BDirectory dir;
|
||||||
|
if (fVolume.GetRootDirectory(&dir) == B_OK) {
|
||||||
|
BEntry entry;
|
||||||
|
if (dir.GetEntry(&entry) == B_OK) {
|
||||||
|
BPath path;
|
||||||
|
if (entry.GetPath(&path) == B_OK) {
|
||||||
|
BString label;
|
||||||
|
label << name << " (" << path.Path() << ")";
|
||||||
|
SetLabel(label);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLabel(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -131,81 +120,90 @@ SettingsWindow::SettingsWindow()
|
|||||||
:
|
:
|
||||||
BWindow(BRect(0, 0, 269, 172), B_TRANSLATE_SYSTEM_NAME("VirtualMemory"),
|
BWindow(BRect(0, 0, 269, 172), B_TRANSLATE_SYSTEM_NAME("VirtualMemory"),
|
||||||
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS
|
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS
|
||||||
| B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
| B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)
|
||||||
fLocked(false)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
BView* view = new BGroupView();
|
gBootDev = dev_for_path("/boot");
|
||||||
|
BAlignment align(B_ALIGN_LEFT, B_ALIGN_MIDDLE);
|
||||||
|
|
||||||
|
if (fSettings.ReadWindowSettings() != B_OK)
|
||||||
|
CenterOnScreen();
|
||||||
|
else
|
||||||
|
MoveTo(fSettings.WindowPosition());
|
||||||
|
|
||||||
|
status_t result = fSettings.ReadSwapSettings();
|
||||||
|
if (result == kErrorSettingsNotFound)
|
||||||
|
fSettings.DefaultSwapSettings(false);
|
||||||
|
else if (result == kErrorSettingsInvalid) {
|
||||||
|
int32 choice = (new BAlert(B_TRANSLATE_SYSTEM_NAME("VirtualMemory"),
|
||||||
|
B_TRANSLATE("The settings specified in the settings file "
|
||||||
|
"are invalid. You can load the defaults or quit."),
|
||||||
|
B_TRANSLATE("Load defaults"), B_TRANSLATE("Quit")))->Go();
|
||||||
|
if (choice == 1) {
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fSettings.DefaultSwapSettings(false);
|
||||||
|
} else if (result == kErrorVolumeNotFound) {
|
||||||
|
int32 choice = (new BAlert(B_TRANSLATE_SYSTEM_NAME("VirtualMemory"),
|
||||||
|
B_TRANSLATE("The volume specified in the settings file "
|
||||||
|
"could not be found. You can use the boot volume or quit."),
|
||||||
|
B_TRANSLATE("Use boot volume"), B_TRANSLATE("Quit")))->Go();
|
||||||
|
if (choice == 1) {
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fSettings.SetSwapVolume(gBootDev, false);
|
||||||
|
}
|
||||||
|
|
||||||
fSwapEnabledCheckBox = new BCheckBox("enable swap",
|
fSwapEnabledCheckBox = new BCheckBox("enable swap",
|
||||||
B_TRANSLATE("Enable virtual memory"),
|
B_TRANSLATE("Enable virtual memory"),
|
||||||
new BMessage(kMsgSwapEnabledUpdate));
|
new BMessage(kMsgSwapEnabledUpdate));
|
||||||
|
fSwapEnabledCheckBox->SetExplicitAlignment(align);
|
||||||
|
|
||||||
BBox* box = new BBox("box", B_FOLLOW_LEFT_RIGHT);
|
fSwapAutomaticCheckBox = new BCheckBox("auto swap",
|
||||||
box->SetLabel(fSwapEnabledCheckBox);
|
B_TRANSLATE("Choose swap size automatically"),
|
||||||
|
new BMessage(kMsgSwapAutomaticUpdate));
|
||||||
|
fSwapEnabledCheckBox->SetExplicitAlignment(align);
|
||||||
|
|
||||||
system_info info;
|
fSwapUsageBar = new BStatusBar("swap usage");
|
||||||
get_system_info(&info);
|
|
||||||
|
|
||||||
BString string = B_TRANSLATE("Physical memory: ");
|
BPopUpMenu* menu = new BPopUpMenu("volume menu");
|
||||||
string << byte_string((off_t)info.max_pages * B_PAGE_SIZE);
|
fVolumeMenuField = new BMenuField("volume menu field",
|
||||||
BStringView* memoryView = new BStringView("physical memory", string.String());
|
B_TRANSLATE("Use volume:"), menu);
|
||||||
|
fVolumeMenuField->SetExplicitAlignment(align);
|
||||||
|
|
||||||
string = B_TRANSLATE("Current swap file size: ");
|
BVolumeRoster roster;
|
||||||
string << byte_string(fSettings.SwapSize());
|
BVolume vol;
|
||||||
BStringView* swapfileView = new BStringView("current swap size", string.String());
|
while (roster.GetNextVolume(&vol) == B_OK) {
|
||||||
|
if (!vol.IsPersistent() || vol.IsReadOnly() || vol.IsRemovable()
|
||||||
BPopUpMenu* menu = new BPopUpMenu("invalid");
|
|| vol.IsShared())
|
||||||
|
|
||||||
// collect volumes
|
|
||||||
// TODO: listen to volume changes!
|
|
||||||
// TODO: accept dropped volumes
|
|
||||||
|
|
||||||
BVolumeRoster volumeRoster;
|
|
||||||
BVolume* volume = new BVolume();
|
|
||||||
char name[B_FILE_NAME_LENGTH];
|
|
||||||
while (volumeRoster.GetNextVolume(volume) == B_OK) {
|
|
||||||
if (!volume->IsPersistent() || volume->GetName(name) != B_OK || !name[0])
|
|
||||||
continue;
|
continue;
|
||||||
VolumeMenuItem* item = new VolumeMenuItem(name,
|
_AddVolumeMenuItem(vol.Device());
|
||||||
new BMessage(kMsgVolumeSelected), volume);
|
|
||||||
menu->AddItem(item);
|
|
||||||
volume = new BVolume();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fVolumeMenuField = new BMenuField("volumes", B_TRANSLATE("Use volume:"), menu);
|
watch_node(NULL, B_WATCH_MOUNT, this, this);
|
||||||
|
|
||||||
fSizeSlider = new SizeSlider("size slider",
|
fSizeSlider = new SizeSlider("size slider",
|
||||||
B_TRANSLATE("Requested swap file size:"), new BMessage(kMsgSliderUpdate),
|
B_TRANSLATE("Requested swap file size:"),
|
||||||
1, 1, B_WILL_DRAW | B_FRAME_EVENTS);
|
new BMessage(kMsgSliderUpdate), 0, 0, B_WILL_DRAW | B_FRAME_EVENTS);
|
||||||
fSizeSlider->SetViewColor(255, 0, 255);
|
fSizeSlider->SetViewColor(255, 0, 255);
|
||||||
|
fSizeSlider->SetExplicitAlignment(align);
|
||||||
|
|
||||||
fWarningStringView = new BStringView("", "");
|
fWarningStringView = new BStringView("warning",
|
||||||
fWarningStringView->SetAlignment(B_ALIGN_CENTER);
|
B_TRANSLATE("Changes will take effect upon reboot."));
|
||||||
|
|
||||||
view->SetLayout(new BGroupLayout(B_HORIZONTAL));
|
BBox* box = new BBox("box");
|
||||||
view->AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
|
box->SetLabel(fSwapEnabledCheckBox);
|
||||||
.AddGroup(B_HORIZONTAL)
|
|
||||||
.Add(memoryView)
|
box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, B_USE_DEFAULT_SPACING)
|
||||||
.AddGlue()
|
.Add(fSwapUsageBar)
|
||||||
.End()
|
.Add(fSwapAutomaticCheckBox)
|
||||||
.AddGroup(B_HORIZONTAL)
|
.Add(fVolumeMenuField)
|
||||||
.Add(swapfileView)
|
|
||||||
.AddGlue()
|
|
||||||
.End()
|
|
||||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
|
||||||
.AddGroup(B_HORIZONTAL)
|
|
||||||
.Add(fVolumeMenuField)
|
|
||||||
.AddGlue()
|
|
||||||
.End()
|
|
||||||
#else
|
|
||||||
.AddGlue()
|
|
||||||
#endif
|
|
||||||
.Add(fSizeSlider)
|
.Add(fSizeSlider)
|
||||||
.Add(fWarningStringView)
|
.Add(fWarningStringView)
|
||||||
.SetInsets(10, 10, 10, 10)
|
.SetInsets(10)
|
||||||
);
|
.View());
|
||||||
box->AddChild(view);
|
|
||||||
|
|
||||||
fDefaultsButton = new BButton("defaults", B_TRANSLATE("Defaults"),
|
fDefaultsButton = new BButton("defaults", B_TRANSLATE("Defaults"),
|
||||||
new BMessage(kMsgDefaults));
|
new BMessage(kMsgDefaults));
|
||||||
@ -214,32 +212,28 @@ SettingsWindow::SettingsWindow()
|
|||||||
new BMessage(kMsgRevert));
|
new BMessage(kMsgRevert));
|
||||||
fRevertButton->SetEnabled(false);
|
fRevertButton->SetEnabled(false);
|
||||||
|
|
||||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
|
||||||
AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
|
|
||||||
.Add(box)
|
.Add(box)
|
||||||
.AddGroup(B_HORIZONTAL, 10)
|
.AddGroup(B_HORIZONTAL, 10)
|
||||||
.Add(fDefaultsButton)
|
.Add(fDefaultsButton)
|
||||||
.Add(fRevertButton)
|
.Add(fRevertButton)
|
||||||
.AddGlue()
|
.AddGlue()
|
||||||
.End()
|
.End()
|
||||||
.SetInsets(10, 10, 10, 10)
|
.SetInsets(10);
|
||||||
);
|
|
||||||
|
|
||||||
BScreen screen;
|
BScreen screen;
|
||||||
BRect screenFrame = screen.Frame();
|
BRect screenFrame = screen.Frame();
|
||||||
if (!screenFrame.Contains(fSettings.WindowPosition()))
|
if (!screenFrame.Contains(fSettings.WindowPosition()))
|
||||||
CenterOnScreen();
|
CenterOnScreen();
|
||||||
else
|
|
||||||
MoveTo(fSettings.WindowPosition());
|
|
||||||
|
|
||||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
#ifdef SWAP_VOLUME_IMPLEMENTED
|
||||||
// Validate the volume specified in settings file
|
// Validate the volume specified in settings file
|
||||||
status_t result = fSettings.SwapVolume().InitCheck();
|
status_t result = fSettings.SwapVolume().InitCheck();
|
||||||
|
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
BAlert* alert = new BAlert("VirtualMemory", B_TRANSLATE(
|
BAlert* alert = new BAlert(B_TRANSLATE_SYSTEM_NAME("VirtualMemory"),
|
||||||
"The swap volume specified in the settings file is invalid.\n"
|
B_TRANSLATE("The swap volume specified in the settings file is ",
|
||||||
"You can keep the current setting or switch to the "
|
"invalid.\n You can keep the current setting or switch to the "
|
||||||
"default swap volume."),
|
"default swap volume."),
|
||||||
B_TRANSLATE("Keep"), B_TRANSLATE("Switch"), NULL,
|
B_TRANSLATE("Keep"), B_TRANSLATE("Switch"), NULL,
|
||||||
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||||
@ -255,11 +249,9 @@ SettingsWindow::SettingsWindow()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Update();
|
_Update();
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: We may want to run this at an interval
|
||||||
SettingsWindow::~SettingsWindow()
|
_UpdateSwapInfo();
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -267,36 +259,53 @@ void
|
|||||||
SettingsWindow::MessageReceived(BMessage* message)
|
SettingsWindow::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
|
case B_NODE_MONITOR:
|
||||||
|
{
|
||||||
|
int32 opcode;
|
||||||
|
if (message->FindInt32("opcode", &opcode) != B_OK)
|
||||||
|
break;
|
||||||
|
dev_t device;
|
||||||
|
if (opcode == B_DEVICE_MOUNTED
|
||||||
|
&& message->FindInt32("new device", &device) == B_OK) {
|
||||||
|
BVolume vol(device);
|
||||||
|
if (!vol.IsPersistent() || vol.IsReadOnly()
|
||||||
|
|| vol.IsRemovable() || vol.IsShared()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_AddVolumeMenuItem(device);
|
||||||
|
} else if (opcode == B_DEVICE_UNMOUNTED
|
||||||
|
&& message->FindInt32("device", &device) == B_OK) {
|
||||||
|
_RemoveVolumeMenuItem(device);
|
||||||
|
}
|
||||||
|
_Update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case kMsgRevert:
|
case kMsgRevert:
|
||||||
fSettings.RevertSwapChanges();
|
fSettings.RevertSwapSettings();
|
||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
case kMsgDefaults:
|
case kMsgDefaults:
|
||||||
_SetSwapDefaults();
|
fSettings.DefaultSwapSettings();
|
||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
case kMsgSliderUpdate:
|
case kMsgSliderUpdate:
|
||||||
fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte);
|
_RecordChoices();
|
||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
case kMsgVolumeSelected:
|
case kMsgVolumeSelected:
|
||||||
fSettings.SetSwapVolume(*((VolumeMenuItem*)fVolumeMenuField->Menu()
|
_RecordChoices();
|
||||||
->FindMarked())->Volume());
|
|
||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
case kMsgSwapEnabledUpdate:
|
case kMsgSwapEnabledUpdate:
|
||||||
{
|
{
|
||||||
int32 value;
|
if (fSwapEnabledCheckBox->Value() == 0) {
|
||||||
if (message->FindInt32("be:value", &value) != B_OK)
|
// print out warning, give the user the
|
||||||
break;
|
// time to think about it :)
|
||||||
|
|
||||||
if (value == 0) {
|
|
||||||
// print out warning, give the user the time to think about it :)
|
|
||||||
// ToDo: maybe we want to remove this possibility in the GUI
|
// ToDo: maybe we want to remove this possibility in the GUI
|
||||||
// as Be did, but I thought a proper warning could be helpful
|
// as Be did, but I thought a proper warning could be helpful
|
||||||
// (for those that want to change that anyway)
|
// (for those that want to change that anyway)
|
||||||
BAlert* alert = new BAlert("VirtualMemory",
|
BAlert* alert = new BAlert(
|
||||||
B_TRANSLATE(
|
B_TRANSLATE_SYSTEM_NAME("VirtualMemory"), B_TRANSLATE(
|
||||||
"Disabling virtual memory will have unwanted effects on "
|
"Disabling virtual memory will have unwanted effects on "
|
||||||
"system stability once the memory is used up.\n"
|
"system stability once the memory is used up.\n"
|
||||||
"Virtual memory does not affect system performance "
|
"Virtual memory does not affect system performance "
|
||||||
@ -312,7 +321,13 @@ SettingsWindow::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fSettings.SetSwapEnabled(value != 0);
|
_RecordChoices();
|
||||||
|
_Update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kMsgSwapAutomaticUpdate:
|
||||||
|
{
|
||||||
|
_RecordChoices();
|
||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -327,142 +342,155 @@ bool
|
|||||||
SettingsWindow::QuitRequested()
|
SettingsWindow::QuitRequested()
|
||||||
{
|
{
|
||||||
fSettings.SetWindowPosition(Frame().LeftTop());
|
fSettings.SetWindowPosition(Frame().LeftTop());
|
||||||
|
|
||||||
|
_RecordChoices();
|
||||||
|
fSettings.WriteWindowSettings();
|
||||||
|
fSettings.WriteSwapSettings();
|
||||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
SettingsWindow::_AddVolumeMenuItem(dev_t device)
|
||||||
|
{
|
||||||
|
if (_FindVolumeMenuItem(device) != NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
VolumeMenuItem* item = new VolumeMenuItem(device,
|
||||||
|
new BMessage(kMsgVolumeSelected));
|
||||||
|
|
||||||
|
fs_info info;
|
||||||
|
if (fs_stat_dev(device, &info) == 0) {
|
||||||
|
node_ref node;
|
||||||
|
node.device = info.dev;
|
||||||
|
node.node = info.root;
|
||||||
|
AddHandler(item);
|
||||||
|
watch_node(&node, B_WATCH_NAME, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
fVolumeMenuField->Menu()->AddItem(item);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
SettingsWindow::_RemoveVolumeMenuItem(dev_t device)
|
||||||
|
{
|
||||||
|
VolumeMenuItem* item = _FindVolumeMenuItem(device);
|
||||||
|
if (item != NULL) {
|
||||||
|
fVolumeMenuField->Menu()->RemoveItem(item);
|
||||||
|
delete item;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VolumeMenuItem*
|
||||||
|
SettingsWindow::_FindVolumeMenuItem(dev_t device)
|
||||||
|
{
|
||||||
|
VolumeMenuItem* item = NULL;
|
||||||
|
int32 count = fVolumeMenuField->Menu()->CountItems();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
item = (VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(i);
|
||||||
|
if (item->Volume().Device() == device)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsWindow::_RecordChoices()
|
||||||
|
{
|
||||||
|
fSettings.SetSwapAutomatic(fSwapAutomaticCheckBox->Value());
|
||||||
|
fSettings.SetSwapEnabled(fSwapEnabledCheckBox->Value());
|
||||||
|
fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte);
|
||||||
|
fSettings.SetSwapVolume(((VolumeMenuItem*)fVolumeMenuField
|
||||||
|
->Menu()->FindMarked())->Volume().Device());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsWindow::_Update()
|
SettingsWindow::_Update()
|
||||||
{
|
{
|
||||||
if ((fSwapEnabledCheckBox->Value() != 0) != fSettings.SwapEnabled())
|
fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled());
|
||||||
fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled());
|
fSwapAutomaticCheckBox->SetValue(fSettings.SwapAutomatic());
|
||||||
|
|
||||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
VolumeMenuItem* item = _FindVolumeMenuItem(fSettings.SwapVolume());
|
||||||
if (fVolumeMenuField->IsEnabled() != fSettings.SwapEnabled())
|
if (item != NULL) {
|
||||||
fVolumeMenuField->SetEnabled(fSettings.SwapEnabled());
|
fSizeSlider->SetEnabled(true);
|
||||||
VolumeMenuItem* selectedVolumeItem =
|
item->SetMarked(true);
|
||||||
(VolumeMenuItem*)fVolumeMenuField->Menu()->FindMarked();
|
BEntry swapFile;
|
||||||
if (selectedVolumeItem == NULL) {
|
if (gBootDev == item->Volume().Device())
|
||||||
VolumeMenuItem* currentVolumeItem;
|
swapFile.SetTo("/var/swap");
|
||||||
int32 items = fVolumeMenuField->Menu()->CountItems();
|
else {
|
||||||
for (int32 index = 0; index < items; ++index) {
|
BDirectory root;
|
||||||
currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index));
|
item->Volume().GetRootDirectory(&root);
|
||||||
if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) {
|
swapFile.SetTo(&root, "swap");
|
||||||
currentVolumeItem->SetMarked(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (*selectedVolumeItem->fVolume != fSettings.SwapVolume()) {
|
|
||||||
VolumeMenuItem* currentVolumeItem;
|
|
||||||
int32 items = fVolumeMenuField->Menu()->CountItems();
|
|
||||||
for (int32 index = 0; index < items; ++index) {
|
|
||||||
currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index));
|
|
||||||
if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) {
|
|
||||||
currentVolumeItem->SetMarked(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fWarningStringView->SetText("");
|
off_t swapFileSize = 0;
|
||||||
fLocked = false;
|
swapFile.GetSize(&swapFileSize);
|
||||||
|
|
||||||
if (fSettings.IsRevertible())
|
char sizeStr[16];
|
||||||
fWarningStringView->SetText(
|
|
||||||
B_TRANSLATE("Changes will take effect on restart!"));
|
off_t freeSpace = item->Volume().FreeBytes() + swapFileSize;
|
||||||
if (fRevertButton->IsEnabled() != fSettings.IsRevertible())
|
off_t safeSpace = freeSpace - (off_t)(0.15 * freeSpace);
|
||||||
fRevertButton->SetEnabled(fSettings.IsRevertible());
|
(safeSpace >>= 20) <<= 20;
|
||||||
|
off_t minSize = B_PAGE_SIZE + kMegaByte;
|
||||||
off_t minSize, maxSize;
|
|
||||||
if (_GetSwapFileLimits(minSize, maxSize) == B_OK) {
|
|
||||||
// round to nearest MB -- slider steps in whole MBs
|
|
||||||
(minSize >>= 20) <<= 20;
|
(minSize >>= 20) <<= 20;
|
||||||
(maxSize >>= 20) <<= 20;
|
|
||||||
BString minLabel, maxLabel;
|
BString minLabel, maxLabel;
|
||||||
minLabel << byte_string(minSize);
|
minLabel << string_for_size(minSize, sizeStr, sizeof(sizeStr));
|
||||||
maxLabel << byte_string(maxSize);
|
maxLabel << string_for_size(safeSpace, sizeStr, sizeof(sizeStr));
|
||||||
if (minLabel != fSizeSlider->MinLimitLabel()
|
|
||||||
|| maxLabel != fSizeSlider->MaxLimitLabel()) {
|
fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String());
|
||||||
fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String());
|
fSizeSlider->SetLimits(minSize / kMegaByte, safeSpace / kMegaByte);
|
||||||
fSizeSlider->SetLimits(minSize / kMegaByte, maxSize / kMegaByte);
|
|
||||||
}
|
|
||||||
} else if (fSettings.SwapEnabled()) {
|
|
||||||
fWarningStringView->SetText(
|
|
||||||
B_TRANSLATE("Insufficient space for a swap file."));
|
|
||||||
fLocked = true;
|
|
||||||
}
|
|
||||||
if (fSizeSlider->Value() != fSettings.SwapSize() / kMegaByte)
|
|
||||||
fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte);
|
fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte);
|
||||||
if (fSizeSlider->IsEnabled() != fSettings.SwapEnabled() || fLocked)
|
} else
|
||||||
{
|
fSizeSlider->SetEnabled(false);
|
||||||
fSizeSlider->SetEnabled(fSettings.SwapEnabled() && !fLocked);
|
|
||||||
fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool revertable = fSettings.IsRevertable();
|
||||||
|
if (revertable)
|
||||||
|
fWarningStringView->Show();
|
||||||
|
else
|
||||||
|
fWarningStringView->Hide();
|
||||||
|
|
||||||
status_t
|
fRevertButton->SetEnabled(revertable);
|
||||||
SettingsWindow::_GetSwapFileLimits(off_t& minSize, off_t& maxSize)
|
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
|
||||||
{
|
|
||||||
minSize = kMegaByte;
|
|
||||||
|
|
||||||
// maximum size is the free space on the current volume
|
// Automatic Swap depends on swap being enabled
|
||||||
// (minus some safety offset, depending on the disk size)
|
fSwapAutomaticCheckBox->SetEnabled(fSettings.SwapEnabled());
|
||||||
off_t freeSpace = fSettings.SwapVolume().FreeBytes();
|
|
||||||
off_t safetyFreeSpace = fSettings.SwapVolume().Capacity() / 100;
|
|
||||||
if (safetyFreeSpace > 1024 * kMegaByte)
|
|
||||||
safetyFreeSpace = 1024 * kMegaByte;
|
|
||||||
|
|
||||||
// check if there already is a page file on this disk and
|
// Manual swap settings depend on enabled swap
|
||||||
// adjust the free space accordingly
|
// and automatic swap being disabled
|
||||||
BPath path;
|
fSizeSlider->SetEnabled(fSettings.SwapEnabled()
|
||||||
if (find_directory(B_COMMON_VAR_DIRECTORY, &path, false,
|
&& !fSwapAutomaticCheckBox->Value());
|
||||||
&fSettings.SwapVolume()) == B_OK) {
|
fVolumeMenuField->SetEnabled(fSettings.SwapEnabled()
|
||||||
path.Append("swap");
|
&& !fSwapAutomaticCheckBox->Value());
|
||||||
BEntry swap(path.Path());
|
|
||||||
|
|
||||||
off_t size;
|
|
||||||
if (swap.GetSize(&size) == B_OK) {
|
|
||||||
// If swap file exists, forget about safety space;
|
|
||||||
// disk may have filled after creation of swap file.
|
|
||||||
safetyFreeSpace = 0;
|
|
||||||
freeSpace += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maxSize = freeSpace - safetyFreeSpace;
|
|
||||||
if (maxSize < minSize) {
|
|
||||||
maxSize = 0;
|
|
||||||
minSize = 0;
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsWindow::_SetSwapDefaults()
|
SettingsWindow::_UpdateSwapInfo()
|
||||||
{
|
{
|
||||||
fSettings.SetSwapEnabled(true);
|
system_memory_info memInfo = {};
|
||||||
|
__get_system_info_etc(B_MEMORY_INFO, &memInfo, sizeof(memInfo));
|
||||||
|
|
||||||
BVolumeRoster volumeRoster;
|
off_t currentSwapSize = memInfo.max_swap_space;
|
||||||
BVolume temporaryVolume;
|
off_t currentSwapUsed = (memInfo.max_swap_space - memInfo.free_swap_space);
|
||||||
volumeRoster.GetBootVolume(&temporaryVolume);
|
|
||||||
fSettings.SetSwapVolume(temporaryVolume);
|
|
||||||
|
|
||||||
system_info info;
|
char sizeStr[16];
|
||||||
get_system_info(&info);
|
BString swapSizeStr = string_for_size(currentSwapSize, sizeStr,
|
||||||
|
sizeof(sizeStr));
|
||||||
off_t defaultSize = (off_t)info.max_pages * B_PAGE_SIZE;
|
BString swapUsedStr = string_for_size(currentSwapUsed, sizeStr,
|
||||||
off_t minSize, maxSize;
|
sizeof(sizeStr));
|
||||||
_GetSwapFileLimits(minSize, maxSize);
|
|
||||||
|
BString string = swapUsedStr << " / " << swapSizeStr;
|
||||||
if (defaultSize > maxSize / 2)
|
|
||||||
defaultSize = maxSize / 2;
|
fSwapUsageBar->SetMaxValue(currentSwapSize / kMegaByte);
|
||||||
|
fSwapUsageBar->Update(currentSwapUsed / kMegaByte,
|
||||||
fSettings.SetSwapSize(defaultSize);
|
B_TRANSLATE("Current Swap:"), string.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,43 +1,88 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright 2010-2012 Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hamish Morrison, hamish@lavabit.com
|
||||||
|
* Alexander von Gluck, kallisti5@unixzen.com
|
||||||
*/
|
*/
|
||||||
#ifndef SETTINGS_WINDOW_H
|
#ifndef SETTINGS_WINDOW_H
|
||||||
#define SETTINGS_WINDOW_H
|
#define SETTINGS_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Slider.h>
|
||||||
|
#include <StatusBar.h>
|
||||||
|
#include <Volume.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
|
|
||||||
class BStringView;
|
class BStringView;
|
||||||
class BCheckBox;
|
class BCheckBox;
|
||||||
class BSlider;
|
class BSlider;
|
||||||
class BButton;
|
class BButton;
|
||||||
class BMenuField;
|
class BMenuField;
|
||||||
|
|
||||||
|
|
||||||
|
class SizeSlider : public BSlider {
|
||||||
|
public:
|
||||||
|
SizeSlider(const char* name, const char* label,
|
||||||
|
BMessage* message, int32 min, int32 max,
|
||||||
|
uint32 flags);
|
||||||
|
virtual ~SizeSlider() {};
|
||||||
|
|
||||||
|
virtual const char* UpdateText() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable char fText[128];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeMenuItem : public BMenuItem, public BHandler {
|
||||||
|
public:
|
||||||
|
VolumeMenuItem(BVolume volume, BMessage* message);
|
||||||
|
virtual ~VolumeMenuItem() {}
|
||||||
|
|
||||||
|
virtual BVolume Volume() { return fVolume; }
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual void GenerateLabel();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BVolume fVolume;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class SettingsWindow : public BWindow {
|
class SettingsWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
SettingsWindow();
|
SettingsWindow();
|
||||||
virtual ~SettingsWindow();
|
virtual ~SettingsWindow() {};
|
||||||
|
|
||||||
virtual bool QuitRequested();
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual bool QuitRequested();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Update();
|
status_t _AddVolumeMenuItem(dev_t device);
|
||||||
status_t _GetSwapFileLimits(off_t& minSize, off_t& maxSize);
|
status_t _RemoveVolumeMenuItem(dev_t device);
|
||||||
void _SetSwapDefaults();
|
VolumeMenuItem* _FindVolumeMenuItem(dev_t device);
|
||||||
|
|
||||||
BCheckBox* fSwapEnabledCheckBox;
|
void _RecordChoices();
|
||||||
BSlider* fSizeSlider;
|
void _Update();
|
||||||
BButton* fDefaultsButton;
|
void _UpdateSwapInfo();
|
||||||
BButton* fRevertButton;
|
|
||||||
BStringView* fWarningStringView;
|
BCheckBox* fSwapEnabledCheckBox;
|
||||||
BMenuField* fVolumeMenuField;
|
BCheckBox* fSwapAutomaticCheckBox;
|
||||||
Settings fSettings;
|
BSlider* fSizeSlider;
|
||||||
|
BButton* fDefaultsButton;
|
||||||
bool fLocked;
|
BButton* fRevertButton;
|
||||||
|
BStringView* fWarningStringView;
|
||||||
|
BMenuField* fVolumeMenuField;
|
||||||
|
BStatusBar* fSwapUsageBar;
|
||||||
|
Settings fSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SETTINGS_WINDOW_H */
|
#endif /* SETTINGS_WINDOW_H */
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "SettingsWindow.h"
|
#include "SettingsWindow.h"
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
|
#include <Catalog.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,24 +7,15 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Catalog.h>
|
|
||||||
#include <Locale.h>
|
|
||||||
|
|
||||||
class VMSettings;
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualMemory : public BApplication {
|
class VirtualMemory : public BApplication {
|
||||||
public:
|
public:
|
||||||
VirtualMemory();
|
VirtualMemory();
|
||||||
virtual ~VirtualMemory();
|
virtual ~VirtualMemory();
|
||||||
|
|
||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
virtual void AboutRequested();
|
virtual void AboutRequested();
|
||||||
|
|
||||||
private:
|
|
||||||
void GetCurrentSettings(bool& enabled, off_t& size);
|
|
||||||
|
|
||||||
VMSettings *fSettings;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* VIRTUAL_MEMORY_H */
|
#endif /* VIRTUAL_MEMORY_H */
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "acpi.h"
|
#include "acpi.h"
|
||||||
#include "hpet.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define NO_SMP 0
|
#define NO_SMP 0
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
|
.section .init
|
||||||
.globl _start
|
.globl _start
|
||||||
_start:
|
_start:
|
||||||
b jmp_loader
|
b jmp_loader
|
||||||
|
|
||||||
.balign 0x8000, 0
|
.section .text
|
||||||
|
/* Start "safe" code area.
|
||||||
|
* 0x4000 minimum safe area
|
||||||
|
* defined in boot_loader_raspberrypi_arm.ld
|
||||||
|
*/
|
||||||
|
|
||||||
jmp_loader:
|
jmp_loader:
|
||||||
/* Start Haiku loader */
|
/* Start Haiku loader */
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012, Alexander von Gluck IV, kallisti5@unixzen.com.
|
|
||||||
* Copyright 2011, Hamish Morrison, hamish@lavabit.com.
|
|
||||||
* Copyright 2008, Zhao Shuai, upczhsh@163.com.
|
* Copyright 2008, Zhao Shuai, upczhsh@163.com.
|
||||||
* Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||||
@ -8,6 +6,13 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
* Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2012 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Hamish Morrison, hamish@lavabit.com
|
||||||
|
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -1456,52 +1461,59 @@ swap_init_post_modules()
|
|||||||
|
|
||||||
if (enabled != NULL) {
|
if (enabled != NULL) {
|
||||||
swapEnabled = get_driver_boolean_parameter(settings, "vm",
|
swapEnabled = get_driver_boolean_parameter(settings, "vm",
|
||||||
false, false);
|
true, false);
|
||||||
|
swapAutomatic = get_driver_boolean_parameter(settings, "swap_auto",
|
||||||
|
true, false);
|
||||||
|
|
||||||
const char* size = get_driver_parameter(settings, "swap_size",
|
if (swapEnabled && !swapAutomatic) {
|
||||||
NULL, NULL);
|
const char* size = get_driver_parameter(settings, "swap_size",
|
||||||
const char* volume = get_driver_parameter(settings,
|
NULL, NULL);
|
||||||
"swap_volume_name", NULL, NULL);
|
const char* volume = get_driver_parameter(settings,
|
||||||
const char* device = get_driver_parameter(settings,
|
"swap_volume_name", NULL, NULL);
|
||||||
"swap_volume_device", NULL, NULL);
|
const char* device = get_driver_parameter(settings,
|
||||||
const char* filesystem = get_driver_parameter(settings,
|
"swap_volume_device", NULL, NULL);
|
||||||
"swap_volume_filesystem", NULL, NULL);
|
const char* filesystem = get_driver_parameter(settings,
|
||||||
const char* capacity = get_driver_parameter(settings,
|
"swap_volume_filesystem", NULL, NULL);
|
||||||
"swap_volume_capacity", NULL, NULL);
|
const char* capacity = get_driver_parameter(settings,
|
||||||
|
"swap_volume_capacity", NULL, NULL);
|
||||||
|
|
||||||
if (size != NULL && device != NULL && volume != NULL
|
if (size != NULL && device != NULL && volume != NULL
|
||||||
&& filesystem != NULL && capacity != NULL) {
|
&& filesystem != NULL && capacity != NULL) {
|
||||||
// User specified a size / volume
|
// User specified a size / volume that seems valid
|
||||||
swapAutomatic = false;
|
swapAutomatic = false;
|
||||||
swapSize = atoll(size);
|
swapSize = atoll(size);
|
||||||
strncpy(selectedVolume.name, volume,
|
strncpy(selectedVolume.name, volume,
|
||||||
sizeof(selectedVolume.name));
|
sizeof(selectedVolume.name));
|
||||||
strncpy(selectedVolume.device, device,
|
strncpy(selectedVolume.device, device,
|
||||||
sizeof(selectedVolume.device));
|
sizeof(selectedVolume.device));
|
||||||
strncpy(selectedVolume.filesystem, filesystem,
|
strncpy(selectedVolume.filesystem, filesystem,
|
||||||
sizeof(selectedVolume.filesystem));
|
sizeof(selectedVolume.filesystem));
|
||||||
selectedVolume.capacity = atoll(capacity);
|
selectedVolume.capacity = atoll(capacity);
|
||||||
} else if (size != NULL) {
|
} else {
|
||||||
// Older file format, no location information (assume /var/swap)
|
// Something isn't right with swap config, go auto
|
||||||
swapAutomatic = false;
|
swapAutomatic = true;
|
||||||
swapSize = atoll(size);
|
dprintf("%s: virtual_memory configuration is invalid, "
|
||||||
swapDeviceID = gBootDevice;
|
"using automatic swap\n", __func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
unload_driver_settings(settings);
|
||||||
}
|
}
|
||||||
unload_driver_settings(settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapAutomatic) {
|
if (swapAutomatic) {
|
||||||
swapEnabled = true;
|
|
||||||
swapSize = (off_t)vm_page_num_pages() * B_PAGE_SIZE;
|
swapSize = (off_t)vm_page_num_pages() * B_PAGE_SIZE;
|
||||||
if (swapSize <= (1024 * 1024 * 1024)) {
|
if (swapSize <= (1024 * 1024 * 1024)) {
|
||||||
// Memory under 1GB? double the swap
|
// Memory under 1GB? double the swap
|
||||||
swapSize *= 2;
|
swapSize *= 2;
|
||||||
}
|
}
|
||||||
|
// Automatic swap defaults to the boot device
|
||||||
|
swapDeviceID = gBootDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!swapEnabled || swapSize < B_PAGE_SIZE)
|
if (!swapEnabled || swapSize < B_PAGE_SIZE) {
|
||||||
|
dprintf("%s: virtual_memory is disabled\n", __func__);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!swapAutomatic && swapDeviceID < 0) {
|
if (!swapAutomatic && swapDeviceID < 0) {
|
||||||
// If user-specified swap, and no swap device has been chosen yet...
|
// If user-specified swap, and no swap device has been chosen yet...
|
||||||
|
@ -11,10 +11,22 @@ UND_STACK_SIZE = 0;
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Raspberry Pi boot logic:
|
||||||
|
* start.elf loads the kernel specified in config.txt
|
||||||
|
* if a dtb exists, it is loaded at 0x100 and the kernel at 0x8000
|
||||||
|
* else if disable_commandline_tags true, set kernel load address to 0x0
|
||||||
|
* else load kernel at 0x8000 and put atags at 0x100
|
||||||
|
*/
|
||||||
|
|
||||||
. = BOARD_LOADER_BASE;
|
. = BOARD_LOADER_BASE;
|
||||||
|
|
||||||
/* text/read-only data */
|
/* .init is a stub that jumps to code at .text */
|
||||||
.text : {
|
.init : {
|
||||||
|
*(.init)
|
||||||
|
}
|
||||||
|
|
||||||
|
.text 0x8000 : {
|
||||||
CREATE_OBJECT_SYMBOLS
|
CREATE_OBJECT_SYMBOLS
|
||||||
*(.text .text.* .gnu.linkonce.t.*)
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
*(.plt)
|
*(.plt)
|
||||||
|
Loading…
Reference in New Issue
Block a user