diff options
| -rw-r--r-- | arch/x86/boot/tty.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c index f6d52e65f97a..ff4b27a0fc5e 100644 --- a/arch/x86/boot/tty.c +++ b/arch/x86/boot/tty.c | |||
| @@ -152,35 +152,40 @@ int getchar_timeout(void) | |||
| 152 | return 0; /* Timeout! */ | 152 | return 0; /* Timeout! */ |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static void early_serial_init(int baud) | 155 | static void early_serial_init(int port, int baud) |
| 156 | { | 156 | { |
| 157 | unsigned char c; | 157 | unsigned char c; |
| 158 | unsigned divisor; | 158 | unsigned divisor; |
| 159 | 159 | ||
| 160 | outb(0x3, early_serial_base + LCR); /* 8n1 */ | 160 | outb(0x3, port + LCR); /* 8n1 */ |
| 161 | outb(0, early_serial_base + IER); /* no interrupt */ | 161 | outb(0, port + IER); /* no interrupt */ |
| 162 | outb(0, early_serial_base + FCR); /* no fifo */ | 162 | outb(0, port + FCR); /* no fifo */ |
| 163 | outb(0x3, early_serial_base + MCR); /* DTR + RTS */ | 163 | outb(0x3, port + MCR); /* DTR + RTS */ |
| 164 | 164 | ||
| 165 | divisor = 115200 / baud; | 165 | divisor = 115200 / baud; |
| 166 | c = inb(early_serial_base + LCR); | 166 | c = inb(port + LCR); |
| 167 | outb(c | DLAB, early_serial_base + LCR); | 167 | outb(c | DLAB, port + LCR); |
| 168 | outb(divisor & 0xff, early_serial_base + DLL); | 168 | outb(divisor & 0xff, port + DLL); |
| 169 | outb((divisor >> 8) & 0xff, early_serial_base + DLH); | 169 | outb((divisor >> 8) & 0xff, port + DLH); |
| 170 | outb(c & ~DLAB, early_serial_base + LCR); | 170 | outb(c & ~DLAB, port + LCR); |
| 171 | |||
| 172 | early_serial_base = port; | ||
| 173 | |||
| 174 | printf("Early serial console at I/O port 0x%x baud: %d\n", port, baud); | ||
| 171 | } | 175 | } |
| 172 | 176 | ||
| 173 | static int parse_earlyprintk(void) | 177 | static void parse_earlyprintk(void) |
| 174 | { | 178 | { |
| 175 | int baud = DEFAULT_BAUD; | 179 | int baud = DEFAULT_BAUD; |
| 176 | char arg[32]; | 180 | char arg[32]; |
| 177 | int pos = 0; | 181 | int pos = 0; |
| 182 | int port = 0; | ||
| 178 | 183 | ||
| 179 | if (cmdline_find_option("earlyprintk", arg, sizeof arg) > 0) { | 184 | if (cmdline_find_option("earlyprintk", arg, sizeof arg) > 0) { |
| 180 | char *e; | 185 | char *e; |
| 181 | 186 | ||
| 182 | if (!strncmp(arg, "serial", 6)) { | 187 | if (!strncmp(arg, "serial", 6)) { |
| 183 | early_serial_base = DEFAULT_SERIAL_PORT; | 188 | port = DEFAULT_SERIAL_PORT; |
| 184 | pos += 6; | 189 | pos += 6; |
| 185 | } | 190 | } |
| 186 | 191 | ||
| @@ -189,15 +194,15 @@ static int parse_earlyprintk(void) | |||
| 189 | 194 | ||
| 190 | if (!strncmp(arg, "ttyS", 4)) { | 195 | if (!strncmp(arg, "ttyS", 4)) { |
| 191 | static const int bases[] = { 0x3f8, 0x2f8 }; | 196 | static const int bases[] = { 0x3f8, 0x2f8 }; |
| 192 | int port = 0; | 197 | int idx = 0; |
| 193 | 198 | ||
| 194 | if (!strncmp(arg + pos, "ttyS", 4)) | 199 | if (!strncmp(arg + pos, "ttyS", 4)) |
| 195 | pos += 4; | 200 | pos += 4; |
| 196 | 201 | ||
| 197 | if (arg[pos++] == '1') | 202 | if (arg[pos++] == '1') |
| 198 | port = 1; | 203 | idx = 1; |
| 199 | 204 | ||
| 200 | early_serial_base = bases[port]; | 205 | port = bases[idx]; |
| 201 | } | 206 | } |
| 202 | 207 | ||
| 203 | if (arg[pos] == ',') | 208 | if (arg[pos] == ',') |
| @@ -208,7 +213,8 @@ static int parse_earlyprintk(void) | |||
| 208 | baud = DEFAULT_BAUD; | 213 | baud = DEFAULT_BAUD; |
| 209 | } | 214 | } |
| 210 | 215 | ||
| 211 | return baud; | 216 | if (port) |
| 217 | early_serial_init(port, baud); | ||
| 212 | } | 218 | } |
| 213 | 219 | ||
| 214 | #define BASE_BAUD (1843200/16) | 220 | #define BASE_BAUD (1843200/16) |
| @@ -227,44 +233,41 @@ static unsigned int probe_baud(int port) | |||
| 227 | return BASE_BAUD / quot; | 233 | return BASE_BAUD / quot; |
| 228 | } | 234 | } |
| 229 | 235 | ||
| 230 | static int parse_console_uart8250(void) | 236 | static void parse_console_uart8250(void) |
| 231 | { | 237 | { |
| 232 | char optstr[64], *options; | 238 | char optstr[64], *options; |
| 233 | int baud = DEFAULT_BAUD; | 239 | int baud = DEFAULT_BAUD; |
| 240 | int port = 0; | ||
| 234 | 241 | ||
| 235 | /* | 242 | /* |
| 236 | * console=uart8250,io,0x3f8,115200n8 | 243 | * console=uart8250,io,0x3f8,115200n8 |
| 237 | * need to make sure it is last one console ! | 244 | * need to make sure it is last one console ! |
| 238 | */ | 245 | */ |
| 239 | if (cmdline_find_option("console", optstr, sizeof optstr) <= 0) | 246 | if (cmdline_find_option("console", optstr, sizeof optstr) <= 0) |
| 240 | return baud; | 247 | return; |
| 241 | 248 | ||
| 242 | options = optstr; | 249 | options = optstr; |
| 243 | 250 | ||
| 244 | if (!strncmp(options, "uart8250,io,", 12)) | 251 | if (!strncmp(options, "uart8250,io,", 12)) |
| 245 | early_serial_base = simple_strtoull(options + 12, &options, 0); | 252 | port = simple_strtoull(options + 12, &options, 0); |
| 246 | else if (!strncmp(options, "uart,io,", 8)) | 253 | else if (!strncmp(options, "uart,io,", 8)) |
| 247 | early_serial_base = simple_strtoull(options + 8, &options, 0); | 254 | port = simple_strtoull(options + 8, &options, 0); |
| 248 | else | 255 | else |
| 249 | return baud; | 256 | return; |
| 250 | 257 | ||
| 251 | if (options && (options[0] == ',')) | 258 | if (options && (options[0] == ',')) |
| 252 | baud = simple_strtoull(options + 1, &options, 0); | 259 | baud = simple_strtoull(options + 1, &options, 0); |
| 253 | else | 260 | else |
| 254 | baud = probe_baud(early_serial_base); | 261 | baud = probe_baud(port); |
| 255 | 262 | ||
| 256 | return baud; | 263 | if (port) |
| 264 | early_serial_init(port, baud); | ||
| 257 | } | 265 | } |
| 258 | 266 | ||
| 259 | void console_init(void) | 267 | void console_init(void) |
| 260 | { | 268 | { |
| 261 | int baud; | 269 | parse_earlyprintk(); |
| 262 | |||
| 263 | baud = parse_earlyprintk(); | ||
| 264 | 270 | ||
| 265 | if (!early_serial_base) | 271 | if (!early_serial_base) |
| 266 | baud = parse_console_uart8250(); | 272 | parse_console_uart8250(); |
| 267 | |||
| 268 | if (early_serial_base != 0) | ||
| 269 | early_serial_init(baud); | ||
| 270 | } | 273 | } |
