This source file includes following definitions.
- amiga_chip_init
- amiga_chip_alloc
- amiga_chip_free
1
2
3
4
5
6
7
8
9 #include <linux/types.h>
10 #include <linux/kernel.h>
11 #include <asm/bootinfo.h>
12 #include <asm/amigahw.h>
13
14 struct chip_desc {
15 unsigned first : 1;
16 unsigned last : 1;
17 unsigned alloced : 1;
18 unsigned length : 24;
19 long pad;
20 };
21
22 #define DP(ptr) ((struct chip_desc *)(ptr))
23
24 static unsigned long chipsize;
25
26 void amiga_chip_init (void)
27 {
28 struct chip_desc *dp;
29
30 if (!AMIGAHW_PRESENT(CHIP_RAM))
31 return;
32
33 chipsize = boot_info.bi_amiga.chip_size;
34
35
36
37 custom.color[0] = 0xfff;
38
39 dp = DP(chipaddr);
40 dp->first = 1;
41
42 custom.color[0] = 0x0f00;
43
44 dp->alloced = 0;
45 dp->length = chipsize - 2*sizeof(*dp);
46
47
48 dp = DP(chipaddr + chipsize) - 1;
49 dp->last = 1;
50
51 custom.color[0] = 0x00f0;
52
53 dp->alloced = 0;
54 dp->length = chipsize - 2*sizeof(*dp);
55
56 custom.color[0] = 0x000f;
57
58 #ifdef DEBUG
59 printk ("chipram end boundary is %p, length is %d\n", dp,
60 dp->length);
61 #endif
62 }
63
64 void *amiga_chip_alloc (long size)
65 {
66
67 struct chip_desc *dp;
68 void *ptr;
69
70
71 size = (size + 7) & ~7;
72
73 #ifdef DEBUG
74 printk ("chip_alloc: allocate %ld bytes\n", size);
75 #endif
76
77
78
79
80
81 dp = DP(chipaddr + chipsize) - 1;
82 dp = DP((unsigned long)dp - dp->length) - 1;
83
84 while ((dp->alloced || dp->length < size)
85 && !dp->first)
86 dp = DP ((unsigned long)dp - dp[-1].length) - 2;
87
88 if (dp->alloced || dp->length < size) {
89 printk ("no chipmem available for %ld allocation\n", size);
90 return NULL;
91 }
92
93 if (dp->length < (size + 2*sizeof(*dp))) {
94
95 dp->alloced = 1;
96 ptr = (void *)(dp+1);
97 dp = DP((unsigned long)ptr + dp->length);
98 dp->alloced = 1;
99 #ifdef DEBUG
100 printk ("chip_alloc: no split\n");
101 #endif
102 } else {
103
104 long newsize = dp->length - (2*sizeof(*dp) + size);
105
106 #ifdef DEBUG
107 printk ("chip_alloc: splitting %d to %ld\n", dp->length,
108 newsize);
109 #endif
110 dp->length = newsize;
111 dp = DP((unsigned long)(dp+1) + newsize);
112 dp->first = dp->last = 0;
113 dp->alloced = 0;
114 dp->length = newsize;
115 dp++;
116 dp->first = dp->last = 0;
117 dp->alloced = 1;
118 dp->length = size;
119 ptr = (void *)(dp+1);
120 dp = DP((unsigned long)ptr + size);
121 dp->alloced = 1;
122 dp->length = size;
123 }
124
125 #ifdef DEBUG
126 printk ("chip_alloc: returning %p\n", ptr);
127 #endif
128
129 if ((unsigned long)ptr & 7)
130 panic("chip_alloc: alignment violation\n");
131
132 return ptr;
133 }
134
135 void amiga_chip_free (void *ptr)
136 {
137 struct chip_desc *sdp = DP(ptr) - 1, *dp2;
138 struct chip_desc *edp = DP((unsigned long)ptr + sdp->length);
139
140
141 sdp->alloced = edp->alloced = 0;
142
143
144 if (!sdp->first && !sdp[-1].alloced) {
145 dp2 = DP((unsigned long)sdp - sdp[-1].length) - 2;
146 dp2->length += sdp->length + 2*sizeof(*sdp);
147 edp->length = dp2->length;
148 sdp = dp2;
149 }
150
151
152 if (!edp->last && !edp[1].alloced) {
153 dp2 = DP((unsigned long)edp + edp[1].length) + 2;
154 dp2->length += edp->length + 2*sizeof(*sdp);
155 sdp->length = dp2->length;
156 edp = dp2;
157 }
158 }