1/*
2 * Copyright 2007-2010, Fran��ois Revol, revol@free.fr.
3 * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Copyright 2002-2007, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
5 * Distributed under the terms of the MIT License.
6 *
7 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
9 */
10
11#include <KernelExport.h>
12#include <kernel.h>
13#include <vm/vm.h>
14#include <vm/vm_priv.h>
15#include <vm/VMAddressSpace.h>
16#include <int.h>
17#include <boot/kernel_args.h>
18#include <arch/vm_translation_map.h>
19#include <arch/cpu.h>
20#include <arch_mmu.h>
21#include <stdlib.h>
22
23#include "generic_vm_physical_page_mapper.h"
24//#include "paging/030/M68KPagingMethod030.h"
25#include "paging/040/M68KPagingMethod040.h"
26//#include "paging/060/M68KPagingMethod060.h"
27
28
29#define TRACE_VM_TMAP
30#ifdef TRACE_VM_TMAP
31#	define TRACE(x...) dprintf(x)
32#else
33#	define TRACE(x...) ;
34#endif
35
36
37/*
38 * Each mmu of the m68k family has its own tricks, registers and opcodes...
39 * so they all have a specific paging method class.
40 */
41
42#warning M68K: 060: must *not* have pgtables in copyback cachable mem!!!
43
44static union {
45	uint64	align;
46	//char	m68851[sizeof(M68KPagingMethod851)];
47	//char	m68030[sizeof(M68KPagingMethod030)];
48	char	m68040[sizeof(M68KPagingMethod040)];
49// 060 should be identical to 040 except for copyback issue
50	//char	m68060[sizeof(M68KPagingMethod060)];
51} sPagingMethodBuffer;
52
53
54#if 0
55void *
56m68k_translation_map_get_pgdir(VMTranslationMap *map)
57{
58	return get_vm_ops()->m68k_translation_map_get_pgdir(map);
59}
60#endif
61
62//  #pragma mark -
63//  VM API
64
65
66status_t
67arch_vm_translation_map_create_map(bool kernel, VMTranslationMap** _map)
68{
69	return gM68KPagingMethod->CreateTranslationMap(kernel, _map);
70}
71
72
73status_t
74arch_vm_translation_map_init(kernel_args *args,
75	VMPhysicalPageMapper** _physicalPageMapper)
76{
77	TRACE("vm_translation_map_init: entry\n");
78
79#ifdef TRACE_VM_TMAP
80	TRACE("physical memory ranges:\n");
81	for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) {
82		phys_addr_t start = args->physical_memory_range[i].start;
83		phys_addr_t end = start + args->physical_memory_range[i].size;
84		TRACE("  %#10" B_PRIxPHYSADDR " - %#10" B_PRIxPHYSADDR "\n", start,
85			end);
86	}
87
88	TRACE("allocated physical ranges:\n");
89	for (uint32 i = 0; i < args->num_physical_allocated_ranges; i++) {
90		phys_addr_t start = args->physical_allocated_range[i].start;
91		phys_addr_t end = start + args->physical_allocated_range[i].size;
92		TRACE("  %#10" B_PRIxPHYSADDR " - %#10" B_PRIxPHYSADDR "\n", start,
93			end);
94	}
95
96	TRACE("allocated virtual ranges:\n");
97	for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
98		addr_t start = args->virtual_allocated_range[i].start;
99		addr_t end = start + args->virtual_allocated_range[i].size;
100		TRACE("  %#10" B_PRIxADDR " - %#10" B_PRIxADDR "\n", start, end);
101	}
102#endif
103	switch (arch_mmu_type) {
104		/*
105		case 68030:
106			gM68KPagingMethod = new(&sPagingMethodBuffer) M68KPagingMethod030;
107			break;
108		*/
109		case 68040:
110			gM68KPagingMethod = new(&sPagingMethodBuffer) M68KPagingMethod040;
111			break;
112		/*
113		case 68060:
114			gM68KPagingMethod = new(&sPagingMethodBuffer) M68KPagingMethod060;
115			break;
116		*/
117		default:
118			break;
119	}
120	return gM68KPagingMethod->Init(args, _physicalPageMapper);
121}
122
123
124status_t
125arch_vm_translation_map_init_post_sem(kernel_args *args)
126{
127	return B_OK;
128}
129
130
131status_t
132arch_vm_translation_map_init_post_area(kernel_args *args)
133{
134	TRACE("vm_translation_map_init_post_area: entry\n");
135
136	return gM68KPagingMethod->InitPostArea(args);
137}
138
139
140/**	Directly maps a page without having knowledge of any kernel structures.
141 *	Used only during VM setup.
142 *	It currently ignores the "attributes" parameter and sets all pages
143 *	read/write.
144 */
145status_t
146arch_vm_translation_map_early_map(kernel_args *args, addr_t va, phys_addr_t pa,
147	uint8 attributes, phys_addr_t (*get_free_page)(kernel_args *))
148{
149	TRACE("early_tmap: entry pa 0x%lx va 0x%lx\n", pa, va);
150
151	return gM68KPagingMethod->MapEarly(args, va, pa, attributes, get_free_page);
152}
153
154
155// XXX currently assumes this translation map is active
156/*
157status_t
158arch_vm_translation_map_early_query(addr_t va, addr_t *out_physical)
159{
160	return get_vm_ops()->arch_vm_translation_map_early_query(va, out_physical);
161}
162*/
163
164
165// #pragma mark -
166
167
168bool
169arch_vm_translation_map_is_kernel_page_accessible(addr_t virtualAddress,
170	uint32 protection)
171{
172	return gM68KPagingMethod->IsKernelPageAccessible(virtualAddress, protection);
173}
174
175