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);
|
||||
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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -5,6 +5,6 @@ UsePrivateHeaders kernel ;
|
||||
KernelAddon generic_x86 : kernel cpu :
|
||||
generic_x86.cpp
|
||||
intel.cpp
|
||||
amd.cpp
|
||||
via.cpp
|
||||
# amd.cpp
|
||||
# via.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
|
||||
};
|
||||
|
||||
@@ -9,24 +9,95 @@
|
||||
|
||||
#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
|
||||
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,
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <kernel.h>
|
||||
#include <lock.h>
|
||||
#include <boot_item.h>
|
||||
#include <vm.h>
|
||||
#include <fs/devfs.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);
|
||||
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 -
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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};
|
||||
|
||||
+40
-16
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user