summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/motorola_powerpc/bootloader/bootldr.h
blob: e3e02b0908ec9962488fab1e0371b25564e2ae80 (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/*
 *  bootldr.h -- Include file for bootloader.
 *
 *  Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
 *
 *  Modified to compile in RTEMS development environment
 *  by Eric Valette
 *
 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
 *
 *  The license and distribution terms for this file may be
 *  found in found in the file LICENSE in this distribution or at
 *  http://www.OARcorp.com/rtems/license.html.
 *
 * $Id$
 */

#ifndef _PPC_BOOTLDR_H
#define _PPC_BOOTLDR_H

#ifndef ASM
#include <bsp/residual.h>
#include <bsp/consoleIo.h>
#include "pci.h"

#define abs __builtin_abs

#define PTE_REFD 0x100
#define PTE_CHNG (0x80|PTE_REFD)	/* Modified implies referenced */
#define PTE_WTHR 0x040
#define PTE_CINH 0x020
#define PTE_COHER 0x010
#define PTE_GUAR 0x008
#define PTE_RO   0x003
#define PTE_RW   0x002

#define PTE_RAM (PTE_CHNG|PTE_COHER|PTE_RW)
#define PTE_ROM (PTE_REFD|PTE_RO)
#define PTE_IO  (PTE_CHNG|PTE_CINH|PTE_GUAR|PTE_RW)

typedef struct {}opaque;

/* The context passed during MMU interrupts. */
typedef struct _ctxt {
	u_long lr, ctr;
	u_int cr, xer;
	u_long nip, msr;
	u_long regs[32];
} ctxt;

/* The main structure which is pointed to permanently by r13. Things
 * are not separated very well between parts because it would cause
 * too much code bloat for such a simple program like the bootloader.
 * The code is designed to be compiled with the -m relocatable option and 
 * tries to minimize the number of relocations/fixups and the number of 
 * functions who have to access the .got2 sections (this increases the 
 * size of the prologue in every function).
 */
typedef struct _boot_data {
	RESIDUAL *residual;
	void *load_address;
        void *of_entry;
	void *r6, *r7, *r8, *r9, *r10; 
	u_long cache_lsize;
	void *image;  /* Where to copy ourselves */
	void *stack;
	void *mover;  /* where to copy codemove to avoid overlays */
	u_long o_msr, o_hid0, o_r31;
	opaque * mm_private;
	const struct pci_config_access_functions * pci_functions;
	opaque * pci_private;
	struct pci_dev * pci_devices;
	opaque * v86_private;
	char cmd_line[256];
} boot_data;

register boot_data *bd __asm__("r13");

extern inline int
pcibios_read_config_byte(u_char bus, u_char dev_fn, 
			 u_char where, u_char * val) {
	return bd->pci_functions->read_config_byte(bus, dev_fn, where, val);
}

extern inline int
pcibios_read_config_word(u_char bus, u_char dev_fn, 
			 u_char where, u_short * val) {
	return bd->pci_functions->read_config_word(bus, dev_fn, where, val);
}

extern inline int
pcibios_read_config_dword(u_char bus, u_char dev_fn, 
			 u_char where, u_int * val) {
	return bd->pci_functions->read_config_dword(bus, dev_fn, where, val);
}

extern inline int
pcibios_write_config_byte(u_char bus, u_char dev_fn, 
			 u_char where, u_char val) {
	return bd->pci_functions->write_config_byte(bus, dev_fn, where, val);
}

extern inline int
pcibios_write_config_word(u_char bus, u_char dev_fn, 
			 u_char where, u_short val) {
	return bd->pci_functions->write_config_word(bus, dev_fn, where, val);
}

extern inline int
pcibios_write_config_dword(u_char bus, u_char dev_fn, 
			 u_char where, u_int val) {
	return bd->pci_functions->write_config_dword(bus, dev_fn, where, val);
}

extern inline int
pci_read_config_byte(struct pci_dev *dev, u_char where, u_char * val) {
	return bd->pci_functions->read_config_byte(dev->bus->number, 
						   dev->devfn, 
						   where, val);
}

extern inline int
pci_read_config_word(struct pci_dev *dev, u_char where, u_short * val) {
	return bd->pci_functions->read_config_word(dev->bus->number, 
						   dev->devfn, 
						   where, val);
}

extern inline int
pci_read_config_dword(struct pci_dev *dev, u_char where, u_int * val) {
	return bd->pci_functions->read_config_dword(dev->bus->number, 
						    dev->devfn, 
						    where, val);
}

extern inline int
pci_write_config_byte(struct pci_dev *dev, u_char where, u_char val) {
	return bd->pci_functions->write_config_byte(dev->bus->number, 
						    dev->devfn, 
						    where, val);
}

extern inline int
pci_write_config_word(struct pci_dev *dev, u_char where, u_short val) {
	return bd->pci_functions->write_config_word(dev->bus->number, 
						    dev->devfn, 
						    where, val);
}

extern inline int
pci_write_config_dword(struct pci_dev *dev, u_char where, u_int val) {
	return bd->pci_functions->write_config_dword(dev->bus->number, 
						     dev->devfn, 
						     where, val);
}

/* codemove is like memmove, but it also gets the cache line size
 * as 4th parameter to synchronize them. If this last parameter is
 * zero, it performs more or less like memmove. No copy is performed if
 * source and destination addresses are equal. However the caches
 * are synchronized. Note that the size is always rounded up to the
 * next mutiple of 4. 
 */
extern void * codemove(void *, const void *, size_t, unsigned long);

/* The physical memory allocator allows to align memory by
 * powers of 2 given by the lower order bits of flags. 
 * By default it allocates from higher addresses towrds lower ones,
 * setting PA_LOW reverses this behaviour.
 */

#define palloc(size) __palloc(size,0)

#define isa_io_base (bd->io_base)


void * __palloc(u_long, int);
void  pfree(void *);

#define PA_LOW 0x100
#define PA_PERM 0x200		/* Not freeable by pfree */
#define PA_SUBALLOC 0x400	/* Allocate for suballocation by salloc */
#define PA_ALIGN_MASK 0x1f

void * valloc(u_long size);
void vfree(void *);

int vmap(void *, u_long, u_long);
void vunmap(void *);

void * salloc(u_long size);
void sfree(void *);

void pci_init(void);

void * memset(void *p, int c, size_t n);

void gunzip(void *, int, unsigned char *, int *);

void print_all_maps(const char *);
void print_hash_table(void);
void MMUon(void);
void MMUoff(void);
void hang(const char *, u_long, ctxt *) __attribute__((noreturn));

int init_v86(void);
void cleanup_v86_mess(void);
void em86_main(struct pci_dev *);
int find_max_mem(struct pci_dev *);

#endif

#ifdef ASM
/* These definitions simplify the ugly declarations necessary for
 * GOT definitions. 
 */

#define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1	; .long	NAME
#define GOT(NAME) .L_ ## NAME (r30)	

#define START_GOT	\
	.section	".got2","aw"; \
.LCTOC1 = .+ 0x8000

#define END_GOT \
	.text

#define GET_GOT \
	bl      1f; \
	.text	2; \
0:	.long   .LCTOC1-1f; \
	.text	; \
1:	mflr	r30; \
	lwz	r0,0b-1b(r30); \
        add	r30,r0,r30

#define	bd r13
#define cache_lsize 32	/* Offset into bd area */
#define	image	36
#define stack	40
#define mover	44
#define o_msr	48
#define o_hid0	52
#define o_r31   56
/* Stack offsets for saved registers on exceptions */
#define save_lr    8(r1)
#define save_ctr  12(r1)
#define save_cr   16(r1)
#define save_xer  20(r1)
#define save_nip  24(r1)
#define save_msr  28(r1)
#define save_r(n) 32+4*n(r1)
#endif

#endif