1/*
2 * Copyright 2008-2010, Fran��ois Revol, revol@free.fr. All rights reserved.
3 * Copyright 2004-2007, Axel D��rfler, axeld@pinc-software.de.
4 * Based on code written by Travis Geiselbrecht for NewOS.
5 *
6 * Distributed under the terms of the MIT License.
7 */
8
9
10#include "nextrom.h"
11#include "mmu.h"
12
13#include <boot/platform.h>
14#include <boot/stdio.h>
15#include <boot/kernel_args.h>
16#include <boot/stage2.h>
17#include <arch/cpu.h>
18#include <arch_kernel.h>
19#include <kernel.h>
20
21#include <OS.h>
22
23#include <string.h>
24
25#warning TODO: M68K: NEXT: mmu
26
27//XXX: x86
28/** The (physical) memory layout of the boot loader is currently as follows:
29 *	  0x0500 - 0x10000	protected mode stack
30 *	  0x0500 - 0x09000	real mode stack
31 *	 0x10000 - ?		code (up to ~500 kB)
32 *	 0x90000			1st temporary page table (identity maps 0-4 MB)
33 *	 0x91000			2nd (4-8 MB)
34 *	 0x92000 - 0x92000	further page tables
35 *	 0x9e000 - 0xa0000	SMP trampoline code
36 *	[0xa0000 - 0x100000	BIOS/ROM/reserved area]
37 *	0x100000			page directory
38 *	     ...			boot loader heap (32 kB)
39 *	     ...			free physical memory
40 *
41 *	The first 8 MB are identity mapped (0x0 - 0x0800000); paging is turned
42 *	on. The kernel is mapped at 0x80000000, all other stuff mapped by the
43 *	loader (kernel args, modules, driver settings, ...) comes after
44 *	0x81000000 which means that there is currently only 1 MB reserved for
45 *	the kernel itself (see kMaxKernelSize).
46 */
47
48// notes m68k:
49/** The (physical) memory layout of the boot loader is currently as follows:
50 *	  0x0800 - 0x10000	supervisor mode stack (1) XXX: more ? x86 starts at 500
51 *	 0x10000 - ?		code (up to ~500 kB)
52 *  0x100000 or FAST_RAM_BASE if any:
53 *	     ...			page root directory
54 *	     ...			interrupt vectors (VBR)
55 *	     ...			page directory
56 *	     ...			boot loader heap (32 kB)
57 *	     ...			free physical memory
58 *  0xdNNNNN			video buffer usually there, as per v_bas_ad
59 *						(=Logbase() but Physbase() is better)
60 *
61 *	The first 32 MB (2) are identity mapped (0x0 - 0x1000000); paging
62 *	is turned on. The kernel is mapped at 0x80000000, all other stuff
63 *	mapped by the loader (kernel args, modules, driver settings, ...)
64 *	comes after 0x81000000 which means that there is currently only
65 *	1 MB reserved for the kernel itself (see kMaxKernelSize).
66 *
67 *	(1) no need for user stack, we are already in supervisor mode in the
68 *	loader.
69 *	(2) maps the whole regular ST space; transparent translation registers
70 *	have larger granularity anyway.
71 */
72#warning M68K: check for Physbase() < ST_RAM_TOP
73
74#define TRACE_MMU
75#ifdef TRACE_MMU
76#	define TRACE(x) dprintf x
77#else
78#	define TRACE(x) ;
79#endif
80
81
82// since the page root directory doesn't take a full page (1k)
83// we stuff some other stuff after it, like the interrupt vectors (1k)
84#define VBR_PAGE_OFFSET 1024
85
86static const uint32 kDefaultPageTableFlags = 0x07;	// present, user, R/W
87static const size_t kMaxKernelSize = 0x200000;		// 2 MB for the kernel
88
89// working page directory and page table
90addr_t gPageRoot = 0;
91
92static addr_t sNextPhysicalAddress = 0x100000;
93static addr_t sNextVirtualAddress = KERNEL_LOAD_BASE + kMaxKernelSize;
94static addr_t sMaxVirtualAddress = KERNEL_LOAD_BASE /*+ 0x400000*/;
95
96#if 0
97static addr_t sNextPageTableAddress = 0x90000;
98static const uint32 kPageTableRegionEnd = 0x9e000;
99	// we need to reserve 2 pages for the SMP trampoline code XXX:no
100#endif
101
102
103
104/**	This will unmap the allocated chunk of memory from the virtual
105 *	address space. It might not actually free memory (as its implementation
106 *	is very simple), but it might.
107 */
108
109extern "C" void
110mmu_free(void *virtualAddress, size_t size)
111{
112	TRACE(("mmu_free(virtualAddress = %p, size: %ld)\n", virtualAddress, size));
113}
114
115
116/** Sets up the final and kernel accessible GDT and IDT tables.
117 *	BIOS calls won't work any longer after this function has
118 *	been called.
119 */
120
121extern "C" void
122mmu_init_for_kernel(void)
123{
124	TRACE(("mmu_init_for_kernel\n"));
125}
126
127
128extern "C" void
129mmu_init(void)
130{
131	TRACE(("mmu_init\n"));
132}
133
134
135//	#pragma mark -
136
137
138extern "C" status_t
139platform_allocate_region(void **_address, size_t size, uint8 protection,
140	bool /*exactAddress*/)
141{
142	return B_UNSUPPORTED;
143}
144
145
146extern "C" status_t
147platform_free_region(void *address, size_t size)
148{
149	return B_UNSUPPORTED;
150}
151
152
153void
154platform_release_heap(struct stage2_args *args, void *base)
155{
156	// It will be freed automatically, since it is in the
157	// identity mapped region, and not stored in the kernel's
158	// page tables.
159}
160
161
162status_t
163platform_init_heap(struct stage2_args *args, void **_base, void **_top)
164{
165	return B_UNSUPPORTED;
166}
167
168
169extern "C" status_t
170platform_bootloader_address_to_kernel_address(void *address, addr_t *_result)
171{
172	TRACE(("%s: called\n", __func__));
173	// next_m68k really doesn't need an address conversion
174	*_result = (addr_t)address;
175	return B_OK;
176}
177
178
179extern "C" status_t
180platform_kernel_address_to_bootloader_address(addr_t address, void **_result)
181{
182	TRACE(("%s: called\n", __func__));
183	// next_m68k really doesn't need an address conversion
184	*_result = (void*)address;
185	return B_OK;
186}
187