Skip to content

312551071 lab5 #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 312551071
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lab5/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
UseTab: Never
TabWidth: 4
IndentWidth: 4
AccessModifierOffset: -4

BasedOnStyle: Google
IncludeBlocks: Regroup
SortIncludes: true

7 changes: 7 additions & 0 deletions lab5/.clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CompileFlags:
Compiler: /usr/homebrew/bin/aarch64-linux-gnu-gcc
Add: [
"-Wall", "-ffreestanding", "-nostdinc", "-nostdlib", "-nostartfiles", "-fno-stack-protector", "-g", "-mgeneral-regs-only",
"-I/Users/yjack/GitHub/osc2024/lab5",
]

24 changes: 24 additions & 0 deletions lab5/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
QEMU_OPTS = -initrd new_initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb
BUILD_DIR := $(CURDIR)/build

.PHONY: all bootloader kernel run clean

all: clean kernel run

clean:
rm -rf $(BUILD_DIR)

bootloader: clean
$(MAKE) -C bootloader BUILD_DIR=$(BUILD_DIR) LIB_PATH=$(CURDIR)/lib BSP_PATH=$(CURDIR)/bsp

kernel: clean
$(MAKE) -C kernel BUILD_DIR=$(BUILD_DIR) LIB_PATH=$(CURDIR)/lib BSP_PATH=$(CURDIR)/bsp

run:
qemu-system-aarch64 -M raspi3b -kernel $(BUILD_DIR)/kernel8.img -display none -serial null -serial stdio $(QEMU_OPTS)

run-bootloader:
qemu-system-aarch64 -M raspi3b -kernel $(BUILD_DIR)/kernel8.img -display none -serial null -serial pty $(QEMU_OPTS)

debug: clean kernel
qemu-system-aarch64 -M raspi3b -kernel $(BUILD_DIR)/kernel8.img -display none -serial null -serial stdio -s -S $(QEMU_OPTS)
22 changes: 22 additions & 0 deletions lab5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# OSC2023-Lab01

| Github Account | Student ID |
| -------------- | ---------- |
| visitorckw | 312551071 |

## Requirements

- a cross-compiler for aarch64
- (optional) qemu-system-aarch64

## Build

```
make
```

## Test With QEMU

```
make run
```
Binary file added lab5/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
28 changes: 28 additions & 0 deletions lab5/bsp/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// BCM2837 ARM Peripherals Page 6
#define MMIO_BASE \
0x3F000000
// BCM2835 page. 112-116
#define IRQ_BASIC_PENDING ((volatile unsigned int*)(MMIO_BASE + 0x0000B200))
#define IRQ_PENDING_1 \
((volatile unsigned int*)(MMIO_BASE + \
0x0000B204)) // Holds All interrupts 0...31 from
// the GPU side.
#define IRQ_PENDING_2 \
((volatile unsigned int*)(MMIO_BASE + 0x0000B208)) // 32...63
#define FIQ_CONTROL ((volatile unsigned int*)(MMIO_BASE + 0x0000B20C))
#define ENABLE_IRQS_1 \
((volatile unsigned int*)(MMIO_BASE + \
0x0000B210)) // Writing a 1 to a bit will set
// the corresponding IRQ enable bit.
// (0-31)
#define ENABLE_IRQS_2 \
((volatile unsigned int*)(MMIO_BASE + 0x0000B214)) // (32-63)
#define ENABLE_BASIC_IRQS ((volatile unsigned int*)(MMIO_BASE + 0x0000B218))
#define DISABLE_IRQS_1 ((volatile unsigned int*)(MMIO_BASE + 0x0000B21C))
#define DISABLE_IRQS_2 ((volatile unsigned int*)(MMIO_BASE + 0x0000B220))
#define DISABLE_BASIC_IRQS \
((volatile unsigned int*)(MMIO_BASE + 0x0000B224)) // AUX interrupt. 29

// QA7 page. 16
#define CORE0_IRQ_SOURCE \
((volatile unsigned int*)(0x40000060)) // Get the IRQ source for the core 0.
114 changes: 114 additions & 0 deletions lab5/bsp/entry.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* save general registers to stack */
.macro save_all
sub sp, sp, 16 * 17
stp x0, x1, [sp, 16 * 0]
stp x2, x3, [sp, 16 * 1]
stp x4, x5, [sp, 16 * 2]
stp x6, x7, [sp, 16 * 3]
stp x8, x9, [sp, 16 * 4]
stp x10, x11, [sp, 16 * 5]
stp x12, x13, [sp, 16 * 6]
stp x14, x15, [sp, 16 * 7]
stp x16, x17, [sp, 16 * 8]
stp x18, x19, [sp, 16 * 9]
stp x20, x21, [sp, 16 * 10]
stp x22, x23, [sp, 16 * 11]
stp x24, x25, [sp, 16 * 12]
stp x26, x27, [sp, 16 * 13]
stp x28, x29, [sp, 16 * 14]
mrs x10, spsr_el1
mrs x11, elr_el1
mrs x12, sp_el0
stp x30, x10, [sp, 16 * 15]
stp x11, x12, [sp, 16 * 16]
.endm

/* load general registers from stack */
.macro load_all
ldp x30, x10, [sp, 16 * 15]
ldp x11, x12, [sp, 16 * 16]
msr spsr_el1, x10
msr elr_el1, x11
msr sp_el0, x12
ldp x0, x1, [sp, 16 * 0]
ldp x2, x3, [sp, 16 * 1]
ldp x4, x5, [sp, 16 * 2]
ldp x6, x7, [sp, 16 * 3]
ldp x8, x9, [sp, 16 * 4]
ldp x10, x11, [sp, 16 * 5]
ldp x12, x13, [sp, 16 * 6]
ldp x14, x15, [sp, 16 * 7]
ldp x16, x17, [sp, 16 * 8]
ldp x18, x19, [sp, 16 * 9]
ldp x20, x21, [sp, 16 * 10]
ldp x22, x23, [sp, 16 * 11]
ldp x24, x25, [sp, 16 * 12]
ldp x26, x27, [sp, 16 * 13]
ldp x28, x29, [sp, 16 * 14]
add sp, sp, 16 * 17
.endm

exception_handler:
save_all
mov x0, sp
bl exception_entry // defined in traps.c
load_all
eret

irq_handler:
save_all
mov x0, sp
bl irq_entry // defined in irq.c
load_all
eret

invalid_exc_handler:
save_all
mrs x0, elr_el1
mrs x1, esr_el1
mrs x2, spsr_el1
bl invalid_entry // defined in traps.c
load_all
eret

.global child_ret_from_fork
child_ret_from_fork:
load_all
eret

.global sigreturn
sigreturn:
mov x8, 139
svc 0

.macro ventry label
b \label
.align 7
.endm

/* EL1 Exception Vector table
* vector table should be aligned to 0x800
* and each entry size is 0x80 */
.align 11
.global exception_vector_table
exception_vector_table:
// EL1 -> EL1 while using SP_EL0
ventry invalid_exc_handler
ventry invalid_exc_handler
ventry invalid_exc_handler
ventry invalid_exc_handler
// EL1 -> EL1 while using SP_EL1
ventry invalid_exc_handler
ventry irq_handler
ventry invalid_exc_handler
ventry invalid_exc_handler
// EL0 (AArch64) -> EL1
ventry exception_handler
ventry irq_handler
ventry invalid_exc_handler
ventry invalid_exc_handler
// EL0 (AArch32) -> EL1
ventry invalid_exc_handler
ventry invalid_exc_handler
ventry invalid_exc_handler
ventry invalid_exc_handler
39 changes: 39 additions & 0 deletions lab5/bsp/entry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef _ENTRY_H
#define _ENTRY_H

#define S_FRAME_SIZE 272 // size of all saved registers, which is 16*17 from pt_regs
#define S_X0 0 // offset of x0 register in saved stack frame

#define SYNC_INVALID_EL1t 0
#define IRQ_INVALID_EL1t 1
#define FIQ_INVALID_EL1t 2
#define ERROR_INVALID_EL1t 3

#define SYNC_INVALID_EL1h 4
#define IRQ_INVALID_EL1h 5
#define FIQ_INVALID_EL1h 6
#define ERROR_INVALID_EL1h 7

#define SYNC_INVALID_EL0_64 8
#define IRQ_INVALID_EL0_64 9
#define FIQ_INVALID_EL0_64 10
#define ERROR_INVALID_EL0_64 11

#define SYNC_INVALID_EL0_32 12
#define IRQ_INVALID_EL0_32 13
#define FIQ_INVALID_EL0_32 14
#define ERROR_INVALID_EL0_32 15

#define SYNC_ERROR 16
#define SYSCALL_ERROR 17

#endif

#ifndef __ASSEMBLER__
#include <lib/stddef.h>

void ret_from_fork(void);

void from_el1_to_el0(uint64_t, uint64_t);

#endif
25 changes: 25 additions & 0 deletions lab5/bsp/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _GPIO_H
#define _GPIO_H

#define MMIO_BASE 0x3F000000 // BCM2837 ARM Peripherals Page 6

#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE + 0x00200000))
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE + 0x00200004))
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE + 0x00200008))
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE + 0x0020000C))
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE + 0x00200010))
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE + 0x00200014))
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE + 0x0020001C))
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE + 0x00200020))
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE + 0x00200028))
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE + 0x00200034))
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE + 0x00200038))
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE + 0x00200040))
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE + 0x00200044))
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE + 0x00200064))
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE + 0x00200068))
#define GPPUD ((volatile unsigned int*)(MMIO_BASE + 0x00200094))
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE + 0x00200098))
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE + 0x0020009C))

#endif
29 changes: 29 additions & 0 deletions lab5/bsp/gpu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "base.h"
/* Auxilary mini UART registers */
#define AUX_ENABLE ((volatile unsigned int *)(MMIO_BASE + 0x00215004))
#define AUX_MU_IO ((volatile unsigned int *)(MMIO_BASE + 0x00215040))
#define AUX_MU_IER ((volatile unsigned int *)(MMIO_BASE + 0x00215044))
#define AUX_MU_IIR ((volatile unsigned int *)(MMIO_BASE + 0x00215048))
#define AUX_MU_LCR ((volatile unsigned int *)(MMIO_BASE + 0x0021504C))
#define AUX_MU_MCR ((volatile unsigned int *)(MMIO_BASE + 0x00215050))
#define AUX_MU_LSR ((volatile unsigned int *)(MMIO_BASE + 0x00215054))
#define AUX_MU_MSR ((volatile unsigned int *)(MMIO_BASE + 0x00215058))
#define AUX_MU_SCRATCH ((volatile unsigned int *)(MMIO_BASE + 0x0021505C))
#define AUX_MU_CNTL ((volatile unsigned int *)(MMIO_BASE + 0x00215060))
#define AUX_MU_STAT ((volatile unsigned int *)(MMIO_BASE + 0x00215064))
#define AUX_MU_BAUD ((volatile unsigned int *)(MMIO_BASE + 0x00215068))

#include <bsp/irq.h>
#include <bsp/uart.h>
#include <lib/stdlib.h>

uint32_t is_aux_irq() {
// uart_puts("\nIRQ_PENDING_1: ");
// uart_hex((unsigned long)*IRQ_PENDING_1);
// uart_puts("\n");
return (*IRQ_PENDING_1 & (1 << 29));
}

uint32_t is_uart_rx_irq() { return (*AUX_MU_IIR & 0x6) == (1 << 2); }

uint32_t is_uart_tx_irq() { return (*AUX_MU_IIR & 0x6) == (1 << 1); }
29 changes: 29 additions & 0 deletions lab5/bsp/irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef __IRQ_H__
#define __IRQ_H__

#include <lib/stddef.h>

// el1 IRQ can be disable to protect the critical sections
void enable_irq();
void disable_irq();

// GPU IRQ handle is used to handle the GPU IRQ such as UART IRQ
void gpu_irq_handler();

// Core timer IRQ handle is used to handle the core timer IRQ
void core_timer_enable();
void core_timer_disable();
void core_timer_irq_handler();
uint64_t timer_get_uptime();

// IRQ utils
uint32_t is_core_timer_irq();
uint32_t is_gpu_irq();

uint32_t is_aux_irq();
uint32_t is_uart_rx_irq();
uint32_t is_uart_tx_irq();

const char *get_exception_message(unsigned long type);

#endif
26 changes: 26 additions & 0 deletions lab5/bsp/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

SECTIONS
{
. = 0x60000;
__loader_start = .;
. = 0x80000;
.text :
{
KEEP(*(.text.boot))
*(.text)
}
.rodata :{ *(.rodata) }
.data : { *(.data) }
.bss :
{
__bss_start = .;
*(.bss)
*(COMMON)
__bss_end = .;
}
. = ALIGN(8);
__heap_start = .;
__loader_end = .;
}
__bss_size = (__bss_end - __bss_start) >> 3;
__loader_size = (__loader_end - __loader_start) >> 3;
Loading