Some work in progress of the MTRR support. Shouldn't do any harm yet :-)
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15525 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -24,7 +24,7 @@ void arch_vm_aspace_swap(vm_address_space *aspace);
|
|||||||
bool arch_vm_supports_protection(uint32 protection);
|
bool arch_vm_supports_protection(uint32 protection);
|
||||||
void arch_vm_init_area(vm_area *area);
|
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);
|
void arch_vm_unset_memory_type(vm_area *area);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -14,14 +14,23 @@
|
|||||||
|
|
||||||
|
|
||||||
// MSR registers (possibly Intel specific)
|
// 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 {
|
typedef struct x86_cpu_module_info {
|
||||||
module_info info;
|
module_info info;
|
||||||
uint32 (*count_mtrrs)(void);
|
uint32 (*count_mtrrs)(void);
|
||||||
status_t (*set_mtrr)(uint32 index, addr_t base, addr_t length, uint32 type);
|
status_t (*enable_mtrrs)(void);
|
||||||
status_t (*unset_mtrr)(uint32 index);
|
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;
|
} x86_cpu_module_info;
|
||||||
|
|
||||||
|
|
||||||
@@ -91,8 +100,10 @@ uint64 x86_read_msr(uint32 registerNumber);
|
|||||||
void x86_write_msr(uint32 registerNumber, uint64 value);
|
void x86_write_msr(uint32 registerNumber, uint64 value);
|
||||||
void x86_set_task_gate(int32 n, int32 segment);
|
void x86_set_task_gate(int32 n, int32 segment);
|
||||||
uint32 x86_count_mtrrs(void);
|
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_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);
|
struct tss *x86_get_main_tss(void);
|
||||||
|
|
||||||
#define read_ebp(value) \
|
#define read_ebp(value) \
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ extern "C" {
|
|||||||
|
|
||||||
extern status_t debug_init(struct kernel_args *args);
|
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_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_early_boot_message(const char *string);
|
||||||
extern void debug_puts(const char *s);
|
extern void debug_puts(const char *s);
|
||||||
extern bool debug_debugger_running(void);
|
extern bool debug_debugger_running(void);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ extern "C" {
|
|||||||
|
|
||||||
bool frame_buffer_console_available(void);
|
bool frame_buffer_console_available(void);
|
||||||
status_t frame_buffer_console_init(struct kernel_args *args);
|
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,
|
status_t _user_frame_buffer_update(addr_t baseAddress, int32 width, int32 height,
|
||||||
int32 depth, int32 bytesPerRow);
|
int32 depth, int32 bytesPerRow);
|
||||||
|
|||||||
@@ -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_delete_area(aspace_id aid, area_id id);
|
||||||
status_t vm_create_vnode_cache(void *vnode, vm_cache_ref **_cacheRef);
|
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_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_get_physical_page(addr_t paddr, addr_t *vaddr, int flags);
|
||||||
status_t vm_put_physical_page(addr_t vaddr);
|
status_t vm_put_physical_page(addr_t vaddr);
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ UsePrivateHeaders kernel ;
|
|||||||
KernelAddon generic_x86 : kernel cpu :
|
KernelAddon generic_x86 : kernel cpu :
|
||||||
generic_x86.cpp
|
generic_x86.cpp
|
||||||
intel.cpp
|
intel.cpp
|
||||||
amd.cpp
|
# amd.cpp
|
||||||
via.cpp
|
# via.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
#include "via.h"
|
#include "via.h"
|
||||||
|
|
||||||
|
|
||||||
module_info *gModules[] = {
|
module_info *modules[] = {
|
||||||
(module_info *)&gIntelModule,
|
(module_info *)&gIntelModule,
|
||||||
(module_info *)&gAMDModule,
|
// (module_info *)&gAMDModule,
|
||||||
(module_info *)&gVIAModule,
|
// (module_info *)&gVIAModule,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,24 +9,95 @@
|
|||||||
|
|
||||||
#include "intel.h"
|
#include "intel.h"
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <arch_cpu.h>
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
static uint32
|
||||||
intel_count_mtrrs(void)
|
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
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static void
|
||||||
intel_unset_mtrr(uint32 index)
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,10 +109,28 @@ intel_init(void)
|
|||||||
if (get_system_info(&info) != B_OK)
|
if (get_system_info(&info) != B_OK)
|
||||||
return B_ERROR;
|
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_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_count_mtrrs,
|
||||||
|
intel_enable_mtrrs,
|
||||||
|
intel_disable_mtrrs,
|
||||||
|
|
||||||
intel_set_mtrr,
|
intel_set_mtrr,
|
||||||
intel_unset_mtrr,
|
intel_get_mtrr,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ arch_vm_unset_memory_type(vm_area *area)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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)
|
if (type == 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -103,22 +103,44 @@ x86_count_mtrrs(void)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
x86_set_mtrr(uint32 index, addr_t base, addr_t length, uint32 type)
|
x86_enable_mtrrs(void)
|
||||||
{
|
{
|
||||||
if (load_cpu_module() == NULL)
|
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
|
status_t
|
||||||
x86_unset_mtrr(uint32 index)
|
x86_disable_mtrrs(void)
|
||||||
{
|
{
|
||||||
if (load_cpu_module() == NULL)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,26 +30,27 @@
|
|||||||
#endif
|
#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 int32 sMTRRCount;
|
||||||
static spinlock sMTRRLock;
|
static spinlock sMTRRLock;
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
init_mtrr_bitmap(void)
|
init_mtrr(void)
|
||||||
{
|
{
|
||||||
if (sMTRRBitmap != NULL)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
sMTRRCount = x86_count_mtrrs();
|
sMTRRCount = x86_count_mtrrs();
|
||||||
if (sMTRRCount == 0)
|
if (sMTRRCount == 0)
|
||||||
return B_UNSUPPORTED;
|
return B_NOT_SUPPORTED;
|
||||||
|
|
||||||
sMTRRBitmap = malloc(sMTRRCount / 8);
|
sMTRRBitmap = 0;
|
||||||
if (sMTRRBitmap == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
memset(sMTRRBitmap, 0, sMTRRCount / 8);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,28 +58,22 @@ init_mtrr_bitmap(void)
|
|||||||
static int32
|
static int32
|
||||||
allocate_mtrr(void)
|
allocate_mtrr(void)
|
||||||
{
|
{
|
||||||
int32 count = sMTRRCount / 32;
|
int32 index;
|
||||||
int32 i, j;
|
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
acquire_spinlock(&sMTRRLock);
|
acquire_spinlock(&sMTRRLock);
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
// find free bit
|
||||||
if (sMTRRBitmap[i] == 0xffffffff)
|
|
||||||
|
for (index = 0; index < 32; index++) {
|
||||||
|
if (sMTRRBitmap & (1UL << index))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// find free bit
|
sMTRRBitmap |= 1UL << index;
|
||||||
|
|
||||||
for (j = 0; j < 32; j++) {
|
release_spinlock(&sMTRRLock);
|
||||||
if (sMTRRBitmap[i] & (1UL << j))
|
restore_interrupts(state);
|
||||||
continue;
|
return index;
|
||||||
|
|
||||||
sMTRRBitmap[i] |= 1UL << j;
|
|
||||||
|
|
||||||
release_spinlock(&sMTRRLock);
|
|
||||||
restore_interrupts(state);
|
|
||||||
return i * 32 + j;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
release_spinlock(&sMTRRLock);
|
release_spinlock(&sMTRRLock);
|
||||||
@@ -91,19 +86,38 @@ allocate_mtrr(void)
|
|||||||
static void
|
static void
|
||||||
free_mtrr(int32 index)
|
free_mtrr(int32 index)
|
||||||
{
|
{
|
||||||
int32 i = index / 32;
|
|
||||||
int32 j = index - i * 32;
|
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
acquire_spinlock(&sMTRRLock);
|
acquire_spinlock(&sMTRRLock);
|
||||||
|
|
||||||
sMTRRBitmap[i] &= ~(1UL << j);
|
sMTRRBitmap &= ~(1UL << index);
|
||||||
|
|
||||||
release_spinlock(&sMTRRLock);
|
release_spinlock(&sMTRRLock);
|
||||||
restore_interrupts(state);
|
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
|
status_t
|
||||||
arch_vm_init(kernel_args *args)
|
arch_vm_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
@@ -182,58 +196,58 @@ arch_vm_unset_memory_type(vm_area *area)
|
|||||||
if (area->memory_type.type == 0)
|
if (area->memory_type.type == 0)
|
||||||
return;
|
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);
|
free_mtrr(area->memory_type.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
struct set_mtrr_parameter parameter;
|
||||||
int32 index;
|
|
||||||
|
|
||||||
if (type == 0)
|
if (type == 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case B_MTR_UC: // uncacheable
|
case B_MTR_UC: // uncacheable
|
||||||
type = 0;
|
parameter.type = 0;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WC: // write combining
|
case B_MTR_WC: // write combining
|
||||||
type = 1;
|
parameter.type = 1;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WT: // write through
|
case B_MTR_WT: // write through
|
||||||
type = 4;
|
parameter.type = 4;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WP: // write protected
|
case B_MTR_WP: // write protected
|
||||||
type = 5;
|
parameter.type = 5;
|
||||||
break;
|
break;
|
||||||
case B_MTR_WB: // write back
|
case B_MTR_WB: // write back
|
||||||
type = 6;
|
parameter.type = 6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sMTRRBitmap == NULL) {
|
if (sMTRRCount == 0) {
|
||||||
status = init_mtrr_bitmap();
|
status_t status = init_mtrr();
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = allocate_mtrr();
|
parameter.index = allocate_mtrr();
|
||||||
if (index < 0)
|
if (parameter.index < 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
status = x86_set_mtrr(index, area->base, area->size, type);
|
parameter.base = physicalBase;
|
||||||
if (status != B_OK) {
|
parameter.length = area->size;
|
||||||
area->memory_type.type = (uint16)type;
|
|
||||||
area->memory_type.index = (uint16)index;
|
|
||||||
} else
|
|
||||||
free_mtrr(index);
|
|
||||||
|
|
||||||
dprintf("memory type: %u, index: %ld\n", area->memory_type.type, index);
|
call_all_cpus(&set_mtrr, ¶meter);
|
||||||
return status;
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
// #pragma mark - public API
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
#include <boot_item.h>
|
#include <boot_item.h>
|
||||||
|
#include <vm.h>
|
||||||
#include <fs/devfs.h>
|
#include <fs/devfs.h>
|
||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ render_glyph(int32 x, int32 y, uint8 glyph, uint8 attr)
|
|||||||
+ x * CHAR_WIDTH * sConsole.bytes_per_pixel);
|
+ x * CHAR_WIDTH * sConsole.bytes_per_pixel);
|
||||||
uint8 *color = get_palette_entry(foreground_color(attr));
|
uint8 *color = get_palette_entry(foreground_color(attr));
|
||||||
uint8 *backgroundColor = get_palette_entry(background_color(attr));
|
uint8 *backgroundColor = get_palette_entry(background_color(attr));
|
||||||
|
|
||||||
for (y = 0; y < CHAR_HEIGHT; y++) {
|
for (y = 0; y < CHAR_HEIGHT; y++) {
|
||||||
uint8 bits = FONT[CHAR_HEIGHT * glyph + y];
|
uint8 bits = FONT[CHAR_HEIGHT * glyph + y];
|
||||||
for (x = 0; x < CHAR_WIDTH; x++) {
|
for (x = 0; x < CHAR_WIDTH; x++) {
|
||||||
@@ -122,7 +123,7 @@ render_glyph(int32 x, int32 y, uint8 glyph, uint8 attr)
|
|||||||
}
|
}
|
||||||
bits >>= 1;
|
bits >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
base += sConsole.bytes_per_row;
|
base += sConsole.bytes_per_row;
|
||||||
}
|
}
|
||||||
} else {
|
} 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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -225,6 +225,22 @@ int_io_interrupt_handler(int vector)
|
|||||||
int status = B_UNHANDLED_INTERRUPT;
|
int status = B_UNHANDLED_INTERRUPT;
|
||||||
struct io_handler *io;
|
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);
|
acquire_spinlock(&io_vectors[vector].vector_lock);
|
||||||
|
|
||||||
// The list can be empty at this place
|
// The list can be empty at this place
|
||||||
|
|||||||
@@ -215,27 +215,8 @@ main2(void *unused)
|
|||||||
TRACE(("Mount boot file system\n"));
|
TRACE(("Mount boot file system\n"));
|
||||||
vfs_mount_boot_file_system(&sKernelArgs);
|
vfs_mount_boot_file_system(&sKernelArgs);
|
||||||
|
|
||||||
//module_test();
|
debug_init_post_modules(&sKernelArgs);
|
||||||
#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
|
|
||||||
// start the init process
|
// start the init process
|
||||||
{
|
{
|
||||||
const char *shellArgs[] = {"/bin/sh", "/boot/beos/system/boot/Bootscript", NULL};
|
const char *shellArgs[] = {"/bin/sh", "/boot/beos/system/boot/Bootscript", NULL};
|
||||||
|
|||||||
+40
-16
@@ -935,20 +935,22 @@ vm_create_anonymous_area(aspace_id aid, const char *name, void **address,
|
|||||||
|
|
||||||
|
|
||||||
area_id
|
area_id
|
||||||
vm_map_physical_memory(aspace_id aid, const char *name, void **_address,
|
vm_map_physical_memory(aspace_id areaID, const char *name, void **_address,
|
||||||
uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr)
|
uint32 addressSpec, addr_t size, uint32 protection,
|
||||||
|
addr_t physicalAddress)
|
||||||
{
|
{
|
||||||
vm_area *area;
|
vm_area *area;
|
||||||
vm_cache *cache;
|
vm_cache *cache;
|
||||||
vm_cache_ref *cache_ref;
|
vm_cache_ref *cacheRef;
|
||||||
vm_store *store;
|
vm_store *store;
|
||||||
addr_t map_offset;
|
addr_t mapOffset;
|
||||||
status_t status;
|
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,"
|
TRACE(("vm_map_physical_memory(aspace = %ld, \"%s\", virtual = %p, spec = %ld,"
|
||||||
" size = %lu, protection = %ld, phys = %p)\n",
|
" 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))
|
if (!arch_vm_supports_protection(protection))
|
||||||
return B_NOT_SUPPORTED;
|
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,
|
// if the physical address is somewhat inside a page,
|
||||||
// move the actual area down to align on a page boundary
|
// move the actual area down to align on a page boundary
|
||||||
map_offset = phys_addr % B_PAGE_SIZE;
|
mapOffset = physicalAddress % B_PAGE_SIZE;
|
||||||
size += map_offset;
|
size += mapOffset;
|
||||||
phys_addr -= map_offset;
|
physicalAddress -= mapOffset;
|
||||||
|
|
||||||
size = PAGE_ALIGN(size);
|
size = PAGE_ALIGN(size);
|
||||||
|
|
||||||
// create an device store object
|
// create an device store object
|
||||||
store = vm_store_create_device(phys_addr);
|
// TODO: panic???
|
||||||
|
store = vm_store_create_device(physicalAddress);
|
||||||
if (store == NULL)
|
if (store == NULL)
|
||||||
panic("vm_map_physical_memory: vm_store_create_device returned NULL");
|
panic("vm_map_physical_memory: vm_store_create_device returned NULL");
|
||||||
cache = vm_cache_create(store);
|
cache = vm_cache_create(store);
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
panic("vm_map_physical_memory: vm_cache_create returned NULL");
|
panic("vm_map_physical_memory: vm_cache_create returned NULL");
|
||||||
cache_ref = vm_cache_ref_create(cache);
|
cacheRef = vm_cache_ref_create(cache);
|
||||||
if (cache_ref == NULL)
|
if (cacheRef == NULL)
|
||||||
panic("vm_map_physical_memory: vm_cache_ref_create returned 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
|
// tell the page scanner to skip over this area, it's pages are special
|
||||||
cache->scan_skip = 1;
|
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,
|
status = map_backing_store(aspace, store, _address, 0, size,
|
||||||
addressSpec & ~B_MTR_MASK, 0, protection, REGION_NO_PRIVATE_MAP, &area, name);
|
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) {
|
if (status >= B_OK && (addressSpec & B_MTR_MASK) != 0) {
|
||||||
// set requested memory type
|
// 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)
|
if (status < B_OK)
|
||||||
vm_put_area(area);
|
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
|
// modify the pointer returned to be offset back into the new area
|
||||||
// the same way the physical address in was offset
|
// 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;
|
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:
|
/** This function enforces some protection properties:
|
||||||
* - if B_WRITE_AREA is set, B_WRITE_KERNEL_AREA is set as well
|
* - 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
|
* - if only B_READ_AREA has been set, B_KERNEL_READ_AREA is also set
|
||||||
|
|||||||
Reference in New Issue
Block a user