summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc8260/cpm/dpram.c
blob: 7fb8f512a641547999b1565875b23d27dff01ffa (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
/*
 * dpram.c
 *
 * MPC8260 dual-port RAM allocation routines
 *
 * Based on code in mpc8xx which is
 * Based on code (alloc860.c in eth_comm port) by
 * Jay Monkman (jmonkman@frasca.com),
 * which, in turn, is based on code by
 * W. Eric Norum (eric@skatter.usask.ca).
 *
 *
 * Modifications :
 * Copyright (c) 1999, National Research Council of Canada
 *
 * MPC8260 modifications Andy Dachs, <a.dachs@sstl.co.uk>
 * Surrey Satellite Technology Limited, 2001
 */

#include <rtems.h>
#include <mpc8260.h>
#include <mpc8260/cpm.h>

/*
 * Allocation order:
 *      - Dual-Port RAM section 0
 *      - Dual-Port RAM section 1
 *      - Dual-Port RAM section 2
 *      - Dual-Port RAM section 3
 */
static struct {
  unsigned8     *base;
  unsigned int  size;
  unsigned int  used;
} dpram_regions[] = {
/*  { (char *)&m8260.dpram0[0],    sizeof m8260.dpram0,     0 },*/
  { (char *)&m8260.dpram1[0],    sizeof m8260.dpram1,     0 },
/*  { (char *)&m8260.dpram2[0],    sizeof m8260.dpram2,     0 },*/
  { (char *)&m8260.dpram3[0],    sizeof m8260.dpram3,     0 }
};

#define	NUM_DPRAM_REGIONS	(sizeof(dpram_regions) / sizeof(dpram_regions[0]))

void *
m8xx_dpram_allocate( unsigned int byte_count )
{
  unsigned int i;
  ISR_Level level;
  void *blockp = NULL;
  
  byte_count = (byte_count + 3) & ~0x3;
  
  /*
   * 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 < NUM_DPRAM_REGIONS; i++ ) {
    /*
     * Verify that the region is available for use.
     * This test is necessary because if extra microcode modules
     * are installed, some regions are locked and unavailable.
     * See MPC860 User's Manual Pages 19-9 to 19-11.
     */
    if (dpram_regions[i].used == 0) {
      volatile unsigned char *cp = dpram_regions[i].base;
      *cp = 0xAA;
      if (*cp != 0xAA)
        dpram_regions[i].used = dpram_regions[i].size;
      else {
        *cp = 0x55;
        if (*cp != 0x55)
          dpram_regions[i].used = dpram_regions[i].size;
      }
      *cp = 0x0;
    }
    if (dpram_regions[i].size - dpram_regions[i].used >= byte_count) {
      blockp = dpram_regions[i].base + dpram_regions[i].used;
      dpram_regions[i].used += byte_count;
      break;
    }
  }
  
  _ISR_Enable(level);
  
  if (blockp == NULL)
    rtems_panic("Can't allocate %d bytes of dual-port RAM.\n", byte_count);
  return blockp;
}