Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/m68k/atari/stram.c
26444 views
1
/*
2
* Functions for ST-RAM allocations
3
*
4
* Copyright 1994-97 Roman Hodek <[email protected]>
5
*
6
* This file is subject to the terms and conditions of the GNU General Public
7
* License. See the file COPYING in the main directory of this archive
8
* for more details.
9
*/
10
11
#include <linux/types.h>
12
#include <linux/kernel.h>
13
#include <linux/mm.h>
14
#include <linux/kdev_t.h>
15
#include <linux/major.h>
16
#include <linux/init.h>
17
#include <linux/slab.h>
18
#include <linux/vmalloc.h>
19
#include <linux/pagemap.h>
20
#include <linux/memblock.h>
21
#include <linux/mount.h>
22
#include <linux/blkdev.h>
23
#include <linux/module.h>
24
#include <linux/ioport.h>
25
26
#include <asm/setup.h>
27
#include <asm/machdep.h>
28
#include <asm/page.h>
29
#include <asm/atarihw.h>
30
#include <asm/atari_stram.h>
31
#include <asm/io.h>
32
33
34
/*
35
* The ST-RAM allocator allocates memory from a pool of reserved ST-RAM of
36
* configurable size, set aside on ST-RAM init.
37
* As long as this pool is not exhausted, allocation of real ST-RAM can be
38
* guaranteed.
39
*/
40
41
/* set if kernel is in ST-RAM */
42
static int kernel_in_stram;
43
44
static struct resource stram_pool = {
45
.name = "ST-RAM Pool"
46
};
47
48
static unsigned long pool_size = 1024*1024;
49
50
static unsigned long stram_virt_offset;
51
52
static int __init atari_stram_setup(char *arg)
53
{
54
if (!MACH_IS_ATARI)
55
return 0;
56
57
pool_size = memparse(arg, NULL);
58
return 0;
59
}
60
61
early_param("stram_pool", atari_stram_setup);
62
63
64
/*
65
* This init function is called very early by atari/config.c
66
* It initializes some internal variables needed for stram_alloc()
67
*/
68
void __init atari_stram_init(void)
69
{
70
int i;
71
72
/*
73
* determine whether kernel code resides in ST-RAM
74
* (then ST-RAM is the first memory block at virtual 0x0)
75
*/
76
kernel_in_stram = (m68k_memory[0].addr == 0);
77
78
for (i = 0; i < m68k_num_memory; ++i) {
79
if (m68k_memory[i].addr == 0) {
80
return;
81
}
82
}
83
84
/* Should never come here! (There is always ST-Ram!) */
85
panic("atari_stram_init: no ST-RAM found!");
86
}
87
88
89
/*
90
* This function is called from setup_arch() to reserve the pages needed for
91
* ST-RAM management, if the kernel resides in ST-RAM.
92
*/
93
void __init atari_stram_reserve_pages(void *start_mem)
94
{
95
if (kernel_in_stram) {
96
pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n");
97
stram_pool.start = (resource_size_t)memblock_alloc_low(pool_size,
98
PAGE_SIZE);
99
if (!stram_pool.start)
100
panic("%s: Failed to allocate %lu bytes align=%lx\n",
101
__func__, pool_size, PAGE_SIZE);
102
103
stram_pool.end = stram_pool.start + pool_size - 1;
104
request_resource(&iomem_resource, &stram_pool);
105
stram_virt_offset = 0;
106
pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
107
pool_size, &stram_pool);
108
pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
109
stram_virt_offset);
110
}
111
}
112
113
114
/*
115
* This function is called as arch initcall to reserve the pages needed for
116
* ST-RAM management, if the kernel does not reside in ST-RAM.
117
*/
118
static int __init atari_stram_map_pages(void)
119
{
120
if (!kernel_in_stram) {
121
/*
122
* Skip page 0, as the fhe first 2 KiB are supervisor-only!
123
*/
124
pr_debug("atari_stram pool: kernel not in ST-RAM, using ioremap!\n");
125
stram_pool.start = PAGE_SIZE;
126
stram_pool.end = stram_pool.start + pool_size - 1;
127
request_resource(&iomem_resource, &stram_pool);
128
stram_virt_offset = (unsigned long) ioremap(stram_pool.start,
129
resource_size(&stram_pool)) - stram_pool.start;
130
pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
131
pool_size, &stram_pool);
132
pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
133
stram_virt_offset);
134
}
135
return 0;
136
}
137
arch_initcall(atari_stram_map_pages);
138
139
140
void *atari_stram_to_virt(unsigned long phys)
141
{
142
return (void *)(phys + stram_virt_offset);
143
}
144
EXPORT_SYMBOL(atari_stram_to_virt);
145
146
147
unsigned long atari_stram_to_phys(void *virt)
148
{
149
return (unsigned long)(virt - stram_virt_offset);
150
}
151
EXPORT_SYMBOL(atari_stram_to_phys);
152
153
154
void *atari_stram_alloc(unsigned long size, const char *owner)
155
{
156
struct resource *res;
157
int error;
158
159
pr_debug("atari_stram_alloc: allocate %lu bytes\n", size);
160
161
/* round up */
162
size = PAGE_ALIGN(size);
163
164
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
165
if (!res)
166
return NULL;
167
168
res->name = owner;
169
error = allocate_resource(&stram_pool, res, size, 0, UINT_MAX,
170
PAGE_SIZE, NULL, NULL);
171
if (error < 0) {
172
pr_err("atari_stram_alloc: allocate_resource() failed %d!\n",
173
error);
174
kfree(res);
175
return NULL;
176
}
177
178
pr_debug("atari_stram_alloc: returning %pR\n", res);
179
return atari_stram_to_virt(res->start);
180
}
181
EXPORT_SYMBOL(atari_stram_alloc);
182
183
184
void atari_stram_free(void *addr)
185
{
186
unsigned long start = atari_stram_to_phys(addr);
187
struct resource *res;
188
unsigned long size;
189
190
res = lookup_resource(&stram_pool, start);
191
if (!res) {
192
pr_err("atari_stram_free: trying to free nonexistent region "
193
"at %p\n", addr);
194
return;
195
}
196
197
size = resource_size(res);
198
pr_debug("atari_stram_free: free %lu bytes at %p\n", size, addr);
199
release_resource(res);
200
kfree(res);
201
}
202
EXPORT_SYMBOL(atari_stram_free);
203
204