From 6960c1ccba46373780355b6f444078a751d48b54 Mon Sep 17 00:00:00 2001 From: Zihao Yu Date: Tue, 10 Mar 2020 17:13:30 +0800 Subject: [PATCH] add x86-sdi --- am/arch/x86-sdi.mk | 32 +++++++++++++++++++++ am/include/arch/x86-sdi.h | 1 + am/src/sdi/include/nemu.h | 53 +++++++++++++++++++++++++++++++++++ am/src/sdi/ldscript/loader.ld | 7 +++++ am/src/sdi/trm.c | 25 +++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 am/arch/x86-sdi.mk create mode 100644 am/include/arch/x86-sdi.h create mode 100644 am/src/sdi/include/nemu.h create mode 100644 am/src/sdi/ldscript/loader.ld create mode 100644 am/src/sdi/trm.c diff --git a/am/arch/x86-sdi.mk b/am/arch/x86-sdi.mk new file mode 100644 index 00000000..5cf6777a --- /dev/null +++ b/am/arch/x86-sdi.mk @@ -0,0 +1,32 @@ +include $(AM_HOME)/am/arch/isa/x86.mk + +AM_SRCS += sdi/trm.c \ + nemu/common/mainargs.S \ + nemu/isa/x86/boot/start.S \ + nemu/common/ioe.c \ + nemu/common/input.c \ + nemu/common/timer.c \ + nemu/common/video.c \ + dummy/mpe.c \ + +CFLAGS += -mstringop-strategy=loop -I$(AM_HOME)/am/src/sdi/include +ASFLAGS += -DMAINARGS=\"$(mainargs)\" +.PHONY: $(AM_HOME)/am/src/nemu/common/mainargs.S + +LDFLAGS += -L $(AM_HOME)/am/src/nemu/ldscript +LDFLAGS += -T $(AM_HOME)/am/src/sdi/ldscript/loader.ld + +NEMU_ARGS = --batch --log=$(shell dirname $(BINARY))/nemu-log.txt $(BINARY).bin + +image: + @echo + LD "->" $(BINARY_REL).elf + @$(LD) $(LDFLAGS) --gc-sections -o $(BINARY).elf $(LINK_FILES) + @$(OBJDUMP) -d $(BINARY).elf > $(BINARY).txt + @echo + OBJCOPY "->" $(BINARY_REL).bin + @$(OBJCOPY) -S --set-section-flags .bss=alloc,contents -O binary $(BINARY).elf $(BINARY).bin + +run: + $(MAKE) -C $(NEMU_HOME) ISA=$(ISA) run ARGS="$(NEMU_ARGS)" + +gdb: image + $(MAKE) -C $(NEMU_HOME) ISA=$(ISA) gdb ARGS="$(NEMU_ARGS)" diff --git a/am/include/arch/x86-sdi.h b/am/include/arch/x86-sdi.h new file mode 100644 index 00000000..a45d58ba --- /dev/null +++ b/am/include/arch/x86-sdi.h @@ -0,0 +1 @@ +#include "x86-nemu.h" diff --git a/am/src/sdi/include/nemu.h b/am/src/sdi/include/nemu.h new file mode 100644 index 00000000..35e3aa33 --- /dev/null +++ b/am/src/sdi/include/nemu.h @@ -0,0 +1,53 @@ +#ifndef __NEMU_H__ +#define __NEMU_H__ + +#include + +# define SERIAL_PORT 0xa10003f8 +# define KBD_ADDR 0xa1000060 +# define RTC_ADDR 0xa1000048 +# define SCREEN_ADDR 0xa1000100 +# define SYNC_ADDR 0xa1000104 +# define FB_ADDR 0xa0000000 + +#define MMIO_BASE 0xa0000000 +#define MMIO_SIZE 0x10000000 + +static inline uint8_t inb(uintptr_t addr) { return *(volatile uint8_t *)addr; } +static inline uint16_t inw(uintptr_t addr) { return *(volatile uint16_t *)addr; } +static inline uint32_t inl(uintptr_t addr) { return *(volatile uint32_t *)addr; } + +static inline void outb(uintptr_t addr, uint8_t data) { *(volatile uint8_t *)addr = data; } +static inline void outw(uintptr_t addr, uint16_t data) { *(volatile uint16_t *)addr = data; } +static inline void outl(uintptr_t addr, uint32_t data) { *(volatile uint32_t *)addr = data; } + +extern char _pmem_start, _pmem_end; + +#define NEMU_PADDR_SPACE \ + RANGE(&_pmem_start, &_pmem_end), \ + RANGE(0xa0000000, 0xa0000000 + 0x80000), /* vmem */ \ + RANGE(0xa1000000, 0xa1000000 + 0x1000) /* serial, rtc, screen, keyboard */ + +#define PGSIZE 4096 +#define PGSHFT 12 // log2(PGSIZE) +#define PN(addr) ((uintptr_t)(addr) >> PGSHFT) +#define OFF(va) ((uintptr_t)(va) & (PGSIZE - 1)) + +typedef uintptr_t PTE; + +typedef struct { + int ptw_level; + int vpn_width; +} ptw_config; + +// Offset of VPN[i] in a virtual address +static inline int VPNiSHFT(const ptw_config c, int i) { + return (PGSHFT) + c.vpn_width * i; +} +// Extract the VPN[i] field in a virtual address +static inline uintptr_t VPNi(const ptw_config c, uintptr_t va, int i) { + uintptr_t vpn_mask = (1 << c.vpn_width) - 1; + return (va >> VPNiSHFT(c, i)) & vpn_mask; +} + +#endif diff --git a/am/src/sdi/ldscript/loader.ld b/am/src/sdi/ldscript/loader.ld new file mode 100644 index 00000000..cf8ac10d --- /dev/null +++ b/am/src/sdi/ldscript/loader.ld @@ -0,0 +1,7 @@ +pmem_base = 0x0; + +MEMORY { + ram (rwxa) : ORIGIN = 0x0, LENGTH = 128M +} + +INCLUDE "section.ld" diff --git a/am/src/sdi/trm.c b/am/src/sdi/trm.c new file mode 100644 index 00000000..d05baaec --- /dev/null +++ b/am/src/sdi/trm.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +extern char _heap_start; +int main(const char *args); + +_Area _heap = RANGE(&_heap_start, &_pmem_end); + +void _trm_init() { + extern const char __am_mainargs; + int ret = main(&__am_mainargs); + _halt(ret); +} + +void _putc(char ch) { + outb(SERIAL_PORT, ch); +} + +void _halt(int code) { + printf("Exit with code = %d\n", code); + printf("Spinning\n"); + while (1); +}