2003-10-08 04:28:07 +04:00
|
|
|
/*
|
|
|
|
** 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>
|
2003-10-17 17:58:41 +04:00
|
|
|
#include <string.h>
|
2003-10-08 04:28:07 +04:00
|
|
|
|
2003-10-21 07:07:44 +04:00
|
|
|
#include <arch_cpu.h>
|
|
|
|
|
2003-10-08 04:28:07 +04:00
|
|
|
|
2003-10-17 17:58:41 +04:00
|
|
|
/*** BAT - block address translation ***/
|
|
|
|
|
2003-10-08 04:28:07 +04:00
|
|
|
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
|
2003-10-17 17:58:41 +04:00
|
|
|
uint32 _reserved0 : 4;
|
|
|
|
uint32 length : 11;
|
|
|
|
uint32 kernel_valid : 1; // Vs, Supervisor-state valid
|
|
|
|
uint32 user_valid : 1; // Vp, User-state valid
|
2003-10-08 04:28:07 +04:00
|
|
|
// lower 32 bit
|
2003-10-17 17:58:41 +04:00
|
|
|
uint32 physical_block_number : 15; // BPRN
|
2003-10-08 04:28:07 +04:00
|
|
|
uint32 write_through : 1; // WIMG
|
|
|
|
uint32 caching_inhibited : 1;
|
|
|
|
uint32 memory_coherent : 1;
|
|
|
|
uint32 guarded : 1;
|
|
|
|
uint32 _reserved1 : 1;
|
|
|
|
uint32 protection : 2;
|
|
|
|
|
2003-10-21 07:07:44 +04:00
|
|
|
block_address_translation()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
2003-10-17 17:58:41 +04:00
|
|
|
void SetVirtualAddress(void *address)
|
|
|
|
{
|
|
|
|
page_index = uint32(address) >> 17;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetPhysicalAddress(void *address)
|
|
|
|
{
|
|
|
|
physical_block_number = uint32(address) >> 17;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clear()
|
2003-10-08 04:28:07 +04:00
|
|
|
{
|
2003-10-17 17:58:41 +04:00
|
|
|
memset((void *)this, 0, sizeof(block_address_translation));
|
2003-10-08 04:28:07 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2003-10-21 07:07:44 +04:00
|
|
|
|
|
|
|
segment_descriptor()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
segment_descriptor(uint32 value)
|
|
|
|
{
|
|
|
|
*((uint32 *)this) = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clear()
|
|
|
|
{
|
|
|
|
memset((void *)this, 0, sizeof(segment_descriptor));
|
|
|
|
}
|
2003-10-08 04:28:07 +04:00
|
|
|
};
|
|
|
|
|
2003-10-17 17:58:41 +04:00
|
|
|
|
|
|
|
/*** PTE - page table entry ***/
|
|
|
|
|
|
|
|
enum pte_protection {
|
|
|
|
PTE_READ_ONLY = 3,
|
|
|
|
PTE_READ_WRITE = 2,
|
|
|
|
};
|
|
|
|
|
2003-10-08 04:28:07 +04:00
|
|
|
struct page_table_entry {
|
|
|
|
// upper 32 bit
|
|
|
|
uint32 valid : 1;
|
|
|
|
uint32 virtual_segment_id : 24;
|
2003-10-17 17:58:41 +04:00
|
|
|
uint32 secondary_hash : 1;
|
2003-10-08 04:28:07 +04:00
|
|
|
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);
|
2003-10-11 22:57:35 +04:00
|
|
|
static uint32 SecondaryHash(uint32 primaryHash);
|
2003-10-08 04:28:07 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct page_table_entry_group {
|
|
|
|
struct page_table_entry entry[8];
|
|
|
|
};
|
|
|
|
|
2003-10-17 17:58:41 +04:00
|
|
|
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);
|
2003-10-08 04:28:07 +04:00
|
|
|
|
2003-10-21 07:07:44 +04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2003-10-08 04:28:07 +04:00
|
|
|
#endif /* _KERNEL_ARCH_PPC_MMU_H */
|