source: rtems/bsps/powerpc/beatnik/start/bspstart.c @ 762fa62

5
Last change on this file since 762fa62 was 65f868c, checked in by Sebastian Huber <sebastian.huber@…>, on 05/23/18 at 12:17:25

Add _CPU_Counter_frequency()

Add rtems_counter_frequency() API function. Use it to initialize the
counter value converter via the new system initialization step
(RTEMS_SYSINIT_CPU_COUNTER). This decouples the counter implementation
and the counter converter. It avoids an unnecessary pull in of the
64-bit integer division from libgcc.

Update #3456.

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/*
2 *  This routine does the bulk of the system initialization.
3 */
4
5/*
6 *  COPYRIGHT (c) 1989-1998.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.OARcorp.com/rtems/license.html.
12 *
13 *  Modified to support the MCP750.
14 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
15 *
16 *  Modified to support the Synergy VGM & Motorola PowerPC boards.
17 *  (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
18 *
19 *  Modified to support the mvme5500 BSP
20 *  (C) by Kate Feng <feng1@bnl.gov>, 2003, 2004
21 *      under the contract DE-AC02-98CH10886 with the Deaprtment of Energy
22 *
23 *  T. Straumann: 2005-2007; stolen again for 'beatnik'...
24 */
25#include <string.h>
26#include <stdlib.h>
27#include <ctype.h>
28
29#include <rtems/system.h>
30#include <rtems/libio.h>
31#include <rtems/libcsupport.h>
32#include <rtems/bspIo.h>
33#include <rtems/counter.h>
34#include <rtems/powerpc/powerpc.h>
35#include <rtems/sysinit.h>
36/*#include <bsp/consoleIo.h>*/
37#include <libcpu/spr.h>   /* registers.h is included here */
38#include <bsp.h>
39#include <bsp/bootcard.h>
40#include <bsp/uart.h>
41#include <bsp/pci.h>
42#include <bsp/gtreg.h>
43#include <bsp/gt_timer.h>
44#include <libcpu/bat.h>
45#include <libcpu/pte121.h>
46#include <libcpu/cpuIdent.h>
47#include <bsp/vectors.h>
48#include <bsp/VME.h>
49#include <bsp/vpd.h>
50
51#define SHOW_MORE_INIT_SETTINGS
52
53BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
54BSP_polling_getchar_function_type BSP_poll_char = NULL;
55
56extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
57extern void BSP_pgtbl_activate(Triv121PgTbl);
58extern void BSP_motload_pci_fixup(void);
59
60extern unsigned long __rtems_end[];
61
62/* We really shouldn't use these since MMUoff also sets IP;
63 * nevertheless, during early init I don't care for now
64 */
65extern void MMUoff(void);
66extern void MMUon(void);
67
68extern uint32_t probeMemoryEnd(void);
69
70SPR_RW(SPRG0)
71SPR_RW(SPRG1)
72SPR_RO(HID1)
73
74/* Table of PLL multipliers for 7455/7457:
7501000   2     00010   7.5       00000   11.5      00001   17
7610000   3     11000   8         10111   12        00101   18
7710100   4     01100   8.5       11111   12.5      00111   20
7810110   5     01111   9         01011   13        01001   21
7910010   5.5   01110   9.5       11100   13.5      01101   24
8011010   6     10101   10        11001   14        11101   28
8101010   6.5   10001   10.5      00011   15        00110   bypass
8200100   7     10011   11        11011   16        11110   off
83*/
84
85/* Sorted according to CFG bits and multiplied by 2 it looks
86 * like this (note that this is in sequential order, not
87 * tabulated as above)
88 */
89signed char mpc7450PllMultByTwo[32] = {
9023,       34,           15,           30,
9114,       36,           2/*bypass*/,  40,
924,        42,           13,           26,
9317,       48,           19,           18,
946,        21,           11,           22,
958,        20,           10,           24,
9616,       28,           12,           32,
9727,       56,           0/*off*/,     25,
98};
99
100uint32_t bsp_clicks_per_usec         = 0;
101
102/*
103 * Total memory using probing.
104 */
105unsigned int BSP_mem_size;
106
107/*
108 * PCI Bus Frequency
109 */
110unsigned int BSP_bus_frequency       = 0xdeadbeef;
111/*
112 * processor clock frequency
113 */
114unsigned int BSP_processor_frequency = 0xdeadbeef;
115
116/*
117 * Time base divisior (bus freq / TB clock)
118 */
119unsigned int BSP_time_base_divisor   = 4000; /* most 604+ CPUs seem to use this */
120
121/* Board identification string */
122char BSP_productIdent[20] = {0};
123char BSP_serialNumber[20] = {0};
124
125/* VPD appends an extra char -- what for ? */
126char BSP_enetAddr0[7] = {0};
127char BSP_enetAddr1[7] = {0};
128
129char *rtems_progname;
130
131#define CMDLINE_BUF_SIZE        2048
132
133static char cmdline_buf[CMDLINE_BUF_SIZE];
134char *BSP_commandline_string = cmdline_buf;
135
136/* this routine is called early and must be safe with a not properly
137 * aligned stack
138 */
139char *save_boot_params(
140  void *r3,
141  void *r4,
142  void *r5,
143  char *cmdline_start,
144  char *cmdline_end
145)
146{
147int             i=cmdline_end-cmdline_start;
148        if ( i >= CMDLINE_BUF_SIZE )
149                i = CMDLINE_BUF_SIZE-1;
150        else if ( i < 0 )
151                i = 0;
152        memmove(cmdline_buf, cmdline_start, i);
153        cmdline_buf[i]=0;
154    return cmdline_buf;
155}
156
157static BSP_BoardType    board_type = Unknown;
158
159BSP_BoardType
160BSP_getBoardType( void )
161{
162        return board_type;
163}
164
165uint32_t _CPU_Counter_frequency(void)
166{
167  return BSP_bus_frequency / (BSP_time_base_divisor / 1000);
168}
169
170/*
171 *  bsp_start
172 *
173 *  This routine does the bulk of the system initialization.
174 */
175
176void bsp_start( void )
177{
178  unsigned char  *stack;
179  char           *chpt;
180  uint32_t       intrStackStart;
181  uint32_t       intrStackSize;
182
183  Triv121PgTbl  pt=0;
184
185  VpdBufRec vpdData [] = {
186        { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
187        { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
188        { key: CpuClockHz,   instance: 0, buf: &BSP_processor_frequency, buflen: sizeof(BSP_processor_frequency)  },
189        { key: BusClockHz,   instance: 0, buf: &BSP_bus_frequency, buflen: sizeof(BSP_bus_frequency)  },
190        { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
191        { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
192        VPD_END
193  };
194
195  /* T. Straumann: 4/2005
196   *
197   * Need to map the system registers early, so we can printk...
198   * (otherwise we silently die)
199   */
200  /* map the PCI 0, 1 Domain I/O space, GT64260B registers
201   * and the reserved area so that the size is the power of 2.
202   */
203  setdbat(7, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_SIZE, IO_PAGE);
204
205  /* Intersperse messages with actions to help locate problems */
206  printk("-----------------------------------------\n");
207
208  /*
209   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() & friends functions
210   * store the result in global variables so that it can be used latter...
211   * This also verifies that we run on a known CPU.
212   */
213  get_ppc_cpu_type();
214  get_ppc_cpu_revision();
215
216  /* Make sure we detect a known host bridge */
217  BSP_getDiscoveryVersion(/* assert detection */ 1);
218
219  printk("Welcome to RTEMS %s\n", _RTEMS_version );
220
221  /* Leave all caches as MotLoad left them. Seems to be fine */
222
223  /*
224   * the initial stack  has aready been set to this value in start.S
225   * so there is no need to set it in r1 again... It is just for info
226   * so that it can be printed without accessing R1.
227   */
228  __asm__ volatile("mr %0, 1":"=r"(stack));
229
230  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
231
232  *((uint32_t *)stack) = 0;
233
234  /*
235   * Initialize the interrupt related settings
236   * SPRG0 = interrupt nesting level count
237   * SPRG1 = software managed IRQ stack
238   *
239   * This could be done latter (e.g in IRQ_INIT) but it helps to understand
240   * some settings below...
241   */
242  intrStackStart = (uint32_t)__rtems_end;
243  intrStackSize  = rtems_configuration_get_interrupt_stack_size();
244
245  /*
246   * Initialize default raw exception handlers. See vectors/vectors_init.c
247   */
248  ppc_exc_initialize(intrStackStart, intrStackSize);
249
250  printk("CPU: %s\n", get_ppc_cpu_type_name(current_ppc_cpu));
251
252  /*
253   * Initialize RTEMS IRQ system
254   */
255   BSP_rtems_irq_mng_init(0);
256
257  BSP_vpdRetrieveFields(vpdData);
258
259  if ( !strncmp(BSP_productIdent,"MVME5500",8) )
260        board_type = MVME5500;
261  else if ( !strncmp(BSP_productIdent,"MVME6100",8) )
262        board_type = MVME6100;
263
264  printk("Board Type: %s (S/N %s)\n",
265                BSP_productIdent[0] ? BSP_productIdent : "n/a",
266                BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
267
268  if ( 0xdeadbeef == BSP_bus_frequency ) {
269        BSP_bus_frequency       = 133333333;
270        printk("Bus Clock Freq NOT FOUND in VPD; using %10u Hz\n",
271                BSP_bus_frequency);
272  } else {
273        printk("Bus Clock Freq:  %10u Hz\n",
274                BSP_bus_frequency);
275  }
276
277  if ( 0xdeadbeef == BSP_processor_frequency ) {
278        BSP_processor_frequency  = BSP_bus_frequency/2;
279        BSP_processor_frequency *= mpc7450PllMultByTwo[ (_read_HID1() >> (31-19)) & 31 ];
280  }
281  printk("CPU Clock Freq:  %10u Hz\n", BSP_processor_frequency);
282       
283  /* probe real memory size; if it's more than 256M we can't currently access it
284   * since at this point only BAT-0 maps 0..256M
285   */
286  BSP_mem_size                          =  probeMemoryEnd();
287
288  if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
289                char            *endp;
290                uint32_t        sz;
291                chpt+=6 /* strlen("MEMSZ=") */;
292                sz = strtoul(chpt, &endp, 0);
293                if ( endp != chpt )
294                        BSP_mem_size = sz;
295  }
296
297  printk("Memory:          %10u bytes\n", BSP_mem_size);
298
299  if ( BSP_mem_size > 0x10000000 ) {
300        uint32_t s;
301        if ( BSP_mem_size > 0x80000000 ) {
302                BSP_mem_size = 0x80000000;
303                printk("Memory clipped to 0x%08x for now, sorry\n", BSP_mem_size);
304        }
305        for ( s = 0x20000000; s < BSP_mem_size ; s<<=1)
306                ;
307        MMUoff();
308        /* since it's currently in use we must first surrender it */
309        setdbat(0, 0, 0, 0, 0);
310        setdbat(0, 0, 0, s, _PAGE_RW);
311        MMUon();
312  }
313
314  printk("-----------------------------------------\n");
315
316  /* Maybe not setup yet because of the warning message */
317
318  /* Allocate and set up the page table mappings
319   * This is only available on >604 CPUs.
320   *
321   * NOTE: This setup routine may modify the available memory
322   *       size. It is essential to call it before
323   *       calculating the workspace etc.
324   */
325  pt = BSP_pgtbl_setup(&BSP_mem_size);
326  if (!pt)
327     printk("WARNING: unable to setup page tables.\n");
328
329#ifdef SHOW_MORE_INIT_SETTINGS
330  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
331#endif
332
333  /*
334   * Set up our hooks
335   */
336
337  bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
338
339#ifdef SHOW_MORE_INIT_SETTINGS
340  printk(
341    "Configuration.work_space_size = %x\n",
342    rtems_configuration_get_work_space_size()
343  );
344#endif
345
346  /* Activate the page table mappings only after
347   * initializing interrupts because the irq_mng_init()
348   * routine needs to modify the text
349   */           
350  if ( pt ) {
351#ifdef SHOW_MORE_INIT_SETTINGS
352    printk("Page table setup finished; will activate it NOW...\n");
353#endif
354    BSP_pgtbl_activate(pt);
355  }
356
357#ifdef SHOW_MORE_INIT_SETTINGS
358  printk("Going to start PCI buses scanning and initialization\n");
359#endif
360  BSP_pci_initialize();
361
362  /* need to tweak the motload setup */
363  BSP_motload_pci_fixup();
364
365  /* map 512M, 256 for PCI 256 for VME */
366  setdbat(5,BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_SIZE, IO_PAGE);
367  setdbat(6,BSP_PCI_HOSE1_MEM_BASE, BSP_PCI_HOSE1_MEM_BASE, 0x10000000, IO_PAGE);
368
369#ifdef SHOW_MORE_INIT_SETTINGS
370  printk("Number of PCI buses found is : %d\n", pci_bus_count());
371#endif
372
373  /*
374   * Initialize hardware timer facility (not used by BSP itself)
375   * Needs PCI to identify discovery version...
376   */
377  BSP_timers_initialize();
378
379#ifdef SHOW_MORE_INIT_SETTINGS
380  printk("MSR 0x%lx \n", _read_MSR());
381  printk("Exit from bspstart\n");
382#endif
383}
384
385RTEMS_SYSINIT_ITEM(
386  BSP_vme_config,
387  RTEMS_SYSINIT_BSP_PRE_DRIVERS,
388  RTEMS_SYSINIT_ORDER_MIDDLE
389);
Note: See TracBrowser for help on using the repository browser.