Skip to content

312551071 lab7 #286

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
Show file tree
Hide file tree
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 lab7/.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 lab7/.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/lab7/include",
]

24 changes: 24 additions & 0 deletions lab7/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
QEMU_OPTS = -initrd 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 lab7/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 lab7/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
114 changes: 114 additions & 0 deletions lab7/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 lab7/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
90 changes: 90 additions & 0 deletions lab7/bsp/fbdev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <bsp//mailbox.h>
#include <bsp/fbdev.h>
#include <bsp/mailbox.h>
#include <bsp/uart.h>
#include <lib/string.h>

unsigned int __attribute__((aligned(16))) mbox[36];

unsigned int width, height, pitch, isrgb; /* dimensions and channel order */
unsigned char *lfb;

// This function is responsible for setting up the framebuffer
int fb_init() {
mbox[0] = 35 * 4; // Total size of the message
mbox[1] = MBOX_REQUEST;

// Set physical width-height
mbox[2] = 0x48003;
mbox[3] = 8;
mbox[4] = 8;
mbox[5] = 1024; // width
mbox[6] = 768; // height

// Set virtual width-height
mbox[7] = 0x48004;
mbox[8] = 8;
mbox[9] = 8;
mbox[10] = 1024; // virtual width
mbox[11] = 768; // virtual height

// Set virtual offset
mbox[12] = 0x48009;
mbox[13] = 8;
mbox[14] = 8;
mbox[15] = 0; // x offset
mbox[16] = 0; // y offset

// Set depth
mbox[17] = 0x48005;
mbox[18] = 4;
mbox[19] = 4;
mbox[20] = 32; // depth

// Set pixel order
mbox[21] = 0x48006;
mbox[22] = 4;
mbox[23] = 4;
mbox[24] = 1; // RGB, not BGR

// Get framebuffer
mbox[25] = 0x40001;
mbox[26] = 8;
mbox[27] = 8;
mbox[28] = 4096; // pointer to framebuffer
mbox[29] = 0; // size

// Get pitch
mbox[30] = 0x40008;
mbox[31] = 4;
mbox[32] = 4;
mbox[33] = 0; // pitch

mbox[34] = MBOX_TAG_LAST;

// Call the mailbox
if (mailbox_call(MBOX_CH_PROP, mbox) && mbox[20] == 32 && mbox[28] != 0) {
mbox[28] &= 0x3FFFFFFF; // Convert GPU address to ARM address

width = mbox[5]; // get actual physical width
height = mbox[6]; // get actual physical height
pitch = mbox[33]; // get number of bytes per line
isrgb = mbox[24]; // get the actual channel order
lfb = (void *)((unsigned long)mbox[28]);

// Use the framebuffer (width, height, pitch, isrgb, lfb)
return 0; // Success
}

return -1; // Failure
}

int fb_write(size_t pos, const void *buf, size_t len) {
if (len + pos > pitch * height) {
uart_puts("[ERROR] Attempted write out of bounds\r\n");
return -1;
}

memcpy(lfb + pos, buf, len);
return 0;
}
16 changes: 16 additions & 0 deletions lab7/bsp/fbdev.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef _FBDEV_H_
#define _FBDEV_H_

#include <lib/stddef.h>

struct framebuffer_info {
unsigned int width;
unsigned int height;
unsigned int pitch;
unsigned int isrgb;
};

int fb_init();
int fb_write(size_t pos, const void *buf, size_t len);

#endif
25 changes: 25 additions & 0 deletions lab7/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 lab7/bsp/gpu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <bsp/irq.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); }
Loading