db0fd9726e
Added constructors to block_address_translation and segment_descriptor that will clear its memory (could be done more efficiently though, it just uses memset()). Added definitions for the MSR (machine state register). Added tlbsync() macro (direct assembler call). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5092 a95241bf-73f2-0310-859d-f6bbb57e9c96
150 lines
3.3 KiB
C
150 lines
3.3 KiB
C
/*
|
|
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
|
** Distributed under the terms of the OpenBeOS License.
|
|
*/
|
|
#ifndef _KERNEL_ARCH_PPC_MMU_H
|
|
#define _KERNEL_ARCH_PPC_MMU_H
|
|
|
|
|
|
#include <SupportDefs.h>
|
|
#include <string.h>
|
|
|
|
#include <arch_cpu.h>
|
|
|
|
|
|
/*** BAT - block address translation ***/
|
|
|
|
enum bat_length {
|
|
BAT_LENGTH_128kB = 0x0000,
|
|
BAT_LENGTH_256kB = 0x0001,
|
|
BAT_LENGTH_512kB = 0x0003,
|
|
BAT_LENGTH_1MB = 0x0007,
|
|
BAT_LENGTH_2MB = 0x000f,
|
|
BAT_LENGTH_4MB = 0x001f,
|
|
BAT_LENGTH_8MB = 0x003f,
|
|
BAT_LENGTH_16MB = 0x007f,
|
|
BAT_LENGTH_32MB = 0x00ff,
|
|
BAT_LENGTH_64MB = 0x01ff,
|
|
BAT_LENGTH_128MB = 0x03ff,
|
|
BAT_LENGTH_256MB = 0x07ff,
|
|
};
|
|
|
|
enum bat_protection {
|
|
BAT_READ_ONLY = 1,
|
|
BAT_READ_WRITE = 2,
|
|
};
|
|
|
|
struct block_address_translation {
|
|
// upper 32 bit
|
|
uint32 page_index : 15; // BEPI, block effective page index
|
|
uint32 _reserved0 : 4;
|
|
uint32 length : 11;
|
|
uint32 kernel_valid : 1; // Vs, Supervisor-state valid
|
|
uint32 user_valid : 1; // Vp, User-state valid
|
|
// lower 32 bit
|
|
uint32 physical_block_number : 15; // BPRN
|
|
uint32 write_through : 1; // WIMG
|
|
uint32 caching_inhibited : 1;
|
|
uint32 memory_coherent : 1;
|
|
uint32 guarded : 1;
|
|
uint32 _reserved1 : 1;
|
|
uint32 protection : 2;
|
|
|
|
block_address_translation()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void SetVirtualAddress(void *address)
|
|
{
|
|
page_index = uint32(address) >> 17;
|
|
}
|
|
|
|
void SetPhysicalAddress(void *address)
|
|
{
|
|
physical_block_number = uint32(address) >> 17;
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
memset((void *)this, 0, sizeof(block_address_translation));
|
|
}
|
|
};
|
|
|
|
struct segment_descriptor {
|
|
uint32 type : 1; // 0 for page translation descriptors
|
|
uint32 kernel_protection_key : 1; // Ks, Supervisor-state protection key
|
|
uint32 user_protection_key : 1; // Kp, User-state protection key
|
|
uint32 no_execute_protection : 1;
|
|
uint32 _reserved : 4;
|
|
uint32 virtual_segment_id : 24;
|
|
|
|
segment_descriptor()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
segment_descriptor(uint32 value)
|
|
{
|
|
*((uint32 *)this) = value;
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
memset((void *)this, 0, sizeof(segment_descriptor));
|
|
}
|
|
};
|
|
|
|
|
|
/*** PTE - page table entry ***/
|
|
|
|
enum pte_protection {
|
|
PTE_READ_ONLY = 3,
|
|
PTE_READ_WRITE = 2,
|
|
};
|
|
|
|
struct page_table_entry {
|
|
// upper 32 bit
|
|
uint32 valid : 1;
|
|
uint32 virtual_segment_id : 24;
|
|
uint32 secondary_hash : 1;
|
|
uint32 abbr_page_index : 6;
|
|
// lower 32 bit
|
|
uint32 physical_page_number : 20;
|
|
uint32 _reserved0 : 3;
|
|
uint32 referenced : 1;
|
|
uint32 changed : 1;
|
|
uint32 write_through : 1; // WIMG
|
|
uint32 caching_inhibited : 1;
|
|
uint32 memory_coherent : 1;
|
|
uint32 guarded : 1;
|
|
uint32 _reserved1 : 1;
|
|
uint32 page_protection : 2;
|
|
|
|
static uint32 PrimaryHash(uint32 virtualSegmentID, uint32 virtualAddress);
|
|
static uint32 SecondaryHash(uint32 virtualSegmentID, uint32 virtualAddress);
|
|
static uint32 SecondaryHash(uint32 primaryHash);
|
|
};
|
|
|
|
struct page_table_entry_group {
|
|
struct page_table_entry entry[8];
|
|
};
|
|
|
|
extern void ppc_get_page_table(page_table_entry_group **_pageTable, size_t *_size);
|
|
extern void ppc_set_page_table(page_table_entry_group *pageTable, size_t size);
|
|
|
|
static inline segment_descriptor
|
|
ppc_get_segment_register(void *virtualAddress)
|
|
{
|
|
return (segment_descriptor)get_sr(virtualAddress);
|
|
}
|
|
|
|
|
|
static inline void
|
|
ppc_set_segment_register(void *virtualAddress, segment_descriptor segment)
|
|
{
|
|
set_sr(virtualAddress, *(uint32 *)&segment);
|
|
}
|
|
|
|
#endif /* _KERNEL_ARCH_PPC_MMU_H */
|