haiku/headers/private/kernel/arch/ppc/arch_mmu.h
Axel Dörfler db0fd9726e Added functions to set and get the segment register (as segment_descriptor).
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
2003-10-21 03:07:44 +00:00

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