am: unify code of mips32-nemu and x86-nemu

This commit is contained in:
Yanyan Jiang 2019-02-17 09:20:03 +00:00
parent d470f4f6a2
commit 5b40f0f54d
29 changed files with 138 additions and 191 deletions

View File

@ -24,11 +24,13 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
READELF = $(CROSS_COMPILE)readelf
ISA_DEF = __ISA_$(shell echo $(ISA) | tr a-z A-Z)__
ARCH_DEF = __ARCH_$(shell echo $(ARCH) | tr a-z A-Z | tr - _)
INCLUDES = $(addprefix -I, $(INC_DIR)) -I$(AM_HOME)/am/
INCLUDES += -I$(AM_HOME)/am/include
CFLAGS_COMMON += -O2 -MMD -Wall -Werror -ggdb $(INCLUDES) -D$(ISA_DEF) -D__ISA__=\"$(ISA)\" \
-D__ARCH__=$(ARCH) -D$(ARCH_DEF) \
-fno-builtin -fno-stack-protector
CFLAGS += -std=gnu11
CXXFLAGS += -std=c++11 -ffreestanding -fno-rtti -fno-exceptions

View File

@ -6,9 +6,13 @@
#ifndef __AM_H__
#define __AM_H__
#define __XSTR(x) #x
#define __STR(x) __XSTR(x)
#define ARCH_H_PATH __STR(arch/__ARCH__.h)
#include <stdint.h>
#include <stddef.h>
#include <arch.h>
#include ARCH_H_PATH // "arch/x86-qemu.h"
#ifdef __cplusplus
extern "C" {

19
am/arch/mips32-nemu.mk Normal file
View File

@ -0,0 +1,19 @@
AM_SRCS := mips32/nemu/trm.c \
mips32/nemu/ioe.c \
mips32/nemu/trap.S \
mips32/nemu/cte.c \
mips32/nemu/vme.c \
devices/nemu-input.c \
devices/nemu-timer.c \
devices/nemu-video.c \
LOADER_DIR := $(AM_HOME)/am/src/mips32/nemu/loader
image:
mips-linux-gnu-gcc -EL -march=mips32 -fno-pic -mno-abicalls -fno-delayed-branch -c $(LOADER_DIR)/start.S -o $(LOADER_DIR)/start.o
mips-linux-gnu-ld --gc-sections -EL -T $(LOADER_DIR)/loader.ld -e _start -o $(BINARY).o $(LOADER_DIR)/start.o --start-group $(LINK_FILES) --end-group
mips-linux-gnu-objdump -d $(BINARY).o > $(BINARY).txt
mips-linux-gnu-objcopy -S --set-section-flags .bss=alloc,contents -O binary $(BINARY).o $(BINARY).bin
run:
make -C $(NEMU_HOME) ISA=mips32 run ARGS="-b -l $(shell dirname $(BINARY))/nemu-log.txt $(BINARY).bin"

View File

@ -3,17 +3,17 @@ AM_SRCS := x86/nemu/trm.c \
x86/nemu/cte.c \
x86/nemu/trap.S \
x86/nemu/vme.c \
x86/nemu/devices/input.c \
x86/nemu/devices/timer.c \
x86/nemu/devices/video.c \
devices/nemu-input.c \
devices/nemu-timer.c \
devices/nemu-video.c \
DIR := $(AM_HOME)/am/src/x86/nemu/loader
LOADER_DIR := $(AM_HOME)/am/src/x86/nemu/loader
image:
gcc -m32 -fno-pic -ffunction-sections -c $(DIR)/start.S -o $(DIR)/start.o
ld -melf_i386 --gc-sections -T $(DIR)/loader.ld -e _start -o $(BINARY).o $(DIR)/start.o --start-group $(LINK_FILES) --end-group
gcc -m32 -fno-pic -ffunction-sections -c $(LOADER_DIR)/start.S -o $(LOADER_DIR)/start.o
ld -melf_i386 --gc-sections -T $(LOADER_DIR)/loader.ld -e _start -o $(BINARY).o $(LOADER_DIR)/start.o --start-group $(LINK_FILES) --end-group
objdump -d $(BINARY).o > $(BINARY).txt
objcopy -S --set-section-flags .bss=alloc,contents -O binary $(BINARY) $(BINARY).bin
objcopy -S --set-section-flags .bss=alloc,contents -O binary $(BINARY).o $(BINARY).bin
run:
make -C $(NEMU_HOME) ISA=x86 run ARGS="-b -l $(shell dirname $(BINARY))/nemu-log.txt $(BINARY).bin"

View File

@ -14,8 +14,8 @@ AM_SRCS := x86/qemu/trm.c \
image:
@ld -melf_i386 -Ttext 0x00100000 -o $(BINARY).o --start-group $(LINK_FILES) --end-group
@make -C ${AM_HOME}/am/src/x86/boot
@cat ${AM_HOME}/am/src/x86/boot/mbr $(BINARY).o > $(BINARY)
@make -C ${AM_HOME}/am/src/x86/qemu/boot
@cat ${AM_HOME}/am/src/x86/qemu/boot/mbr $(BINARY).o > $(BINARY)
run:
@qemu-system-i386 -serial stdio $(BINARY)

View File

@ -1,11 +1,6 @@
#ifndef __ARCH_H__
#define __ARCH_H__
#include <am.h>
#define PMEM_SIZE (128 * 1024 * 1024)
#define PGSIZE 4096
struct _Context {
struct _AddressSpace *prot;
uint32_t gpr[31];
@ -19,11 +14,4 @@ struct _Context {
#define GPR4 gpr[6]
#define GPRx gpr[1]
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,20 +1,6 @@
#ifndef __ARCH_H__
#define __ARCH_H__
#include <stdint.h>
#define PMEM_SIZE (128 * 1024 * 1024)
/*
struct _Context {
uint32_t eax, ebx, ecx, edx,
esi, edi, ebp, esp3,
eip, eflags,
cs, ds, es, ss,
ss0, esp0;
void *prot;
};
*/
struct _Context {
struct _AddressSpace *prot;
uintptr_t edi, esi, ebp, esp;
@ -23,21 +9,10 @@ struct _Context {
uintptr_t err, eip, cs, eflags; // Execution state before trap
};
#define GPR1 eax
#define GPR2 ebx
#define GPR3 ecx
#define GPR4 edx
#define GPRx eax
#ifdef NEMU
#define GPR1 eax
#define GPR2 ebx
#define GPR3 ecx
#define GPR4 edx
#define GPRx eax
#endif
#endif

View File

@ -0,0 +1,19 @@
#ifndef __ARCH_H__
#define __ARCH_H__
struct _Context {
uint32_t eax, ebx, ecx, edx,
esi, edi, ebp, esp3,
eip, eflags,
cs, ds, es, ss,
ss0, esp0;
void *prot;
};
#define GPR1 eax
#define GPR2 ebx
#define GPR3 ecx
#define GPR4 edx
#define GPRx eax
#endif

View File

@ -3,7 +3,7 @@
#ifndef __ASSEMBLER__
#include <arch.h>
#include <stdint.h>
#define MMIO_OFFSET(addr) ((uintptr_t)0xa0000000 + addr)

5
am/include/nemu.h Normal file
View File

@ -0,0 +1,5 @@
#define PMEM_SIZE (128 * 1024 * 1024)
#define PGSIZE 4096
#ifdef __ARCH_X86_QEMU
#endif

View File

@ -96,8 +96,6 @@
// Below are only defined for c/cpp files
#ifndef __ASSEMBLER__
#include <arch.h>
// +--------10------+-------10-------+---------12----------+
// | Page Directory | Page Table | Offset within Page |
// | Index | Index | |

View File

@ -1 +0,0 @@
# MIPS32-NEMU

View File

@ -1,15 +1,23 @@
#include <am.h>
#include <mips32.h>
#include <amdev.h>
#define KBD_DATA_MMIO 0x4060
#define KEYDOWN_MASK 0x8000
#ifdef __ARCH_X86_NEMU
#include <x86.h>
#define KBD_ADDR 0x60
#endif
#ifdef __ARCH_MIPS32_NEMU
#include <mips32.h>
#define KBD_ADDR 0x4060
#endif
size_t input_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_INPUT_KBD: {
_DEV_INPUT_KBD_t *kbd = (_DEV_INPUT_KBD_t *)buf;
int k = inl(KBD_DATA_MMIO);
int k = inl(KBD_ADDR);
kbd->keydown = (k & KEYDOWN_MASK ? 1 : 0);
kbd->keycode = k & ~KEYDOWN_MASK;
return sizeof(_DEV_INPUT_KBD_t);

View File

@ -1,8 +1,16 @@
#include <am.h>
#include <mips32.h>
#include <amdev.h>
#define RTC_MMIO 0x4048 // Note that this is not standard
#ifdef __ARCH_X86_NEMU
#include <x86.h>
#define RTC_ADDR 0x48
#endif
#ifdef __ARCH_MIPS32_NEMU
#include <mips32.h>
#define RTC_ADDR 0x4048
#endif
static unsigned long boot_time;
size_t timer_read(uintptr_t reg, void *buf, size_t size) {
@ -10,7 +18,7 @@ size_t timer_read(uintptr_t reg, void *buf, size_t size) {
case _DEVREG_TIMER_UPTIME: {
_DEV_TIMER_UPTIME_t *uptime = (_DEV_TIMER_UPTIME_t *)buf;
uptime->hi = 0;
uptime->lo = inl(RTC_MMIO) - boot_time;
uptime->lo = inl(RTC_ADDR) - boot_time;
return sizeof(_DEV_TIMER_UPTIME_t);
}
case _DEVREG_TIMER_DATE: {
@ -28,5 +36,5 @@ size_t timer_read(uintptr_t reg, void *buf, size_t size) {
}
void timer_init() {
boot_time = inl(RTC_MMIO);
boot_time = inl(RTC_ADDR);
}

View File

@ -1,12 +1,23 @@
#include <am.h>
#include <mips32.h>
#include <amdev.h>
#include <klib.h>
#define SCREEN_MMIO 0x4100
#define SYNC_MMIO 0x4104
#ifdef __ARCH_X86_NEMU
#include <x86.h>
#define SCREEN_ADDR 0x100
#define SYNC_ADDR 0x104
#define FB_ADDR 0x40000
#endif
#ifdef __ARCH_MIPS32_NEMU
#include <mips32.h>
#define SCREEN_ADDR 0x4100
#define SYNC_ADDR 0x4104
#define FB_ADDR 0x40000
#endif
static int W, H;
static uint32_t* const fb = (uint32_t *)MMIO_OFFSET(0x40000);
static uint32_t* const fb = (uint32_t *)FB_ADDR;
size_t video_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
@ -38,7 +49,7 @@ size_t video_write(uintptr_t reg, void *buf, size_t size) {
}
if (ctl->sync) {
outl(SYNC_MMIO, 0);
outl(SYNC_ADDR, 0);
}
return size;
}
@ -47,7 +58,7 @@ size_t video_write(uintptr_t reg, void *buf, size_t size) {
}
void vga_init() {
uint32_t data = inl(SCREEN_MMIO);
uint32_t data = inl(SCREEN_ADDR);
W = data >> 16;
H = data & 0xffff;
}

View File

@ -0,0 +1,29 @@
SECTIONS {
. = 0x80100000;
.text : {
*(.text)
}
etext = .;
_etext = .;
.rodata : {
*(.rodata*)
}
.data : {
*(.data)
}
edata = .;
_data = .;
.bss : {
_bss_start = .;
*(.bss*)
*(.sbss*)
*(.scommon)
}
_stack_top = ALIGN(4096);
. = _stack_top + 0x8000;
_stack_pointer = .;
end = .;
_end = .;
_heap_start = ALIGN(4096);
_heap_end = 0x88000000;
}

View File

@ -0,0 +1,7 @@
.globl _start
.type _start, function
_start:
move $fp, $zero
la $sp, _stack_pointer
jal _trm_init

View File

@ -1,5 +1,6 @@
#include <mips32.h>
#include <klib.h>
#include <nemu.h>
#define PG_ALIGN __attribute((aligned(PGSIZE)))

View File

@ -1,19 +0,0 @@
#include <am.h>
#include <x86.h>
#include <amdev.h>
#define KBD_DATA_PORT 0x60
#define KEYDOWN_MASK 0x8000
size_t input_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_INPUT_KBD: {
_DEV_INPUT_KBD_t *kbd = (_DEV_INPUT_KBD_t *)buf;
int k = inl(KBD_DATA_PORT);
kbd->keydown = (k & KEYDOWN_MASK ? 1 : 0);
kbd->keycode = k & ~KEYDOWN_MASK;
return sizeof(_DEV_INPUT_KBD_t);
}
}
return 0;
}

View File

@ -1,32 +0,0 @@
#include <am.h>
#include <x86.h>
#include <amdev.h>
#define RTC_PORT 0x48 // Note that this is not standard
static unsigned long boot_time;
size_t timer_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_TIMER_UPTIME: {
_DEV_TIMER_UPTIME_t *uptime = (_DEV_TIMER_UPTIME_t *)buf;
uptime->hi = 0;
uptime->lo = inl(RTC_PORT) - boot_time;
return sizeof(_DEV_TIMER_UPTIME_t);
}
case _DEVREG_TIMER_DATE: {
_DEV_TIMER_DATE_t *rtc = (_DEV_TIMER_DATE_t *)buf;
rtc->second = 0;
rtc->minute = 0;
rtc->hour = 0;
rtc->day = 0;
rtc->month = 0;
rtc->year = 2018;
return sizeof(_DEV_TIMER_DATE_t);
}
}
return 0;
}
void timer_init() {
boot_time = inl(RTC_PORT);
}

View File

@ -1,53 +0,0 @@
#include <am.h>
#include <x86.h>
#include <amdev.h>
#include <klib.h>
#define SCREEN_PORT 0x100
#define SYNC_PORT 0x104
static int W, H;
static uint32_t* const fb = (uint32_t *)0x40000;
size_t video_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_VIDEO_INFO: {
_DEV_VIDEO_INFO_t *info = (_DEV_VIDEO_INFO_t *)buf;
info->width = W;
info->height = H;
return sizeof(_DEV_VIDEO_INFO_t);
}
}
return 0;
}
size_t video_write(uintptr_t reg, void *buf, size_t size) {
switch (reg) {
case _DEVREG_VIDEO_FBCTL: {
_DEV_VIDEO_FBCTL_t *ctl = (_DEV_VIDEO_FBCTL_t *)buf;
int x = ctl->x, y = ctl->y, w = ctl->w, h = ctl->h;
uint32_t *pixels = ctl->pixels;
int len = sizeof(uint32_t) * ( (x + w >= W) ? W - x : w );
uint32_t *p_fb = &fb[y * W + x];
int j;
for (j = 0; j < h; j ++) {
if (y + j < H) { memcpy(p_fb, pixels, len); }
else { break; }
p_fb += W;
pixels += w;
}
if (ctl->sync) {
outl(SYNC_PORT, 0);
}
return size;
}
}
return 0;
}
void vga_init() {
uint32_t data = inl(SCREEN_PORT);
W = data >> 16;
H = data & 0xffff;
}

View File

@ -1,12 +0,0 @@
#!/bin/bash
DIR=${AM_HOME}/am/arch/x86-nemu/img
DEST=$1
shift
make -C $DIR/boot -s
ld -melf_i386 --gc-sections -T $DIR/loader.ld -e _start -o $DEST $DIR/boot/start.o --start-group $@ --end-group
objdump -d $DEST > $DEST.txt
objcopy -S --set-section-flags .bss=alloc,contents -O binary $DEST $DEST.bin

View File

@ -1,3 +0,0 @@
#!/bin/bash
make -C $NEMU_HOME ISA=x86 run ARGS="-b -l `dirname $1`/nemu-log.txt $1.bin"

View File

@ -1,8 +0,0 @@
.section entry, "ax"
.globl _start
.type _start, @function
_start:
mov $0, %ebp
mov $_stack_pointer, %esp
call _trm_init # never return

View File

@ -1,5 +1,6 @@
#include <am.h>
#include <x86.h>
#include <nemu.h>
#define PG_ALIGN __attribute((aligned(PGSIZE)))