提交 eb71d140 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Re-add some pared down uart code.

上级 0441ba0f
......@@ -3,6 +3,7 @@
OBJS = \
asm.o \
main.o \
uart.o \
trap.o
# Cross-compiling (e.g., on Mac OS X)
......@@ -44,7 +45,7 @@ clean:
ifndef CPUS
CPUS := 2
endif
QEMUOPTS = -smp $(CPUS) -m 512
QEMUOPTS = -smp $(CPUS) -m 512 -nographic
qemu: kernel
$(QEMU) -serial mon:stdio $(QEMUOPTS) -kernel kernel
$(QEMU) $(QEMUOPTS) -kernel kernel
#include "vmx.h"
#include "multiboot.h"
extern void uartinit(void);
void
cmain(void)
{
uartinit();
}
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef uint pde_t;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef long int64;
typedef unsigned long uint64;
typedef unsigned char uint8;
typedef uint64 uintptr;
typedef uint8 u8;
typedef uint16 u16;
typedef uint32 u32;
typedef int64 s64;
typedef uint64 u64;
// Intel 8250 serial port (UART).
#include "types.h"
#include "defs.h"
#include "param.h"
#include "traps.h"
#include "spinlock.h"
#include "mmu.h"
#include "condvar.h"
#include "queue.h"
#include "proc.h"
#include "kernel.h"
#include "x86.h"
#include "fs.h"
#include "file.h"
#define COM1 0x3f8
static int uart; // is there a uart?
void
uartputc(int c)
{
int i;
if(!uart)
return;
for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++)
microdelay(10);
outb(COM1+0, c);
}
void
uartinit(void)
{
char *p;
char *p;
// Turn off the FIFO
outb(COM1+2, 0);
......@@ -42,38 +43,8 @@ uartinit(void)
// enable interrupts.
inb(COM1+2);
inb(COM1+0);
picenable(IRQ_COM1);
ioapicenable(IRQ_COM1, 0);
// Announce that we're here.
for(p="xv6...\n"; *p; p++)
uartputc(*p);
}
void
uartputc(int c)
{
int i;
if(!uart)
return;
for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++)
microdelay(10);
outb(COM1+0, c);
}
static int
uartgetc(void)
{
if(!uart)
return -1;
if(!(inb(COM1+5) & 0x01))
return -1;
return inb(COM1+0);
}
void
uartintr(void)
{
consoleintr(uartgetc);
}
#pragma once
// Routines to let C code use special x86 instructions.
static inline uchar
inb(ushort port)
static inline u8
inb(u16 port)
{
uchar data;
u8 data = 0;
__asm volatile("in %1,%0" : "=a" (data) : "d" (port));
__asm volatile("inb %1,%0" : "=a" (data) : "d" (port));
return data;
}
static inline void
insl(int port, void *addr, int cnt)
outb(u16 port, u8 data)
{
__asm volatile("cld; rep insl" :
"=D" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"memory", "cc");
__asm volatile("outb %0,%1" : : "a" (data), "d" (port));
}
static inline void
outb(ushort port, uchar data)
microdelay(u32 delay)
{
__asm volatile("out %0,%1" : : "a" (data), "d" (port));
}
static inline void
outw(ushort port, ushort data)
{
__asm volatile("out %0,%1" : : "a" (data), "d" (port));
}
static inline void
outsl(int port, const void *addr, int cnt)
{
__asm volatile("cld; rep outsl" :
"=S" (addr), "=c" (cnt) :
"d" (port), "0" (addr), "1" (cnt) :
"cc");
}
static inline void
stosb(void *addr, int data, int cnt)
{
__asm volatile("cld; rep stosb" :
"=D" (addr), "=c" (cnt) :
"0" (addr), "1" (cnt), "a" (data) :
"memory", "cc");
}
struct segdesc;
static inline void
lgdt(struct segdesc *p, int size)
{
volatile ushort pd[3];
pd[0] = size-1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
__asm volatile("lgdt (%0)" : : "r" (pd));
}
struct gatedesc;
static inline void
lidt(struct gatedesc *p, int size)
{
volatile ushort pd[3];
pd[0] = size-1;
pd[1] = (uint)p;
pd[2] = (uint)p >> 16;
__asm volatile("lidt (%0)" : : "r" (pd));
}
static inline void
ltr(ushort sel)
{
__asm volatile("ltr %0" : : "r" (sel));
}
static inline uint
readeflags(void)
{
uint eflags;
__asm volatile("pushfl; popl %0" : "=r" (eflags));
return eflags;
}
static inline void
loadgs(ushort v)
{
__asm volatile("movw %0, %%gs" : : "r" (v));
}
static inline void
loadfs(ushort v)
{
__asm volatile("movw %0, %%fs" : : "r" (v));
}
static inline void
loades(ushort v)
{
__asm volatile("movw %0, %%es" : : "r" (v));
}
static inline void
loadds(ushort v)
{
__asm volatile("movw %0, %%ds" : : "r" (v));
}
static inline void
loadss(ushort v)
{
__asm volatile("movw %0, %%ss" : : "r" (v));
}
static inline uint
rebp(void)
{
uint val;
__asm volatile("movl %%ebp,%0" : "=r" (val));
return val;
}
static inline uint
resp(void)
{
uint val;
__asm volatile("movl %%esp,%0" : "=r" (val));
return val;
}
static inline void
cli(void)
{
__asm volatile("cli");
}
static inline void
sti(void)
{
__asm volatile("sti");
}
static inline uint
xchg(volatile uint *addr, uint newval)
{
uint result;
// The + in "+m" denotes a read-modify-write operand.
__asm volatile("lock; xchgl %0, %1" :
"+m" (*addr), "=a" (result) :
"1" (newval) :
"cc");
return result;
}
static inline void
nop_pause(void)
{
__asm volatile("pause" : :);
}
//PAGEBREAK!
static inline void
lcr0(uint val)
{
__asm volatile("movl %0,%%cr0" : : "r" (val));
}
static inline uint
rcr0(void)
{
uint val;
__asm volatile("movl %%cr0,%0" : "=r" (val));
return val;
}
static inline uint
rcr2(void)
{
uint val;
__asm volatile("movl %%cr2,%0" : "=r" (val));
return val;
}
static inline void
lcr3(uint val)
{
__asm volatile("movl %0,%%cr3" : : "r" (val));
}
static inline uint
rcr3(void)
{
uint val;
__asm volatile("movl %%cr3,%0" : "=r" (val));
return val;
}
static __inline__ unsigned long long rdtsc(void)
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
static __inline__ void hlt(void)
{
__asm__ __volatile__ ("hlt");
}
//PAGEBREAK: 36
// Layout of the trap frame built on the stack by the
// hardware and by trapasm.S, and passed to trap().
struct trapframe {
// registers as pushed by pusha
uint edi;
uint esi;
uint ebp;
uint oesp; // useless & ignored
uint ebx;
uint edx;
uint ecx;
uint eax;
// rest of trap frame
ushort gs;
ushort padding1;
ushort fs;
ushort padding2;
ushort es;
ushort padding3;
ushort ds;
ushort padding4;
uint trapno;
// below here defined by x86 hardware
uint err;
uint eip;
ushort cs;
ushort padding5;
uint eflags;
// below here only when crossing rings, such as from user to kernel
uint esp;
ushort ss;
ushort padding6;
};
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论