summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/gen68360/startup/alloc360.c
blob: e8c3385bf71e9abe47cda352ab537226c06eb50f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
 * MC68360 buffer descriptor allocation routines
 *
 * W. Eric Norum
 * Saskatchewan Accelerator Laboratory
 * University of Saskatchewan
 * Saskatoon, Saskatchewan, CANADA
 * eric@skatter.usask.ca
 *
 *  $Id$
 */

#include <rtems.h>
#include <bsp.h>
#include <rtems/m68k/m68360.h>
#include <rtems/error.h>

/*
 * Allocation order:
 *	- Dual-Port RAM section 1
 *	- Dual-Port RAM section 3
 *	- Dual-Port RAM section 0
 *	- Dual-Port RAM section 2
 */
static struct {
	uint8_t        *base;
	uint32_t	size;
	uint32_t	used;
} bdregions[] = {
	{ (uint8_t *)&m360.dpram1[0],	sizeof m360.dpram1,	0 },
	{ (uint8_t *)&m360.dpram3[0],	sizeof m360.dpram3,	0 },
	{ (uint8_t *)&m360.dpram0[0],	sizeof m360.dpram0,	0 },
	{ (uint8_t *)&m360.dpram2[0],	sizeof m360.dpram2,	0 },
};

/*
 * Send a command to the CPM RISC processer
 */
void *
M360AllocateBufferDescriptors (int count)
{
	unsigned int i;
	ISR_Level level;
	void *bdp = NULL;
	unsigned int want = count * sizeof(m360BufferDescriptor_t);

	/*
	 * Running with interrupts disabled is usually considered bad
	 * form, but this routine is probably being run as part of an
	 * initialization sequence so the effect shouldn't be too severe.
	 */
	_ISR_Disable (level);
	for (i = 0 ; i < sizeof(bdregions) / sizeof(bdregions[0]) ; i++) {
		/*
		 * Verify that the region exists.
		 * This test is necessary since some chips have
		 * less dual-port RAM.
		 */
		if (bdregions[i].used == 0) {
			volatile uint8_t *cp = bdregions[i].base;
			*cp = 0xAA;
			if (*cp != 0xAA) {
				bdregions[i].used = bdregions[i].size;
				continue;
			}
			*cp = 0x55;
			if (*cp != 0x55) {
				bdregions[i].used = bdregions[i].size;
				continue;
			}
			*cp = 0x0;
		}
		if (bdregions[i].size - bdregions[i].used >= want) {
			bdp = bdregions[i].base + bdregions[i].used;
			bdregions[i].used += want;
			break;
		}
	}
	_ISR_Enable (level);
	if (bdp == NULL)
		rtems_panic ("Can't allocate %d buffer descriptor(s).\n", count);
	return bdp;
}

void *
M360AllocateRiscTimers (int count)
{
	/*
	 * Convert the count to the number of buffer descriptors
	 * of equal or larger size.  This ensures that all buffer
	 * descriptors are allocated with appropriate alignment.
	 */
	return M360AllocateBufferDescriptors (((count * 4) +
					sizeof(m360BufferDescriptor_t) - 1) /
					sizeof(m360BufferDescriptor_t));
}