Merge branch 'master' into sam460ex

This commit is contained in:
François Revol 2012-09-10 11:14:31 +02:00
commit 95540b8a19
19 changed files with 851 additions and 608 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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", &parameter, NULL); AcpiEvaluateObject(NULL, "\\_PIC", &parameter, 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));

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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
; ;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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());
} }

View File

@ -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 */

View File

@ -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>

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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...

View File

@ -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)