blob: d3b971ef67b0eb7ff754ddbcacff195d86781a91 [file] [log] [blame]
#include "libcflat.h"
#include "smp.h"
#include "io.h"
#ifndef USE_SERIAL
#define USE_SERIAL
#endif
static struct spinlock lock;
static int serial_iobase = 0x3f8;
static int serial_inited = 0;
static void serial_outb(char ch)
{
u8 lsr;
do {
lsr = inb(serial_iobase + 0x05);
} while (!(lsr & 0x20));
outb(ch, serial_iobase + 0x00);
}
static void serial_init(void)
{
u8 lcr;
/* set DLAB */
lcr = inb(serial_iobase + 0x03);
lcr |= 0x80;
outb(lcr, serial_iobase + 0x03);
/* set baud rate to 115200 */
outb(0x01, serial_iobase + 0x00);
outb(0x00, serial_iobase + 0x01);
/* clear DLAB */
lcr = inb(serial_iobase + 0x03);
lcr &= ~0x80;
outb(lcr, serial_iobase + 0x03);
}
static void print_serial(const char *buf)
{
unsigned long len = strlen(buf);
#ifdef USE_SERIAL
unsigned long i;
if (!serial_inited) {
serial_init();
serial_inited = 1;
}
for (i = 0; i < len; i++) {
serial_outb(buf[i]);
}
#else
asm volatile ("rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1));
#endif
}
void puts(const char *s)
{
spin_lock(&lock);
print_serial(s);
spin_unlock(&lock);
}
void exit(int code)
{
#ifdef USE_SERIAL
static const char shutdown_str[8] = "Shutdown";
int i;
/* test device exit (with status) */
outl(code, 0xf4);
/* if that failed, try the Bochs poweroff port */
for (i = 0; i < 8; i++) {
outb(shutdown_str[i], 0x8900);
}
#else
asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4));
#endif
}