xref: /haiku/headers/private/kernel/arch/m68k/arch_mmu.h (revision b6f76ebe7153b94820cf35f8db4facc158841abb)
10b2adc3dSFrançois Revol /*
20b2adc3dSFrançois Revol ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3*b6f76ebeSAugustin Cavalier ** Distributed under the terms of the MIT License.
40b2adc3dSFrançois Revol */
50b2adc3dSFrançois Revol #ifndef _KERNEL_ARCH_M68K_MMU_H
60b2adc3dSFrançois Revol #define _KERNEL_ARCH_M68K_MMU_H
70b2adc3dSFrançois Revol 
80b2adc3dSFrançois Revol 
90b2adc3dSFrançois Revol #include <SupportDefs.h>
100b2adc3dSFrançois Revol #include <string.h>
110b2adc3dSFrançois Revol 
120b2adc3dSFrançois Revol 
131a8a803eSFrançois Revol /*
141a8a803eSFrançois Revol  * cf.
151a8a803eSFrançois Revol  * "mc68030 Enhanced 32-bit Microprocessor User's Manual"
161a8a803eSFrançois Revol  * (3rd edition), Section 9
171a8a803eSFrançois Revol  * "mc68040 Enhanced 32-bit Microprocessor User's Manual"
181a8a803eSFrançois Revol  * Section 9
191a8a803eSFrançois Revol  *
201a8a803eSFrançois Revol  * The 030 pmmu can support up to 6-level translation tree,
211a8a803eSFrançois Revol  * each level using an size-selectable index from the
221a8a803eSFrançois Revol  * virtual address, short (4-bit) and long (8-bit) page table
231a8a803eSFrançois Revol  * and page entry descriptors, early tree termination, and selectable
241a8a803eSFrançois Revol  * page size from 256 bytes to 32K.
251a8a803eSFrançois Revol  * There is optionally a separate Supervisor Root Pointer to separate
261a8a803eSFrançois Revol  * the user and kernel trees.
271a8a803eSFrançois Revol  *
281a8a803eSFrançois Revol  * The 040 pmmu however is way more limited in its abilities.
291a8a803eSFrançois Revol  * It has a fixed 3-level page tree, with 7/7/6 bit splitting for
301a8a803eSFrançois Revol  * 4K pages. The opcodes are also different so we will need specific
311a8a803eSFrançois Revol  * routines. Both supervisor and root pointers must be used so we can't
321a8a803eSFrançois Revol  * reuse one of them.
331a8a803eSFrançois Revol  *
341a8a803eSFrançois Revol  *
351a8a803eSFrançois Revol  * We settle to:
361a8a803eSFrançois Revol  * - 1 bit index for the first level to easily split kernel and user
371a8a803eSFrançois Revol  * part of the tree, with the possibility to force supervisor only for
381a8a803eSFrançois Revol  * the kernel tree. The use of SRP to point to a 2nd tree is avoided as
391a8a803eSFrançois Revol  * it is not available on 68060, plus that makes a spare 64bit reg to
401a8a803eSFrançois Revol  * stuff things in.
411a8a803eSFrançois Revol  * - 9 bit page directory
421a8a803eSFrançois Revol  * - 10 bit page tables
431a8a803eSFrançois Revol  * - 12 bit page index (4K pages, a common value).
441a8a803eSFrançois Revol  */
450b2adc3dSFrançois Revol 
460b2adc3dSFrançois Revol 
471a8a803eSFrançois Revol 
481a8a803eSFrançois Revol enum descriptor_types {
491a8a803eSFrançois Revol 	DT_INVALID = 0,			// invalid entry
501a8a803eSFrançois Revol 	DT_PAGE,				// page descriptor
511a8a803eSFrançois Revol 	DT_VALID_4,				// short page table descriptor
521a8a803eSFrançois Revol 	DT_VALID_8,				// long page table descriptor
530b2adc3dSFrançois Revol };
540b2adc3dSFrançois Revol 
55f239fdf6SFrançois Revol #define M68K_PE_DT_MASK	0x00000003
56f239fdf6SFrançois Revol #define DT_MASK	M68K_PE_DT_MASK
57f239fdf6SFrançois Revol 
581a8a803eSFrançois Revol #if 0
591a8a803eSFrançois Revol /* This is the normal layout of the descriptors, as per documentation.
601a8a803eSFrançois Revol  * When page size > 256, several bits are unused in the LSB of page
611a8a803eSFrançois Revol  * addresses, which we can use in addition of other unused bits.
621a8a803eSFrançois Revol  * the structs dedlared later reflect this for 4K pages.
631a8a803eSFrançois Revol  */
641a8a803eSFrançois Revol 
651a8a803eSFrançois Revol struct short_page_directory_entry {
661a8a803eSFrançois Revol 	// upper 32 bits
671a8a803eSFrançois Revol 	uint32 type : 2;
681a8a803eSFrançois Revol 	uint32 write_protect : 1;
691a8a803eSFrançois Revol 	uint32 used : 1;
701a8a803eSFrançois Revol 	uint32 address : 28;
710b2adc3dSFrançois Revol };
720b2adc3dSFrançois Revol 
731a8a803eSFrançois Revol struct long_page_directory_entry {
741a8a803eSFrançois Revol 	// upper 32 bits
751a8a803eSFrançois Revol 	uint32 type : 2;
761a8a803eSFrançois Revol 	uint32 write_protect : 1;
771a8a803eSFrançois Revol 	uint32 used : 1;
781a8a803eSFrançois Revol 	uint32 _zero1 : 4;
791a8a803eSFrançois Revol 	uint32 supervisor : 1;
801a8a803eSFrançois Revol 	uint32 _zero2 : 1;
811a8a803eSFrançois Revol 	uint32 _ones : 6;
821a8a803eSFrançois Revol 	uint32 limit : 15;
831a8a803eSFrançois Revol 	uint32 low_up : 1;						// limit is lower(1)/upper(0)
841a8a803eSFrançois Revol 	// lower 32 bits
851a8a803eSFrançois Revol 	uint32 unused : 4;						//
861a8a803eSFrançois Revol 	uint32 address : 28;
870b2adc3dSFrançois Revol };
880b2adc3dSFrançois Revol 
891a8a803eSFrançois Revol struct short_page_table_entry {
901a8a803eSFrançois Revol 	uint32 type : 2;
911a8a803eSFrançois Revol 	uint32 write_protect : 1;
921a8a803eSFrançois Revol 	uint32 used : 1;
931a8a803eSFrançois Revol 	uint32 modified : 1;
941a8a803eSFrançois Revol 	uint32 _zero1 : 1;
951a8a803eSFrançois Revol 	uint32 cache_inhibit : 1;
961a8a803eSFrançois Revol 	uint32 _zero2 : 1;
971a8a803eSFrançois Revol 	uint32 address : 24;
980b2adc3dSFrançois Revol };
990b2adc3dSFrançois Revol 
1001a8a803eSFrançois Revol struct long_page_table_entry {
1011a8a803eSFrançois Revol 	// upper 32 bits
1021a8a803eSFrançois Revol 	uint32 type : 2;
1031a8a803eSFrançois Revol 	uint32 write_protect : 1;
1041a8a803eSFrançois Revol 	uint32 used : 1;
1051a8a803eSFrançois Revol 	uint32 modified : 1;
1061a8a803eSFrançois Revol 	uint32 _zero1 : 1;
1071a8a803eSFrançois Revol 	uint32 cache_inhibit : 1;
1081a8a803eSFrançois Revol 	uint32 _zero2 : 1;
1091a8a803eSFrançois Revol 	uint32 supervisor : 1;
1101a8a803eSFrançois Revol 	uint32 _zero3 : 1;
1111a8a803eSFrançois Revol 	uint32 _ones : 6;
1121a8a803eSFrançois Revol 	// limit only used on early table terminators, else unused
1131a8a803eSFrançois Revol 	uint32 limit : 15;
1141a8a803eSFrançois Revol 	uint32 low_up : 1;						// limit is lower(1)/upper(0)
1151a8a803eSFrançois Revol 	// lower 32 bits
1161a8a803eSFrançois Revol 	uint32 unused : 8;						//
1171a8a803eSFrançois Revol 	uint32 address : 24;
1180b2adc3dSFrançois Revol };
1191a8a803eSFrançois Revol #endif
1200b2adc3dSFrançois Revol 
1211778540aSFrançois Revol /* ppc
1220b2adc3dSFrançois Revol extern void m68k_get_page_table(page_table_entry_group **_pageTable, size_t *_size);
1230b2adc3dSFrançois Revol extern void m68k_set_page_table(page_table_entry_group *pageTable, size_t size);
1241778540aSFrançois Revol */
1250b2adc3dSFrançois Revol 
1260b2adc3dSFrançois Revol #endif	/* _KERNEL_ARCH_M68K_MMU_H */
127