summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/mvme167/startup/page_table.c
blob: ebbcc9739df22f4ec6d566a8bae4c52c4033a3a2 (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
136
137
138
139
/*  page_table.c
 *
 *  The code submitted by Eric Vaitl <vaitl@viasat.com> for the MVME162 appears
 *  to be for a uniprocessor implementation. The function that sets up the
 *  page tables, page_table_init(), is not data driven. For all processors, it
 *  sets up page tables to map virtual addresses from 0x20000 to 0x3FFFFF to
 *  physical addresses 0x20000 to 0x3FFFFF. This presumably maps a subset of
 *  a local 4 MB space, which is probably the amount of RAM on Eric Vailt's
 *  MVME162.
 *
 *  It is possible to set up the various bus bridges in the MVME167s to create
 *  a flat physical address space across multiple boards, i.e., it is possible
 *  for each MVME167 in a multiprocessor system to access a given memory
 *  location using the same physical address, whether that location is in local
 *  or VME space. Addres translation can be set up so that each virtual address
 *  maps to its corresponding physical address, e.g. virtual address 0x12345678
 *  is mapped to physical address 0x12345678. With this mapping, the MMU is
 *  only used to control the caching modes for the various regions of memory.
 *  Mapping the virtual addresses to their corresponding physical address makes
 *  it unnecessary to map addresses under software control during the 
 *  initialization of RTEMS, before address translation is turned on.
 *
 *  With the above approach, address translation may be set up either with the
 *  transparent address translation registers, or with page tables. If page
 *  tables are used, a more efficient use of page table space can be achieved
 *  by sharing the page tables between processors. The entire page table tree
 *  can be shared, or each processor can hold a private copy of the top nodes
 *  which point to leaf nodes stored on individual processors.
 *
 *  In this port, only the transparent address translation registers are used.
 *  We map the entire virtual range from 0x0 to 0x7FFFFFFF to the identical
 *  physical range 0x0 to 0x7FFFFFFF. We rely on the hardware to signal bus
 *  errors if we address non-existent memory within this range. Our two
 *  MVME167s are configured to exist at physical addresses 0x00800000 to
 *  0x00BFFFFF and 0x00C00000 to 0x00FFFFFF respectively. We map the space
 *  from 0x0 to 0x7FFFFFFF as copyback, unless jumper J1-5 is removed, in
 *  which case we map as writethrough. If jumper J1-7 is removed, the data
 *  cache is NOT enabled. If jumper J1-6 is removed, the instruction cache
 *  is not enabled.
 *
 *  Copyright (c) 1998, National Research Council of Canada
 *
 *  $Id$
 */

#include <bsp.h>
#include <page_table.h>                 /* Nothing in here for us */

/*
 *  page_table_init
 *  
 *  Map the virtual range 0x00000000--0x7FFFFFFF to the physical range
 *  0x00000000--0x7FFFFFFF. Rely on the hardware to raise exceptions when
 *  addressing non-existent memory. Use only the transparent translation
 *  registers (for now).
 *
 *  On all processors, the local virtual address range 0xFF000000--0xFFFFFFFF 
 *  is mapped to the physical address range 0xFF000000--0xFFFFFFFF as
 *  caching disabled, serialized access.
 *
 *  Input parameters:
 *    config_table - ignored for now
 *
 *  Output parameters: NONE
 *
 *  Return values: NONE
 */
void page_table_init(
  rtems_configuration_table *config_table
)
{
  unsigned char j1;               /* State of J1 jumpers */
  register unsigned long dtt0;    /* Content of dtt0 */
  register unsigned long cacr;    /* Content of cacr */
  
  /*
   *  Logical base addr = 0x00    map starting at 0x00000000
   *  Logical address mask = 0x7F map up to 0x7FFFFFFF
   *  E = 0b1                     enable address translation
   *  S-Field = 0b1X              ignore FC2 when matching
   *  U1, U0 = 0b00               user page attributes not used
   *  CM = 0b01                   cachable, copyback
   *  W = 0b0                     read/write access allowed
   */
  dtt0 = 0x007FC020;
  
  cacr = 0x80008000;              /* Data and instruction cache on */
  
  /* Read the J1 header */
  j1 = (unsigned char)(lcsr->vector_base & 0xFF);
  
  if ( j1 & 0x80 )
    /* Jumper J1-7 if off, disable data caching */
    cacr &= 0x7FFFFFFF;
      
  if ( j1 & 0x40 )
    /* Jumper J1-6 if off, disable instruction caching */
    cacr &= 0xFFFF7FFF;
      
  if ( j1 & 0x20 )
    /* Jumper J1-5 is off, enable writethrough caching */
    dtt0 &= 0xFFFFFF9F;
  
  /* do it ! */
  asm volatile("movec %0, %%tc    /* turn off paged address translation */
                movec %0, %%cacr  /* disable both caches */
                cinva %%bc        /* clear both caches */
                movec %1,%%dtt0   /* block address translation on */
                movec %1,%%itt0
                movec %2,%%dtt1
                movec %2,%%itt1
                movec %3,%%cacr"  /* data cache on */
	  :: "d" (0), "d" (dtt0), "d" (0xFF00C040), "d" (cacr));
}

 
/*
 *  page_table_teardown
 *
 *  Turn off paging. Turn off the cache. Flush the cache. Tear down
 *  the transparent translations.
 *
 *  Input parameters: NONE
 *
 *  Output parameters: NONE
 *
 *  Return values: NONE
 */
void page_table_teardown( void )
{
  asm volatile ("movec %0,%%tc
                 movec %0,%%cacr
                 cpusha %%bc
                 movec %0,%%dtt0
                 movec %0,%%itt0
                 movec %0,%%dtt1
                 movec %0,%%itt1"
    :: "d" (0) );
}