~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to arch/sh/kernel/sh_bios.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  linux/arch/sh/kernel/sh_bios.c
3
2
 *  C interface for trapping into the standard LinuxSH BIOS.
4
3
 *
5
4
 *  Copyright (C) 2000 Greg Banks, Mitch Davis
 
5
 *  Copyright (C) 1999, 2000  Niibe Yutaka
 
6
 *  Copyright (C) 2002  M. R. Brown
 
7
 *  Copyright (C) 2004 - 2010  Paul Mundt
6
8
 *
 
9
 * This file is subject to the terms and conditions of the GNU General Public
 
10
 * License.  See the file "COPYING" in the main directory of this archive
 
11
 * for more details.
7
12
 */
8
13
#include <linux/module.h>
 
14
#include <linux/console.h>
 
15
#include <linux/tty.h>
 
16
#include <linux/init.h>
 
17
#include <linux/io.h>
 
18
#include <linux/delay.h>
9
19
#include <asm/sh_bios.h>
10
20
 
11
21
#define BIOS_CALL_CONSOLE_WRITE         0
12
22
#define BIOS_CALL_ETH_NODE_ADDR         10
13
23
#define BIOS_CALL_SHUTDOWN              11
14
 
#define BIOS_CALL_CHAR_OUT              0x1f    /* TODO: hack */
15
24
#define BIOS_CALL_GDB_DETACH            0xff
16
25
 
 
26
void *gdb_vbr_vector = NULL;
 
27
 
17
28
static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
18
29
                                    long arg3)
19
30
{
23
34
        register long r6 __asm__("r6") = arg2;
24
35
        register long r7 __asm__("r7") = arg3;
25
36
 
 
37
        if (!gdb_vbr_vector)
 
38
                return -ENOSYS;
 
39
 
26
40
        __asm__ __volatile__("trapa     #0x3f":"=z"(r0)
27
41
                             :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
28
42
                             :"memory");
34
48
        sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
35
49
}
36
50
 
37
 
void sh_bios_char_out(char ch)
38
 
{
39
 
        sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0);
40
 
}
41
 
 
42
51
void sh_bios_gdb_detach(void)
43
52
{
44
53
        sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
55
64
{
56
65
        sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
57
66
}
 
67
 
 
68
/*
 
69
 * Read the old value of the VBR register to initialise the vector
 
70
 * through which debug and BIOS traps are delegated by the Linux trap
 
71
 * handler.
 
72
 */
 
73
void sh_bios_vbr_init(void)
 
74
{
 
75
        unsigned long vbr;
 
76
 
 
77
        if (unlikely(gdb_vbr_vector))
 
78
                return;
 
79
 
 
80
        __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
 
81
 
 
82
        if (vbr) {
 
83
                gdb_vbr_vector = (void *)(vbr + 0x100);
 
84
                printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
 
85
                       gdb_vbr_vector);
 
86
        } else
 
87
                printk(KERN_NOTICE "SH-BIOS not detected\n");
 
88
}
 
89
 
 
90
/**
 
91
 * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector.
 
92
 *
 
93
 * This can be used by save/restore code to reinitialize the system VBR
 
94
 * from the fixed BIOS VBR. A no-op if no BIOS VBR is known.
 
95
 */
 
96
void sh_bios_vbr_reload(void)
 
97
{
 
98
        if (gdb_vbr_vector)
 
99
                __asm__ __volatile__ (
 
100
                        "ldc %0, vbr"
 
101
                        :
 
102
                        : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
 
103
                        : "memory"
 
104
                );
 
105
}
 
106
 
 
107
/*
 
108
 *      Print a string through the BIOS
 
109
 */
 
110
static void sh_console_write(struct console *co, const char *s,
 
111
                                 unsigned count)
 
112
{
 
113
        sh_bios_console_write(s, count);
 
114
}
 
115
 
 
116
/*
 
117
 *      Setup initial baud/bits/parity. We do two things here:
 
118
 *      - construct a cflag setting for the first rs_open()
 
119
 *      - initialize the serial port
 
120
 *      Return non-zero if we didn't find a serial port.
 
121
 */
 
122
static int __init sh_console_setup(struct console *co, char *options)
 
123
{
 
124
        int     cflag = CREAD | HUPCL | CLOCAL;
 
125
 
 
126
        /*
 
127
         *      Now construct a cflag setting.
 
128
         *      TODO: this is a totally bogus cflag, as we have
 
129
         *      no idea what serial settings the BIOS is using, or
 
130
         *      even if its using the serial port at all.
 
131
         */
 
132
        cflag |= B115200 | CS8 | /*no parity*/0;
 
133
 
 
134
        co->cflag = cflag;
 
135
 
 
136
        return 0;
 
137
}
 
138
 
 
139
static struct console bios_console = {
 
140
        .name           = "bios",
 
141
        .write          = sh_console_write,
 
142
        .setup          = sh_console_setup,
 
143
        .flags          = CON_PRINTBUFFER,
 
144
        .index          = -1,
 
145
};
 
146
 
 
147
static struct console *early_console;
 
148
 
 
149
static int __init setup_early_printk(char *buf)
 
150
{
 
151
        int keep_early = 0;
 
152
 
 
153
        if (!buf)
 
154
                return 0;
 
155
 
 
156
        if (strstr(buf, "keep"))
 
157
                keep_early = 1;
 
158
 
 
159
        if (!strncmp(buf, "bios", 4))
 
160
                early_console = &bios_console;
 
161
 
 
162
        if (likely(early_console)) {
 
163
                if (keep_early)
 
164
                        early_console->flags &= ~CON_BOOT;
 
165
                else
 
166
                        early_console->flags |= CON_BOOT;
 
167
                register_console(early_console);
 
168
        }
 
169
 
 
170
        return 0;
 
171
}
 
172
early_param("earlyprintk", setup_early_printk);