Skip to content
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

A121163 Lab4 #200

Open
wants to merge 4 commits into
base: main
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
Binary file modified lab3/kernel/build/kernel8.elf
Binary file not shown.
7 changes: 3 additions & 4 deletions lab3/kernel/src/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ void el1h_irq_router(){
if (*AUX_MU_IIR_REG & (1 << 1)) // FIFO clear bits
{
*AUX_MU_IER_REG &= ~(2); // disable write interrupt
irqtask_add(uart_w_irq_handler, UART_IRQ_PRIORITY);
irqtask_add(uart_w_irq_handler, UART_IRQ_PRIORITY); //rpi write mean we read
irqtask_run_preemptive(); // run the queued task before returning to the program.
}
else if (*AUX_MU_IIR_REG & (2 << 1)) // Interrupt ID bits
{
*AUX_MU_IER_REG &= ~(1); // disable read interrupt
irqtask_add(uart_r_irq_handler, timer_priority);
irqtask_add(uart_r_irq_handler, UART_IRQ_PRIORITY); //rpi read mean we write
irqtask_run_preemptive();
}
}
Expand Down Expand Up @@ -154,8 +154,7 @@ void irqtask_run_preemptive()
// Run new task (early return) if its priority is lower than the scheduled task.
if (curr_task_priority <= the_task->priority)
{
exit = 1;

//exit = 1;
el1_interrupt_enable();
break;
}
Expand Down
10 changes: 5 additions & 5 deletions lab3/kernel/src/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ void cli_cmd_read(char* buffer)
while (1)
{
if (idx >= CMD_MAX_LEN) break;
c = uart_async_getc(); //test preemtive
c = uart_async_getc();
if (c == '\n') break;

if (c == 127 && idx > 0)
{
uart_puts("\b \b"); //test preemptive
uart_puts("\b \b");
idx--;
continue;
}
Expand Down Expand Up @@ -301,7 +301,7 @@ void do_cmd_reboot()
void do_test_preemptive()
{
add_timer(test_loop, 1, "test loop");
add_timer(set_exit, 10, "exit");
add_timer(set_exit, 5, "exit");
}

volatile int exit = 0;
Expand All @@ -314,6 +314,6 @@ void test_loop()

void set_exit()
{
//exit = 1;
uart_sendline("We set exit as 1 to exit infinite loop at t = 10s.\n");
exit = 1;
uart_sendline("We set exit as 1 to exit infinite loop at t = 5s.\n");
}
4 changes: 3 additions & 1 deletion lab3/kernel/src/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define STR(x) #x
#define XSTR(s) STR(s)


struct list_head* timer_event_list; // first head has nothing, store timer_event_t after it

void timer_list_init(){
Expand Down Expand Up @@ -60,12 +61,13 @@ void timer_event_callback(timer_event_t * timer_event){
}
core_timer_enable();
((void (*)(char*))timer_event->callback)(timer_event->args); // call the event

}

void timer_set2sAlert(char* str)
{
static int count = 0;
if(count > 10){
if(count > 3){
return;
}
count++;
Expand Down
84 changes: 58 additions & 26 deletions lab3/kernel/src/uart1.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,32 +90,53 @@ int uart_sendline(char* fmt, ...) {
}


// uart_async_getc read from buffer
// uart_r_irq_handler write to buffer then output
// Read a character asynchronously from UART receive buffer.
char uart_async_getc() {
*AUX_MU_IER_REG |=1; // enable read interrupt
// do while if buffer empty
while (uart_rx_buffer_ridx == uart_rx_buffer_widx) *AUX_MU_IER_REG |=1; // enable read interrupt
// Enable read interrupt
*AUX_MU_IER_REG |= 1;

// Loop until the buffer has data
while (uart_rx_buffer_ridx == uart_rx_buffer_widx) {
*AUX_MU_IER_REG |= 1; // Keep enabling read interrupt
}

// Disable interrupts to ensure atomic operations
el1_interrupt_disable();

// Read character from the buffer and increment read index
char r = uart_rx_buffer[uart_rx_buffer_ridx++];
// Wrap around the index if it exceeds the buffer size
if (uart_rx_buffer_ridx >= VSPRINT_MAX_BUF_SIZE) uart_rx_buffer_ridx = 0;

// Re-enable interrupts
el1_interrupt_enable();
return r;

return r; // Return the read character
}


// uart_async_putc writes to buffer
// uart_w_irq_handler read from buffer then output
// Write a character asynchronously to UART transmit buffer.
void uart_async_putc(char c) {
// if buffer full, wait for uart_w_irq_handler
while( (uart_tx_buffer_widx + 1) % VSPRINT_MAX_BUF_SIZE == uart_tx_buffer_ridx ) *AUX_MU_IER_REG |=2; // enable write interrupt
// Wait if the buffer is full
while((uart_tx_buffer_widx + 1) % VSPRINT_MAX_BUF_SIZE == uart_tx_buffer_ridx) {
*AUX_MU_IER_REG |= 2; // Enable write interrupt
}

// Disable interrupts to ensure atomic operations
el1_interrupt_disable();

// Write character to the buffer and increment write index
uart_tx_buffer[uart_tx_buffer_widx++] = c;
if(uart_tx_buffer_widx >= VSPRINT_MAX_BUF_SIZE) uart_tx_buffer_widx=0; // cycle pointer
// Wrap around the index if it exceeds the buffer size
if(uart_tx_buffer_widx >= VSPRINT_MAX_BUF_SIZE) uart_tx_buffer_widx = 0;

// Re-enable interrupts
el1_interrupt_enable();
*AUX_MU_IER_REG |=2; // enable write interrupt

// Enable write interrupt
*AUX_MU_IER_REG |= 2;
}


int uart_puts(char* fmt, ...) {
__builtin_va_list args;
__builtin_va_start(args, fmt);
Expand Down Expand Up @@ -147,25 +168,36 @@ void uart_interrupt_disable(){
}


void uart_r_irq_handler(){
if((uart_rx_buffer_widx + 1) % VSPRINT_MAX_BUF_SIZE == uart_rx_buffer_ridx)
{
*AUX_MU_IER_REG &= ~(1); // disable read interrupt
// UART receive interrupt handler
void uart_r_irq_handler() {
// Check if the buffer is full
if((uart_rx_buffer_widx + 1) % VSPRINT_MAX_BUF_SIZE == uart_rx_buffer_ridx) {
// Disable read interrupt to prevent overflow
*AUX_MU_IER_REG &= ~(1);
return;
}
// Read data from UART and store it in the buffer
uart_rx_buffer[uart_rx_buffer_widx++] = uart_recv();
if(uart_rx_buffer_widx>=VSPRINT_MAX_BUF_SIZE) uart_rx_buffer_widx=0;
*AUX_MU_IER_REG |=1;
// Wrap the write index if it reaches the buffer size
if(uart_rx_buffer_widx >= VSPRINT_MAX_BUF_SIZE) uart_rx_buffer_widx = 0;
// Re-enable read interrupt
*AUX_MU_IER_REG |= 1;
}

void uart_w_irq_handler(){
if(uart_tx_buffer_ridx == uart_tx_buffer_widx)
{
*AUX_MU_IER_REG &= ~(2); // disable write interrupt
return; // buffer empty
// UART write interrupt handler
void uart_w_irq_handler() {
// Check if the buffer is empty
if(uart_tx_buffer_ridx == uart_tx_buffer_widx) {
// Disable write interrupt to avoid unnecessary interrupts
*AUX_MU_IER_REG &= ~(2);
return; // Exit if nothing to send
}
// Send data from the buffer via UART
uart_send(uart_tx_buffer[uart_tx_buffer_ridx++]);
if(uart_tx_buffer_ridx>=VSPRINT_MAX_BUF_SIZE) uart_tx_buffer_ridx=0;
*AUX_MU_IER_REG |=2; // enable write interrupt
// Wrap the read index if it reaches the buffer size
if(uart_tx_buffer_ridx >= VSPRINT_MAX_BUF_SIZE) uart_tx_buffer_ridx = 0;
// Re-enable write interrupt
*AUX_MU_IER_REG |= 2;
}


Binary file added lab4/bootloader/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
3 changes: 3 additions & 0 deletions lab4/bootloader/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kernel=bootloader.img
arm_64bit=1
initramfs initramfs.cpio 0x8000000
6 changes: 6 additions & 0 deletions lab4/bootloader/include/bcm2837/rpi_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _RPI_BASE_H_
#define _RPI_BASE_H_

#define PERIPHERAL_BASE 0x3F000000

#endif /*_RPI_BASE_H_ */
25 changes: 25 additions & 0 deletions lab4/bootloader/include/bcm2837/rpi_gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _RPI_GPIO_H_
#define _RPI_GPIO_H_

#include "bcm2837/rpi_base.h"

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

#endif /*_RPI_GPIO_H_*/
19 changes: 19 additions & 0 deletions lab4/bootloader/include/bcm2837/rpi_uart1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _RPI_UART1_H_
#define _RPI_UART1_H_

#include "bcm2837/rpi_base.h"

#define AUX_ENABLES ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215004))
#define AUX_MU_IO_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215040))
#define AUX_MU_IER_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215044))
#define AUX_MU_IIR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215048))
#define AUX_MU_LCR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x0021504C))
#define AUX_MU_MCR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215050))
#define AUX_MU_LSR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215054))
#define AUX_MU_MSR_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215058))
#define AUX_MU_SCRATCH ((volatile unsigned int*)(PERIPHERAL_BASE+0x0021505C))
#define AUX_MU_CNTL_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215060))
#define AUX_MU_STAT_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215064))
#define AUX_MU_BAUD_REG ((volatile unsigned int*)(PERIPHERAL_BASE+0x00215068))

#endif /*_RPI_UART1_H_ */
8 changes: 8 additions & 0 deletions lab4/bootloader/include/power.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _POWER_H_
#define _POWER_H_

#define PM_PASSWORD 0x5a000000
#define PM_RSTC 0x3F10001c
#define PM_WDOG 0x3F100024

#endif /*_POWER_H_*/
23 changes: 23 additions & 0 deletions lab4/bootloader/include/shell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef _SHELL_H_
#define _SHELL_H_

#define CLI_MAX_CMD 3
#define CMD_MAX_LEN 32
#define MSG_MAX_LEN 128

typedef struct CLI_CMDS
{
char command[CMD_MAX_LEN];
char help[MSG_MAX_LEN];
} CLI_CMDS;

void cli_cmd_clear(char*, int);
void cli_cmd_read(char*);
void cli_cmd_exec(char*);
void cli_print_banner();

void do_cmd_help();
void do_cmd_loadimg();
void do_cmd_reboot();

#endif /* _SHELL_H_ */
11 changes: 11 additions & 0 deletions lab4/bootloader/include/uart1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _UART1_H_
#define _UART1_H_

void uart_init();
char uart_getc();
char uart_recv();
void uart_send(unsigned int c);
int uart_puts(char* fmt, ...);
void uart_2hex(unsigned int d);

#endif /*_UART1_H_*/
11 changes: 11 additions & 0 deletions lab4/bootloader/include/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _UTILS_H_
#define _UTILS_H_

#define VSPRINT_MAX_BUF_SIZE 128

unsigned int sprintf(char *dst, char* fmt, ...);
unsigned int vsprintf(char *dst,char* fmt, __builtin_va_list args);

int strcmp(const char*, const char*);

#endif /* _UTILS_H_ */
42 changes: 42 additions & 0 deletions lab4/bootloader/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
ARMGNU ?= aarch64-linux-gnu

CFLAGS = -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude -mgeneral-regs-only
ASMFLAGS = -Iinclude

BUILD_DIR = build
SRC_DIR = src
#---------------------------------------------------------------------------------------

C_FILES = $(wildcard $(SRC_DIR)/*.c)
ASM_FILES = $(wildcard $(SRC_DIR)/*.S)
OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o)
OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o)

DEP_FILES = $(OBJ_FILES:%.o=%.d)
-include $(DEP_FILES)

$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(ARMGNU)-gcc $(CFLAGS) -MMD -c $< -o $@

$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
$(ARMGNU)-gcc $(ASMFLAGS) -MMD -c $< -o $@

bootloader.img: $(SRC_DIR)/link.ld $(OBJ_FILES)
$(ARMGNU)-ld -T $(SRC_DIR)/link.ld -o $(BUILD_DIR)/bootloader.elf $(OBJ_FILES)
$(ARMGNU)-objcopy $(BUILD_DIR)/bootloader.elf -O binary bootloader.img

all: bootloader.img

clean:
rm -rf $(BUILD_DIR) *.img

run_std:
qemu-system-aarch64 -M raspi3b -kernel bootloader.img -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb

run_pty:
qemu-system-aarch64 -M raspi3b -kernel bootloader.img -serial null -serial pty -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb

debug:
qemu-system-aarch64 -M raspi3b -kernel bootloader.img -display none -S -s

Loading