diff --git a/headers/private/kernel/arch/vm.h b/headers/private/kernel/arch/vm.h index 79ade89e7e..9236e4055f 100644 --- a/headers/private/kernel/arch/vm.h +++ b/headers/private/kernel/arch/vm.h @@ -24,7 +24,7 @@ void arch_vm_aspace_swap(vm_address_space *aspace); bool arch_vm_supports_protection(uint32 protection); void arch_vm_init_area(vm_area *area); -status_t arch_vm_set_memory_type(vm_area *area, uint32 type); +status_t arch_vm_set_memory_type(vm_area *area, addr_t physicalBase, uint32 type); void arch_vm_unset_memory_type(vm_area *area); #ifdef __cplusplus diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index 2ba0b6d04b..36656399e2 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -14,14 +14,23 @@ // MSR registers (possibly Intel specific) -#define IA32_MSR_APIC_BASE 0x1b +#define IA32_MSR_APIC_BASE 0x1b + +#define IA32_MSR_MTRR_CAPABILITIES 0xfe +#define IA32_MSR_MTRR_DEFAULT_TYPE 0x2ff +#define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200 +#define IA32_MSR_MTRR_PHYSICAL_MASK_0 0x201 typedef struct x86_cpu_module_info { module_info info; uint32 (*count_mtrrs)(void); - status_t (*set_mtrr)(uint32 index, addr_t base, addr_t length, uint32 type); - status_t (*unset_mtrr)(uint32 index); + status_t (*enable_mtrrs)(void); + void (*disable_mtrrs)(void); + + void (*set_mtrr)(uint32 index, addr_t base, addr_t length, uint32 type); + status_t (*get_mtrr)(uint32 index, addr_t *_base, addr_t *_length, + uint32 *_type); } x86_cpu_module_info; @@ -91,8 +100,10 @@ uint64 x86_read_msr(uint32 registerNumber); void x86_write_msr(uint32 registerNumber, uint64 value); void x86_set_task_gate(int32 n, int32 segment); uint32 x86_count_mtrrs(void); +status_t x86_enable_mtrrs(void); +status_t x86_disable_mtrrs(void); status_t x86_set_mtrr(uint32 index, addr_t base, addr_t length, uint32 type); -status_t x86_unset_mtrr(uint32 index); +status_t x86_get_mtrr(uint32 index, addr_t *_base, addr_t *_length, uint32 *_type); struct tss *x86_get_main_tss(void); #define read_ebp(value) \ diff --git a/headers/private/kernel/debug.h b/headers/private/kernel/debug.h index 81a1c7c326..e0b4533494 100644 --- a/headers/private/kernel/debug.h +++ b/headers/private/kernel/debug.h @@ -30,6 +30,7 @@ extern "C" { extern status_t debug_init(struct kernel_args *args); extern status_t debug_init_post_vm(struct kernel_args *args); +extern status_t debug_init_post_modules(struct kernel_args *args); extern void debug_early_boot_message(const char *string); extern void debug_puts(const char *s); extern bool debug_debugger_running(void); diff --git a/headers/private/kernel/frame_buffer_console.h b/headers/private/kernel/frame_buffer_console.h index d4bf95d403..4c80a4c7d6 100644 --- a/headers/private/kernel/frame_buffer_console.h +++ b/headers/private/kernel/frame_buffer_console.h @@ -28,6 +28,7 @@ extern "C" { bool frame_buffer_console_available(void); status_t frame_buffer_console_init(struct kernel_args *args); +status_t frame_buffer_console_init_post_modules(struct kernel_args *args); status_t _user_frame_buffer_update(addr_t baseAddress, int32 width, int32 height, int32 depth, int32 bytesPerRow); diff --git a/headers/private/kernel/vm.h b/headers/private/kernel/vm.h index 172bd6dd80..9f0529ee03 100644 --- a/headers/private/kernel/vm.h +++ b/headers/private/kernel/vm.h @@ -67,6 +67,8 @@ area_id vm_clone_area(aspace_id aid, const char *name, void **address, status_t vm_delete_area(aspace_id aid, area_id id); status_t vm_create_vnode_cache(void *vnode, vm_cache_ref **_cacheRef); +status_t vm_set_area_memory_type(area_id id, addr_t physicalBase, uint32 type); + status_t vm_get_page_mapping(aspace_id aid, addr_t vaddr, addr_t *paddr); status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, int flags); status_t vm_put_physical_page(addr_t vaddr); diff --git a/src/add-ons/kernel/cpu/x86/Jamfile b/src/add-ons/kernel/cpu/x86/Jamfile index 75f0d91224..1aad1d564f 100644 --- a/src/add-ons/kernel/cpu/x86/Jamfile +++ b/src/add-ons/kernel/cpu/x86/Jamfile @@ -5,6 +5,6 @@ UsePrivateHeaders kernel ; KernelAddon generic_x86 : kernel cpu : generic_x86.cpp intel.cpp - amd.cpp - via.cpp +# amd.cpp +# via.cpp ; diff --git a/src/add-ons/kernel/cpu/x86/generic_x86.cpp b/src/add-ons/kernel/cpu/x86/generic_x86.cpp index 34d73ac30e..d782d6a8ba 100644 --- a/src/add-ons/kernel/cpu/x86/generic_x86.cpp +++ b/src/add-ons/kernel/cpu/x86/generic_x86.cpp @@ -12,9 +12,9 @@ #include "via.h" -module_info *gModules[] = { +module_info *modules[] = { (module_info *)&gIntelModule, - (module_info *)&gAMDModule, - (module_info *)&gVIAModule, +// (module_info *)&gAMDModule, +// (module_info *)&gVIAModule, NULL }; diff --git a/src/add-ons/kernel/cpu/x86/intel.cpp b/src/add-ons/kernel/cpu/x86/intel.cpp index daeb272f74..0054ec3380 100644 --- a/src/add-ons/kernel/cpu/x86/intel.cpp +++ b/src/add-ons/kernel/cpu/x86/intel.cpp @@ -9,24 +9,95 @@ #include "intel.h" +#include +#include +#include + + +#define IA32_MTRR_FEATURE (1UL << 12) +#define IA32_MTRR_ENABLE (1UL << 11) +#define IA32_MTRR_ENABLE_FIXED (1UL << 10) +#define IA32_MTRR_VALID_RANGE (1UL << 11) + +struct mtrr_capabilities { + mtrr_capabilities(uint64 value) { *(uint64 *)this = value; } + + uint64 variable_ranges : 8; + uint64 supports_fixed : 1; + uint64 _reserved0 : 1; + uint64 supports_write_combined : 1; + uint64 _reserved1 : 53; +}; + static uint32 intel_count_mtrrs(void) { - return 0; + cpuid_info cpuInfo; + if (get_cpuid(&cpuInfo, 1, 0) != B_OK + || (cpuInfo.eax_1.features & IA32_MTRR_FEATURE) == 0) + return 0; + + mtrr_capabilities capabilities(x86_read_msr(IA32_MSR_MTRR_CAPABILITIES)); + return capabilities.variable_ranges; } static status_t -intel_set_mtrr(uint32 index, addr_t base, addr_t length, uint32 type) +intel_enable_mtrrs(void) { + cpuid_info cpuInfo; + if (get_cpuid(&cpuInfo, 1, 0) != B_OK + || (cpuInfo.eax_1.features & IA32_MTRR_FEATURE) == 0) + return B_NOT_SUPPORTED; + + x86_write_msr(IA32_MSR_MTRR_DEFAULT_TYPE, + x86_read_msr(IA32_MSR_MTRR_DEFAULT_TYPE) | IA32_MTRR_ENABLE); + return B_OK; } -static status_t -intel_unset_mtrr(uint32 index) +static void +intel_disable_mtrrs(void) { + x86_write_msr(IA32_MSR_MTRR_DEFAULT_TYPE, + x86_read_msr(IA32_MSR_MTRR_DEFAULT_TYPE) & ~IA32_MTRR_ENABLE); +} + + +static void +intel_set_mtrr(uint32 index, addr_t base, addr_t length, uint32 type) +{ + if (base != 0 && length != 0) { + // enable MTRR + + x86_write_msr(IA32_MSR_MTRR_PHYSICAL_BASE_0 + index, + (base & ~(B_PAGE_SIZE - 1)) | type); + x86_write_msr(IA32_MSR_MTRR_PHYSICAL_MASK_0 + index, + (length & ~(B_PAGE_SIZE - 1)) | IA32_MTRR_VALID_RANGE); + } else { + // disable MTRR + + x86_write_msr(IA32_MSR_MTRR_PHYSICAL_MASK_0 + index, 0); + x86_write_msr(IA32_MSR_MTRR_PHYSICAL_BASE_0 + index, 0); + } +} + + +static status_t +intel_get_mtrr(uint32 index, addr_t *_base, addr_t *_length, uint32 *_type) +{ + uint64 base = x86_read_msr(IA32_MSR_MTRR_PHYSICAL_BASE_0 + index); + uint64 mask = x86_read_msr(IA32_MSR_MTRR_PHYSICAL_MASK_0 + index); + + if ((mask & IA32_MTRR_VALID_RANGE) == 0) + return B_ERROR; + + *_base = base & ~(B_PAGE_SIZE - 1); + *_length = mask & ~(B_PAGE_SIZE - 1); + *_type = base & 0xff; + return B_OK; } @@ -38,10 +109,28 @@ intel_init(void) if (get_system_info(&info) != B_OK) return B_ERROR; - if ((info.cpu_type & B_CPU_x86_VENDOR_MASK) != B_CPU_INTEL_x86) + if ((info.cpu_type & B_CPU_x86_VENDOR_MASK) != B_CPU_INTEL_x86 + || (info.cpu_type & B_CPU_x86_VENDOR_MASK) != B_CPU_AMD_x86) return B_ERROR; - return B_OK; + if (x86_read_msr(IA32_MSR_MTRR_DEFAULT_TYPE) & IA32_MTRR_ENABLE) + dprintf("MTRR enabled\n"); + else + dprintf("MTRR disabled\n"); + + for (uint32 i = 0; i < intel_count_mtrrs(); i++) { + addr_t base; + addr_t length; + uint32 type; + if (intel_get_mtrr(i, &base, &length, &type) == B_OK) + dprintf(" %ld: %p, %p, %ld\n", i, (void *)base, (void *)length, type); + else + dprintf(" %ld: empty\n", i); + } + +// don't open it just now + return B_ERROR; +// return B_OK; } @@ -74,6 +163,9 @@ x86_cpu_module_info gIntelModule = { }, intel_count_mtrrs, + intel_enable_mtrrs, + intel_disable_mtrrs, + intel_set_mtrr, - intel_unset_mtrr, + intel_get_mtrr, }; diff --git a/src/system/kernel/arch/ppc/arch_vm.cpp b/src/system/kernel/arch/ppc/arch_vm.cpp index 4e7865ca13..bb44c50c3a 100644 --- a/src/system/kernel/arch/ppc/arch_vm.cpp +++ b/src/system/kernel/arch/ppc/arch_vm.cpp @@ -126,7 +126,7 @@ arch_vm_unset_memory_type(vm_area *area) status_t -arch_vm_set_memory_type(vm_area *area, uint32 type) +arch_vm_set_memory_type(vm_area *area, addr_t physicalBase, uint32 type) { if (type == 0) return B_OK; diff --git a/src/system/kernel/arch/x86/arch_cpu.c b/src/system/kernel/arch/x86/arch_cpu.c index 8f1258f3fd..7cca130e47 100644 --- a/src/system/kernel/arch/x86/arch_cpu.c +++ b/src/system/kernel/arch/x86/arch_cpu.c @@ -103,22 +103,44 @@ x86_count_mtrrs(void) status_t -x86_set_mtrr(uint32 index, addr_t base, addr_t length, uint32 type) +x86_enable_mtrrs(void) { if (load_cpu_module() == NULL) - return B_UNSUPPORTED; + return B_NOT_SUPPORTED; - return sCpuModule->set_mtrr(index, base, length, type); + return sCpuModule->enable_mtrrs(); } status_t -x86_unset_mtrr(uint32 index) +x86_disable_mtrrs(void) { if (load_cpu_module() == NULL) - return B_UNSUPPORTED; + return B_NOT_SUPPORTED; - return sCpuModule->unset_mtrr(index); + sCpuModule->disable_mtrrs(); + return B_OK; +} + + +status_t +x86_set_mtrr(uint32 index, addr_t base, addr_t length, uint32 type) +{ + if (load_cpu_module() == NULL) + return B_NOT_SUPPORTED; + + sCpuModule->set_mtrr(index, base, length, type); + return B_OK; +} + + +status_t +x86_get_mtrr(uint32 index, addr_t *_base, addr_t *_length, uint32 *_type) +{ + if (load_cpu_module() == NULL) + return B_NOT_SUPPORTED; + + return sCpuModule->get_mtrr(index, _base, _length, _type); } diff --git a/src/system/kernel/arch/x86/arch_vm.c b/src/system/kernel/arch/x86/arch_vm.c index c5d78818d6..278b584aba 100644 --- a/src/system/kernel/arch/x86/arch_vm.c +++ b/src/system/kernel/arch/x86/arch_vm.c @@ -30,26 +30,27 @@ #endif -static uint32 *sMTRRBitmap; +struct set_mtrr_parameter { + int32 index; + addr_t base; + addr_t length; + uint8 type; +}; + + +static uint32 sMTRRBitmap; static int32 sMTRRCount; static spinlock sMTRRLock; static status_t -init_mtrr_bitmap(void) +init_mtrr(void) { - if (sMTRRBitmap != NULL) - return B_OK; - sMTRRCount = x86_count_mtrrs(); if (sMTRRCount == 0) - return B_UNSUPPORTED; + return B_NOT_SUPPORTED; - sMTRRBitmap = malloc(sMTRRCount / 8); - if (sMTRRBitmap == NULL) - return B_NO_MEMORY; - - memset(sMTRRBitmap, 0, sMTRRCount / 8); + sMTRRBitmap = 0; return B_OK; } @@ -57,28 +58,22 @@ init_mtrr_bitmap(void) static int32 allocate_mtrr(void) { - int32 count = sMTRRCount / 32; - int32 i, j; + int32 index; cpu_status state = disable_interrupts(); acquire_spinlock(&sMTRRLock); - for (i = 0; i < count; i++) { - if (sMTRRBitmap[i] == 0xffffffff) + // find free bit + + for (index = 0; index < 32; index++) { + if (sMTRRBitmap & (1UL << index)) continue; - // find free bit + sMTRRBitmap |= 1UL << index; - for (j = 0; j < 32; j++) { - if (sMTRRBitmap[i] & (1UL << j)) - continue; - - sMTRRBitmap[i] |= 1UL << j; - - release_spinlock(&sMTRRLock); - restore_interrupts(state); - return i * 32 + j; - } + release_spinlock(&sMTRRLock); + restore_interrupts(state); + return index; } release_spinlock(&sMTRRLock); @@ -91,19 +86,38 @@ allocate_mtrr(void) static void free_mtrr(int32 index) { - int32 i = index / 32; - int32 j = index - i * 32; - cpu_status state = disable_interrupts(); acquire_spinlock(&sMTRRLock); - sMTRRBitmap[i] &= ~(1UL << j); + sMTRRBitmap &= ~(1UL << index); release_spinlock(&sMTRRLock); restore_interrupts(state); } +static void +unset_mtrr(void *_index, int cpu) +{ + int32 index = (int32)_index; + + x86_set_mtrr(index, 0, 0, 0); +} + + +static void +set_mtrr(void *_parameter, int cpu) +{ + struct set_mtrr_parameter *parameter = (struct set_mtrr_parameter *)_parameter; + + x86_set_mtrr(parameter->index, parameter->base, parameter->length, + parameter->type); +} + + +// #pragma mark - + + status_t arch_vm_init(kernel_args *args) { @@ -182,58 +196,58 @@ arch_vm_unset_memory_type(vm_area *area) if (area->memory_type.type == 0) return; - x86_unset_mtrr(area->memory_type.index); + call_all_cpus(&unset_mtrr, (void *)(int32)area->memory_type.index); free_mtrr(area->memory_type.index); } status_t -arch_vm_set_memory_type(vm_area *area, uint32 type) +arch_vm_set_memory_type(vm_area *area, addr_t physicalBase, uint32 type) { - status_t status; - int32 index; + struct set_mtrr_parameter parameter; if (type == 0) return B_OK; switch (type) { case B_MTR_UC: // uncacheable - type = 0; + parameter.type = 0; break; case B_MTR_WC: // write combining - type = 1; + parameter.type = 1; break; case B_MTR_WT: // write through - type = 4; + parameter.type = 4; break; case B_MTR_WP: // write protected - type = 5; + parameter.type = 5; break; case B_MTR_WB: // write back - type = 6; + parameter.type = 6; break; default: return B_BAD_VALUE; } - if (sMTRRBitmap == NULL) { - status = init_mtrr_bitmap(); + if (sMTRRCount == 0) { + status_t status = init_mtrr(); if (status < B_OK) return status; } - index = allocate_mtrr(); - if (index < 0) + parameter.index = allocate_mtrr(); + if (parameter.index < 0) return B_ERROR; - status = x86_set_mtrr(index, area->base, area->size, type); - if (status != B_OK) { - area->memory_type.type = (uint16)type; - area->memory_type.index = (uint16)index; - } else - free_mtrr(index); + parameter.base = physicalBase; + parameter.length = area->size; - dprintf("memory type: %u, index: %ld\n", area->memory_type.type, index); - return status; + call_all_cpus(&set_mtrr, ¶meter); + + area->memory_type.type = parameter.type; + area->memory_type.index = (uint16)parameter.index; + + dprintf("memory type: %u, index: %ld\n", area->memory_type.type, parameter.index); + return B_OK; } diff --git a/src/system/kernel/debug/debug.c b/src/system/kernel/debug/debug.c index 17d5a1a2a6..e33fd70904 100644 --- a/src/system/kernel/debug/debug.c +++ b/src/system/kernel/debug/debug.c @@ -439,6 +439,13 @@ debug_init_post_vm(kernel_args *args) } +status_t +debug_init_post_modules(struct kernel_args *args) +{ + return frame_buffer_console_init_post_modules(args); +} + + // #pragma mark - public API diff --git a/src/system/kernel/debug/frame_buffer_console.cpp b/src/system/kernel/debug/frame_buffer_console.cpp index 4ff6f5a74c..cc1976c566 100644 --- a/src/system/kernel/debug/frame_buffer_console.cpp +++ b/src/system/kernel/debug/frame_buffer_console.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -110,7 +111,7 @@ render_glyph(int32 x, int32 y, uint8 glyph, uint8 attr) + x * CHAR_WIDTH * sConsole.bytes_per_pixel); uint8 *color = get_palette_entry(foreground_color(attr)); uint8 *backgroundColor = get_palette_entry(background_color(attr)); - + for (y = 0; y < CHAR_HEIGHT; y++) { uint8 bits = FONT[CHAR_HEIGHT * glyph + y]; for (x = 0; x < CHAR_WIDTH; x++) { @@ -122,7 +123,7 @@ render_glyph(int32 x, int32 y, uint8 glyph, uint8 attr) } bits >>= 1; } - + base += sConsole.bytes_per_row; } } else { @@ -426,6 +427,19 @@ frame_buffer_console_init(kernel_args *args) } +status_t +frame_buffer_console_init_post_modules(kernel_args *args) +{ + if (sConsole.frame_buffer == NULL) + return B_OK; + + // try to set frame buffer memory to write combined + + return vm_set_area_memory_type(sConsole.area, + args->frame_buffer.physical_buffer.start, B_MTR_WC); +} + + // #pragma mark - diff --git a/src/system/kernel/int.c b/src/system/kernel/int.c index 87639bf87e..05b42e296f 100644 --- a/src/system/kernel/int.c +++ b/src/system/kernel/int.c @@ -225,6 +225,22 @@ int_io_interrupt_handler(int vector) int status = B_UNHANDLED_INTERRUPT; struct io_handler *io; +#if 0 +{ + static int low[2]; + static int high[2]; + static int counter; + int32 cpu = smp_get_current_cpu(); + + if (vector > 0xf0 - 32) + high[cpu]++; + else + low[cpu]++; + dprintf("got vector %d at CPU %ld\n", vector, cpu); + //if ((counter++ % 10) == 0) + dprintf("ints: %d/%d (high: %d/%d)\n", low[0], low[1], high[0], high[1]); +} +#endif acquire_spinlock(&io_vectors[vector].vector_lock); // The list can be empty at this place diff --git a/src/system/kernel/main.c b/src/system/kernel/main.c index 8ad5d338af..439bd8434c 100644 --- a/src/system/kernel/main.c +++ b/src/system/kernel/main.c @@ -215,27 +215,8 @@ main2(void *unused) TRACE(("Mount boot file system\n")); vfs_mount_boot_file_system(&sKernelArgs); - //module_test(); -#if 0 - // XXX remove - vfs_test(); -#endif -#if 0 - // XXX remove - thread_test(); -#endif -#if 0 - vm_test(); -#endif -#if 0 - panic("debugger_test\n"); -#endif -#if 0 - cbuf_test(); -#endif -#if 0 - port_test(); -#endif + debug_init_post_modules(&sKernelArgs); + // start the init process { const char *shellArgs[] = {"/bin/sh", "/boot/beos/system/boot/Bootscript", NULL}; diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 2e54307d18..92a074df30 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -935,20 +935,22 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address, area_id -vm_map_physical_memory(aspace_id aid, const char *name, void **_address, - uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr) +vm_map_physical_memory(aspace_id areaID, const char *name, void **_address, + uint32 addressSpec, addr_t size, uint32 protection, + addr_t physicalAddress) { vm_area *area; vm_cache *cache; - vm_cache_ref *cache_ref; + vm_cache_ref *cacheRef; vm_store *store; - addr_t map_offset; + addr_t mapOffset; status_t status; - vm_address_space *aspace = vm_get_aspace_by_id(aid); + vm_address_space *aspace = vm_get_aspace_by_id(areaID); TRACE(("vm_map_physical_memory(aspace = %ld, \"%s\", virtual = %p, spec = %ld," " size = %lu, protection = %ld, phys = %p)\n", - aid, name, _address, addressSpec, size, protection, (void *)phys_addr)); + areaID, name, _address, addressSpec, size, protection, + (void *)physicalAddress)); if (!arch_vm_supports_protection(protection)) return B_NOT_SUPPORTED; @@ -958,33 +960,36 @@ vm_map_physical_memory(aspace_id aid, const char *name, void **_address, // if the physical address is somewhat inside a page, // move the actual area down to align on a page boundary - map_offset = phys_addr % B_PAGE_SIZE; - size += map_offset; - phys_addr -= map_offset; + mapOffset = physicalAddress % B_PAGE_SIZE; + size += mapOffset; + physicalAddress -= mapOffset; size = PAGE_ALIGN(size); // create an device store object - store = vm_store_create_device(phys_addr); + // TODO: panic??? + store = vm_store_create_device(physicalAddress); if (store == NULL) panic("vm_map_physical_memory: vm_store_create_device returned NULL"); cache = vm_cache_create(store); if (cache == NULL) panic("vm_map_physical_memory: vm_cache_create returned NULL"); - cache_ref = vm_cache_ref_create(cache); - if (cache_ref == NULL) + cacheRef = vm_cache_ref_create(cache); + if (cacheRef == NULL) panic("vm_map_physical_memory: vm_cache_ref_create returned NULL"); + // tell the page scanner to skip over this area, it's pages are special cache->scan_skip = 1; - vm_cache_acquire_ref(cache_ref, true); + vm_cache_acquire_ref(cacheRef, true); status = map_backing_store(aspace, store, _address, 0, size, addressSpec & ~B_MTR_MASK, 0, protection, REGION_NO_PRIVATE_MAP, &area, name); - vm_cache_release_ref(cache_ref); + vm_cache_release_ref(cacheRef); if (status >= B_OK && (addressSpec & B_MTR_MASK) != 0) { // set requested memory type - status = arch_vm_set_memory_type(area, addressSpec & B_MTR_MASK); + status = arch_vm_set_memory_type(area, physicalAddress, + addressSpec & B_MTR_MASK); if (status < B_OK) vm_put_area(area); } @@ -1003,7 +1008,7 @@ vm_map_physical_memory(aspace_id aid, const char *name, void **_address, // modify the pointer returned to be offset back into the new area // the same way the physical address in was offset - *_address = (void *)((addr_t)*_address + map_offset); + *_address = (void *)((addr_t)*_address + mapOffset); return area->id; } @@ -2750,6 +2755,25 @@ vm_try_reserve_memory(size_t amount) } +status_t +vm_set_area_memory_type(area_id id, addr_t physicalBase, uint32 type) +{ + vm_area *area = vm_get_area(id); + if (area == NULL) + return B_BAD_VALUE; + + status_t status = arch_vm_set_memory_type(area, physicalBase, type); + if (status < B_OK) + goto out; + + arch_cpu_invalidate_TLB_range(area->base, area->size); + +out: + vm_put_area(area); + return status; +} + + /** This function enforces some protection properties: * - if B_WRITE_AREA is set, B_WRITE_KERNEL_AREA is set as well * - if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set