Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/m68k/amiga/chipram.c
10817 views
1
/*
2
** linux/amiga/chipram.c
3
**
4
** Modified 03-May-94 by Geert Uytterhoeven <[email protected]>
5
** - 64-bit aligned allocations for full AGA compatibility
6
**
7
** Rewritten 15/9/2000 by Geert to use resource management
8
*/
9
10
#include <linux/types.h>
11
#include <linux/kernel.h>
12
#include <linux/mm.h>
13
#include <linux/init.h>
14
#include <linux/ioport.h>
15
#include <linux/slab.h>
16
#include <linux/string.h>
17
#include <linux/module.h>
18
19
#include <asm/page.h>
20
#include <asm/amigahw.h>
21
22
unsigned long amiga_chip_size;
23
EXPORT_SYMBOL(amiga_chip_size);
24
25
static struct resource chipram_res = {
26
.name = "Chip RAM", .start = CHIP_PHYSADDR
27
};
28
static unsigned long chipavail;
29
30
31
void __init amiga_chip_init(void)
32
{
33
if (!AMIGAHW_PRESENT(CHIP_RAM))
34
return;
35
36
chipram_res.end = amiga_chip_size-1;
37
request_resource(&iomem_resource, &chipram_res);
38
39
chipavail = amiga_chip_size;
40
}
41
42
43
void *amiga_chip_alloc(unsigned long size, const char *name)
44
{
45
struct resource *res;
46
47
/* round up */
48
size = PAGE_ALIGN(size);
49
50
#ifdef DEBUG
51
printk("amiga_chip_alloc: allocate %ld bytes\n", size);
52
#endif
53
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
54
if (!res)
55
return NULL;
56
res->name = name;
57
58
if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
59
kfree(res);
60
return NULL;
61
}
62
chipavail -= size;
63
#ifdef DEBUG
64
printk("amiga_chip_alloc: returning %lx\n", res->start);
65
#endif
66
return (void *)ZTWO_VADDR(res->start);
67
}
68
EXPORT_SYMBOL(amiga_chip_alloc);
69
70
71
/*
72
* Warning:
73
* amiga_chip_alloc_res is meant only for drivers that need to allocate
74
* Chip RAM before kmalloc() is functional. As a consequence, those
75
* drivers must not free that Chip RAM afterwards.
76
*/
77
78
void * __init amiga_chip_alloc_res(unsigned long size, struct resource *res)
79
{
80
unsigned long start;
81
82
/* round up */
83
size = PAGE_ALIGN(size);
84
/* dmesg into chipmem prefers memory at the safe end */
85
start = CHIP_PHYSADDR + chipavail - size;
86
87
#ifdef DEBUG
88
printk("amiga_chip_alloc_res: allocate %ld bytes\n", size);
89
#endif
90
if (allocate_resource(&chipram_res, res, size, start, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
91
printk("amiga_chip_alloc_res: first alloc failed!\n");
92
if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0)
93
return NULL;
94
}
95
chipavail -= size;
96
#ifdef DEBUG
97
printk("amiga_chip_alloc_res: returning %lx\n", res->start);
98
#endif
99
return (void *)ZTWO_VADDR(res->start);
100
}
101
102
void amiga_chip_free(void *ptr)
103
{
104
unsigned long start = ZTWO_PADDR(ptr);
105
struct resource **p, *res;
106
unsigned long size;
107
108
for (p = &chipram_res.child; (res = *p); p = &res->sibling) {
109
if (res->start != start)
110
continue;
111
*p = res->sibling;
112
size = res->end-start;
113
#ifdef DEBUG
114
printk("amiga_chip_free: free %ld bytes at %p\n", size, ptr);
115
#endif
116
chipavail += size;
117
kfree(res);
118
return;
119
}
120
printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr);
121
}
122
EXPORT_SYMBOL(amiga_chip_free);
123
124
125
unsigned long amiga_chip_avail(void)
126
{
127
#ifdef DEBUG
128
printk("amiga_chip_avail : %ld bytes\n", chipavail);
129
#endif
130
return chipavail;
131
}
132
EXPORT_SYMBOL(amiga_chip_avail);
133
134
135