summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/leon3/amba/amba.c
blob: ffcabf0497e7cc8a3a0d1bec1d113128fb46eab7 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 *  AMBA Plag & Play Bus Driver
 *
 *  This driver hook performs bus scanning.
 *
 *  COPYRIGHT (c) 2004.
 *  Gaisler Research
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */

#include <bsp.h>

#define amba_insert_device(tab, address) \
{ \
  if (*(address)) \
  { \
    (tab)->addr[(tab)->devnr] = (address); \
    (tab)->devnr ++; \
  } \
} while(0)


/* Structure containing address to devices found on the Amba Plug&Play bus */
amba_confarea_type amba_conf;

/* Pointers to Interrupt Controller configuration registers */
volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;

int LEON3_Cpu_Index = 0;
static int apb_init = 0;

/*
 *  bsp_leon3_predriver_hook
 *
 *  BSP predriver hook.  Called just before drivers are initialized.
 *  Used to scan system bus. Probes for AHB masters, AHB slaves and 
 *  APB slaves. Addresses to configuration areas of the AHB masters,
 *  AHB slaves, APB slaves and APB master are storeds in 
 *  amba_ahb_masters, amba_ahb_slaves and amba.
 */

unsigned int getasr17();

asm(" .text  \n"
    "getasr17:   \n"
    "retl \n"
    "mov %asr17, %o0\n"
);
    
      
extern rtems_configuration_table Configuration;

void bsp_leon3_predriver_hook(void)
{
  unsigned int *cfg_area;  /* address to configuration area */
  unsigned int mbar, iobar, conf;
  int i, j;
  unsigned int tmp;

  amba_conf.ahbmst.devnr = 0; amba_conf.ahbslv.devnr = 0; amba_conf.apbslv.devnr = 0;
  cfg_area = (unsigned int *) (LEON3_IO_AREA | LEON3_CONF_AREA);

  for (i = 0; i < LEON3_AHB_MASTERS; i++) 
  {
    amba_insert_device(&amba_conf.ahbmst, cfg_area);
    cfg_area += LEON3_AHB_CONF_WORDS;
  }

  cfg_area = (unsigned int *) (LEON3_IO_AREA | LEON3_CONF_AREA | LEON3_AHB_SLAVE_CONF_AREA);
  for (i = 0; i < LEON3_AHB_SLAVES; i++) 
  {
    amba_insert_device(&amba_conf.ahbslv, cfg_area);
    cfg_area += LEON3_AHB_CONF_WORDS;
  }  

  for (i = 0; i < amba_conf.ahbslv.devnr; i ++) 
  {
    conf = amba_get_confword(amba_conf.ahbslv, i, 0);
    mbar = amba_ahb_get_membar(amba_conf.ahbslv, i, 0);
    if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBMST) &&
	(apb_init == 0))
    {
      amba_conf.apbmst = amba_membar_start(mbar);
      cfg_area = (unsigned int *) (amba_conf.apbmst | LEON3_CONF_AREA);
      for (j = amba_conf.apbslv.devnr; j < LEON3_APB_SLAVES; j++)
      {
	amba_insert_device(&amba_conf.apbslv, cfg_area);
	cfg_area += LEON3_APB_CONF_WORDS;
      }
      apb_init = 1;
    }
  }    

  /* Find LEON3 Interrupt controler */
  i = 0;
  while (i < amba_conf.apbslv.devnr) 
  {
    conf = amba_get_confword(amba_conf.apbslv, i, 0);
    if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_IRQMP))
    {
      iobar = amba_apb_get_membar(amba_conf.apbslv, i);
      LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *) amba_iobar_start(amba_conf.apbmst, iobar);
      /* asm("mov %%asr17, %0": : "r" (tmp)); */
      if (Configuration.User_multiprocessing_table != NULL)
      {	
	tmp = getasr17();
	LEON3_Cpu_Index = (tmp >> 28) & 3;
      }
      break;
    }
    i++;
  }
  /* find GP Timer */
  i = 0;
 while (i < amba_conf.apbslv.devnr) 
  {
    conf = amba_get_confword(amba_conf.apbslv, i, 0);
    if ((amba_vendor(conf) == VENDOR_GAISLER) &&
       (amba_device(conf) == GAISLER_GPTIMER)) {
      iobar = amba_apb_get_membar(amba_conf.apbslv, i);      
      LEON3_Timer_Regs = (volatile LEON3_Timer_Regs_Map *)
        amba_iobar_start(amba_conf.apbmst, iobar);
      break;
    }
    i++;
  }

}