OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [baget/] [balo.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * balo.c: BAget LOader
3
 *
4
 * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
5
 */
6
#include <linux/kernel.h>
7
#include <asm/system.h>
8
#include <asm/ptrace.h>
9
#include <asm/addrspace.h>
10
 
11
#include <asm/baget/baget.h>
12
 
13
#include "balo.h"  /* Includes some kernel symbol values */
14
 
15
static char *banner = "\nBaget Linux Loader v0.2\n";
16
 
17
static void mem_move (long *to, long *from, long size)
18
{
19
        while (size > 0) {
20
                *to++ = *from++;
21
                size -= sizeof(long);
22
        }
23
}
24
 
25
static volatile int *mem_limit     = (volatile int*)KSEG1;
26
static volatile int *mem_limit_dbe = (volatile int*)KSEG1;
27
 
28
static int can_write (volatile int* p) {
29
        return p <  (int*)(KSEG1+BALO_OFFSET) ||
30
               p >= (int*)(KSEG1+BALO_OFFSET+BALO_SIZE);
31
}
32
 
33
static volatile enum balo_state_enum {
34
        BALO_INIT,
35
        MEM_INIT,
36
        MEM_PROBE,
37
        START_KERNEL
38
} balo_state = BALO_INIT;
39
 
40
 
41
static __inline__ void reset_and_jump(int start, int mem_upper)
42
{
43
        unsigned long tmp;
44
 
45
        __asm__ __volatile__(
46
                ".set\tnoreorder\n\t"
47
                ".set\tnoat\n\t"
48
                "mfc0\t$1, $12\n\t"
49
                "nop\n\t"
50
                "nop\n\t"
51
                "nop\n\t"
52
                "ori\t$1, $1, 0xff00\n\t"
53
                "xori\t$1, $1, 0xff00\n\t"
54
                "mtc0\t$1, $12\n\t"
55
                "nop\n\t"
56
                "nop\n\t"
57
                "nop\n\t"
58
                "move\t%0, %2\n\t"
59
                "jr\t%1\n\t"
60
                "nop\n\t"
61
                ".set\tat\n\t"
62
                ".set\treorder"
63
                : "=&r" (tmp)
64
                : "Ir" (start), "Ir" (mem_upper)
65
                : "memory");
66
}
67
 
68
static void start_kernel(void)
69
{
70
        extern char _vmlinux_start, _vmlinux_end;
71
        extern char _ramdisk_start, _ramdisk_end;
72
 
73
        outs( "Relocating Linux... " );
74
        mem_move((long*)KSEG0, (long*)&_vmlinux_start,
75
                 &_vmlinux_end-&_vmlinux_start);
76
        outs("done.\n");
77
 
78
        if (&_ramdisk_start != &_ramdisk_end) {
79
                outs("Setting up RAMDISK... ");
80
                if (*(unsigned long*)RAMDISK_BASE != 0xBA) {
81
                        outs("Bad RAMDISK_BASE signature in system image.\n");
82
                        balo_hungup();
83
                }
84
                *(unsigned long*)RAMDISK_BASE = (unsigned long)&_ramdisk_start;
85
                *(unsigned long*)RAMDISK_SIZE = &_ramdisk_end -&_ramdisk_start;
86
                outs("done.\n");
87
        }
88
 
89
        {
90
                extern void flush_cache_low(int isize, int dsize);
91
                flush_cache_low(256*1024,256*1024);
92
        }
93
 
94
        balo_printf( "Kernel entry: %x\n\n", START);
95
        balo_state = START_KERNEL;
96
        reset_and_jump(START, (int)mem_limit-KSEG1+KSEG0);
97
}
98
 
99
 
100
static void mem_probe(void)
101
{
102
        balo_state = MEM_PROBE;
103
        outs("RAM: <");
104
        while(mem_limit < mem_limit_dbe) {
105
                if (can_write(mem_limit) && *mem_limit != 0)
106
                        break; /* cycle found */
107
                outc('.');
108
                if (can_write(mem_limit))
109
                        *mem_limit = -1; /* mark */
110
                mem_limit += 0x40000;
111
        }
112
        outs(">\n");
113
        start_kernel();
114
}
115
 
116
volatile unsigned int int_cause;
117
volatile unsigned int epc;
118
volatile unsigned int badvaddr;
119
 
120
static void print_regs(void)
121
{
122
        balo_printf("CAUSE=%x EPC=%x BADVADDR=%x\n",
123
                    int_cause, epc, badvaddr);
124
}
125
 
126
void int_handler(struct pt_regs *regs)
127
{
128
        switch (balo_state) {
129
        case BALO_INIT:
130
                balo_printf("\nBALO: trap in balo itself.\n");
131
                print_regs();
132
                balo_hungup();
133
                break;
134
        case MEM_INIT:
135
                if ((int_cause & CAUSE_MASK) != CAUSE_DBE) {
136
                        balo_printf("\nBALO: unexpected trap during memory init.\n");
137
                        print_regs();
138
                        balo_hungup();
139
                } else {
140
                        mem_probe();
141
                }
142
                break;
143
        case MEM_PROBE:
144
                balo_printf("\nBALO: unexpected trap during memory probe.\n");
145
                print_regs();
146
                balo_hungup();
147
                break;
148
        case START_KERNEL:
149
                balo_printf("\nBALO: unexpected kernel trap.\n");
150
                print_regs();
151
                balo_hungup();
152
                break;
153
        }
154
        balo_printf("\nBALO: unexpected return from handler.\n");
155
        print_regs();
156
        balo_hungup();
157
}
158
 
159
static void mem_init(void)
160
{
161
        balo_state = MEM_INIT;
162
 
163
        while(1) {
164
                *mem_limit_dbe;
165
                if (can_write(mem_limit_dbe))
166
                        *mem_limit_dbe = 0;
167
 
168
                mem_limit_dbe += 0x40000; /* +1M */
169
        }
170
        /*  no return: must go to int_handler */
171
}
172
 
173
void balo_entry(void)
174
{
175
        extern void except_vec3_generic(void);
176
 
177
        cli();
178
        outs(banner);
179
        memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
180
        mem_init();
181
}
182
 
183
/* Needed for linking */
184
 
185
int vsprintf(char *buf, const char *fmt, va_list arg)
186
{
187
        outs("BALO: vsprintf called.\n");
188
        balo_hungup();
189
        return 0;
190
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.