diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 2cb93610c..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,13 +0,0 @@ -## Self-Check -- [ ] The base branch belongs to me. -- [ ] There are no large files, useless binaries, or temporary files in the new commits. -- [ ] The PR name contains my student ID and lab assignment number. eg. `0816171 lab0` - -> The following sections are optional. -## Description -A few messages about the pull request. - -## TODO -- Are there any bugs you have not fixed? -- Are there any features you have not implemented? -- Any advices about the lab. diff --git a/README.md b/README.md new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ + diff --git a/README.org b/README.org deleted file mode 100644 index a77151714..000000000 --- a/README.org +++ /dev/null @@ -1,79 +0,0 @@ -#+TITLE: Operating Systems Capstone 2023 -#+OPTIONS: toc:nil - -This repository is used for homework submission. - -*To protect your rights, please create a pull request (PR) before the demo and* -*make sure the TA merges your PR after the demo.* - -* How To Submit Homework - -** Overview -For those who are familiar with git. -1. TA creates a branch named your student ID. -2. You fork this repo. -3. Base on the == branch, you do your labs and put your code in the - forked repo. -4. Create a PR to the == branch in this repo to submit the homework. -5. TA merges the PR as a proof that you have demo the lab. - -** Fork The Repo -Fork the repository on Github. - -[[./images/fork_button.jpg]] - -Uncheck the "Copy the =main= branch only". - -[[./images/create_fork.jpg]] - -If you don't want to see a lot of redundant branches in the forked repo, keep -the checkbox checked and follow the [[./git-usage.org][guide]] to fetch your own branch. - -** Clone To Your Computer -Clone the forked repo and switch to the branch named your student id. -If you cannot find your branch, ask TAs for help. - -[[./images/clone_url.jpg]] - -#+BEGIN_SRC shell - git clone - cd osc2023 - git checkout --track origin/ -#+END_SRC - -** Specify Personal Information -Write down the following info in your =README.md= (or =README.org=, =README.rst= -etc.) -+ Github account name -+ Student ID -+ Your name -+ Any other information you want - -Here is an example [[https://github.com/psychicalcoder/osc2023/blob/0816171/README.md][README.md]]. - -** Implement Your Kernel -Design and implement your kernel in the forked repository. -#+BEGIN_QUOTE - Make good use of =.gitignore=. In the git history, we do not want to see - binaries, objective files, __MACOSX, python caches, super large test files, - or any files that can be compiled from your source code. -#+END_QUOTE - -** Create a PR -Create a Github pull request before your demo. Once the PR is created, you can -always push additional commits to your forked repo before the PR is merged. The -changes will automatically appear within the PR. - -1. Click the =New pull request= buttom in your repo. - [[./images/pr_button.jpg]] -2. Choose the branch with your student ID as the base branch. - [[./images/pr_base_selection.jpg]] -3. Type a title and some information about the PR. - [[./images/pr_desc.jpg]] - -Here is a [[https://github.com/oscapstone/osc2023/pull/1][PR example]]. - -* Happy Coding ~ -As long as you meet the above requirements and the PR can be merged without -conflicts, we do not care about what the forked repo look like. You can rename -your branch, change the default branch, or do whatever you want. diff --git a/git-usage.org b/git-usage.org deleted file mode 100644 index 817c4bb6c..000000000 --- a/git-usage.org +++ /dev/null @@ -1,72 +0,0 @@ -#+TITLE: Appendix -#+OPTIONS: toc: nil - -** How to add a branch that is in the upstream repo but not in your forked repo? - -1. Add osc2023 as the upstream - #+BEGIN_SRC shell - git remote add -t upstream https://github.com/oscapstone/osc2023.git - git fetch upstream - #+END_SRC - -2. Checkout your branch from the upstream - #+BEGIN_SRC shell - git checkout -b upstream/ - #+END_SRC - -3. Push the branch to your forked repo - #+BEGIN_SRC shell - git push -u origin - #+END_SRC - -** How to remove a file from the git history? - -*Warning:* If you not no fully understand what are you doing, please backup the -repo. TAs are not responsible for any mistake in this section or any damage -produced by your git operations. If you need to modify the history that has been -merged into the upstream repo, please contact with TA. - -*** case 1: the file is added in the latest commit -Just modify the latest commit -#+BEGIN_SRC shell - git rm --cached - git commit --amend -C HEAD -#+END_SRC -What if you have pushed to Github? Force push again. -#+BEGIN_SRC shell - git push -f origin -#+END_SRC - -*** case 2: the file is added in a old history. - -I suggest that you use =git rebase= to modify the history. -First, use =git log= to find the commit you added the file. -Suppose the commit id is =7a45f90=. Use the commit before =7a45f90= as the -newbase. - -#+BEGIN_SRC shell - git rebase -i 7a45f90^ -#+END_SRC - -This command pops up the editor. Modify =pick 7a45f90= to =edit 7a45f90=, then -save and close the editor. -#+BEGIN_SRC shell - git rm --cached - git commit --amend -#+END_SRC - -Repeatedly use the following command until the rebase procedure finished. - -#+BEGIN_SRC shell - git rebase --continue - # if there is conflict - git rm -#+END_SRC - -You might need to force push to the github repo. - -*Warning:* force push is not revertable. - -#+BEGIN_SRC shell - git push -f origin -#+END_SRC diff --git a/images/clone_url.jpg b/images/clone_url.jpg deleted file mode 100644 index 730548110..000000000 Binary files a/images/clone_url.jpg and /dev/null differ diff --git a/images/create_fork.jpg b/images/create_fork.jpg deleted file mode 100644 index 19c1a741c..000000000 Binary files a/images/create_fork.jpg and /dev/null differ diff --git a/images/fork_button.jpg b/images/fork_button.jpg deleted file mode 100644 index 1431cd748..000000000 Binary files a/images/fork_button.jpg and /dev/null differ diff --git a/images/forked_repo.jpg b/images/forked_repo.jpg deleted file mode 100644 index 6ac428e5f..000000000 Binary files a/images/forked_repo.jpg and /dev/null differ diff --git a/images/pr_base_selection.jpg b/images/pr_base_selection.jpg deleted file mode 100644 index 455ed90b7..000000000 Binary files a/images/pr_base_selection.jpg and /dev/null differ diff --git a/images/pr_button.jpg b/images/pr_button.jpg deleted file mode 100644 index 988130c62..000000000 Binary files a/images/pr_button.jpg and /dev/null differ diff --git a/images/pr_desc.jpg b/images/pr_desc.jpg deleted file mode 100644 index f0bdf4ccc..000000000 Binary files a/images/pr_desc.jpg and /dev/null differ diff --git a/lab1/build/boot_s.d b/lab1/build/boot_s.d new file mode 100644 index 000000000..718ca3b14 --- /dev/null +++ b/lab1/build/boot_s.d @@ -0,0 +1 @@ +build/boot_s.o: src/boot.S diff --git a/lab1/build/boot_s.o b/lab1/build/boot_s.o new file mode 100644 index 000000000..f62c2919c Binary files /dev/null and b/lab1/build/boot_s.o differ diff --git a/lab1/build/kernel8.elf b/lab1/build/kernel8.elf new file mode 100755 index 000000000..ca50e5109 Binary files /dev/null and b/lab1/build/kernel8.elf differ diff --git a/lab1/build/main_c.d b/lab1/build/main_c.d new file mode 100644 index 000000000..1df972aaf --- /dev/null +++ b/lab1/build/main_c.d @@ -0,0 +1 @@ +build/main_c.o: src/main.c include/uart1.h include/shell.h diff --git a/lab1/build/main_c.o b/lab1/build/main_c.o new file mode 100644 index 000000000..7949f27e6 Binary files /dev/null and b/lab1/build/main_c.o differ diff --git a/lab1/build/mbox_c.d b/lab1/build/mbox_c.d new file mode 100644 index 000000000..3a4b65349 --- /dev/null +++ b/lab1/build/mbox_c.d @@ -0,0 +1,2 @@ +build/mbox_c.o: src/mbox.c include/bcm2837/rpi_mbox.h \ + include/bcm2837/rpi_base.h include/mbox.h diff --git a/lab1/build/mbox_c.o b/lab1/build/mbox_c.o new file mode 100644 index 000000000..007d6d394 Binary files /dev/null and b/lab1/build/mbox_c.o differ diff --git a/lab1/build/shell_c.d b/lab1/build/shell_c.d new file mode 100644 index 000000000..a21cd52d8 --- /dev/null +++ b/lab1/build/shell_c.d @@ -0,0 +1,2 @@ +build/shell_c.o: src/shell.c include/shell.h include/uart1.h \ + include/mbox.h include/power.h diff --git a/lab1/build/shell_c.o b/lab1/build/shell_c.o new file mode 100644 index 000000000..0b9c7910c Binary files /dev/null and b/lab1/build/shell_c.o differ diff --git a/lab1/build/uart1_c.d b/lab1/build/uart1_c.d new file mode 100644 index 000000000..4b20a8d64 --- /dev/null +++ b/lab1/build/uart1_c.d @@ -0,0 +1,2 @@ +build/uart1_c.o: src/uart1.c include/bcm2837/rpi_gpio.h \ + include/bcm2837/rpi_base.h include/bcm2837/rpi_uart1.h include/uart1.h diff --git a/lab1/build/uart1_c.o b/lab1/build/uart1_c.o new file mode 100644 index 000000000..09bba459d Binary files /dev/null and b/lab1/build/uart1_c.o differ diff --git a/lab1/debug.gdb b/lab1/debug.gdb new file mode 100644 index 000000000..800fdf695 --- /dev/null +++ b/lab1/debug.gdb @@ -0,0 +1,2 @@ +file build/kernel8.elf +target remote :1234 diff --git a/lab1/include/bcm2837/rpi_base.h b/lab1/include/bcm2837/rpi_base.h new file mode 100644 index 000000000..e3259e8de --- /dev/null +++ b/lab1/include/bcm2837/rpi_base.h @@ -0,0 +1,6 @@ +#ifndef _RPI_BASE_H_ +#define _RPI_BASE_H_ + +#define PERIPHERAL_BASE 0x3F000000 + +#endif /*_RPI_BASE_H_ */ diff --git a/lab1/include/bcm2837/rpi_gpio.h b/lab1/include/bcm2837/rpi_gpio.h new file mode 100644 index 000000000..e5133708a --- /dev/null +++ b/lab1/include/bcm2837/rpi_gpio.h @@ -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_*/ diff --git a/lab1/include/bcm2837/rpi_mbox.h b/lab1/include/bcm2837/rpi_mbox.h new file mode 100644 index 000000000..ba1001472 --- /dev/null +++ b/lab1/include/bcm2837/rpi_mbox.h @@ -0,0 +1,17 @@ +#ifndef _RPI_MBOX_H_ +#define _RPI_MBOX_H_ + +#include "bcm2837/rpi_base.h" + +#define MBOX_BASE (PERIPHERAL_BASE+0x0000B880) + +// The register access to a mailbox +// https://jsandler18.github.io/extra/mailbox.html +#define MBOX_READ ((volatile unsigned int*)(MBOX_BASE+0x00)) +#define MBOX_POLL ((volatile unsigned int*)(MBOX_BASE+0x10)) +#define MBOX_SENDER ((volatile unsigned int*)(MBOX_BASE+0x14)) +#define MBOX_STATUS ((volatile unsigned int*)(MBOX_BASE+0x18)) +#define MBOX_CONFIG ((volatile unsigned int*)(MBOX_BASE+0x1C)) +#define MBOX_WRITE ((volatile unsigned int*)(MBOX_BASE+0x20)) + +#endif /*_RPI_MBOX_H_ */ diff --git a/lab1/include/bcm2837/rpi_uart1.h b/lab1/include/bcm2837/rpi_uart1.h new file mode 100644 index 000000000..959130656 --- /dev/null +++ b/lab1/include/bcm2837/rpi_uart1.h @@ -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_ */ diff --git a/lab1/include/mbox.h b/lab1/include/mbox.h new file mode 100644 index 000000000..78d2cb7f3 --- /dev/null +++ b/lab1/include/mbox.h @@ -0,0 +1,63 @@ +#ifndef _MBOX_H_ +#define _MBOX_H_ + +extern volatile unsigned int pt[64]; + +// Mailbox Register MMIO +// https://jsandler18.github.io/extra/mailbox.html +// include/bcm2837/rpi_mbox.h + +// Mailbox Channels +// https://github.com/raspberrypi/firmware/wiki/Mailboxes +typedef enum { + MBOX_POWER_MANAGEMENT = 0, + MBOX_FRAMEBUFFER, + MBOX_VIRTUAL_UART, + MBOX_VCHIQ, + MBOX_LEDS, + MBOX_BUTTONS, + MBOX_TOUCHSCREEN, + MBOX_UNUSED, + MBOX_TAGS_ARM_TO_VC, + MBOX_TAGS_VC_TO_ARM, +} mbox_channel_type; + +// Status Code from Broadcom Videocode Driver +// brcm_usrlib/dag/vmcsx/vcinclude/bcm2708_chip/arm_control.h +enum mbox_status_reg_bits { + BCM_ARM_VC_MS_FULL = 0x80000000, + BCM_ARM_VC_MS_EMPTY = 0x40000000, + BCM_ARM_VC_MS_LEVEL = 0x400000FF, +}; + +enum mbox_buffer_status_code { + MBOX_REQUEST_PROCESS = 0x00000000, + MBOX_REQUEST_SUCCEED = 0x80000000, + MBOX_REQUEST_FAILED = 0x80000001, +}; + +// Tag +// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface +// Included partition only +typedef enum { + /* Videocore */ + MBOX_TAG_GET_FIRMWARE_VERSION = 0x1, + + /* Hardware */ + MBOX_TAG_GET_BOARD_MODEL = 0x10001, + MBOX_TAG_GET_BOARD_REVISION, + MBOX_TAG_GET_BOARD_MAC_ADDRESS, + MBOX_TAG_GET_BOARD_SERIAL, + MBOX_TAG_GET_ARM_MEMORY, + MBOX_TAG_GET_VC_MEMORY, + MBOX_TAG_GET_CLOCKS, + +} mbox_tag_type; + + +#define MBOX_TAG_REQUEST_CODE 0x00000000 +#define MBOX_TAG_LAST_BYTE 0x00000000 + +int mbox_call(mbox_channel_type, unsigned int); + +#endif /*_MBOX_H_*/ diff --git a/lab1/include/power.h b/lab1/include/power.h new file mode 100644 index 000000000..baf990974 --- /dev/null +++ b/lab1/include/power.h @@ -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_*/ diff --git a/lab1/include/shell.h b/lab1/include/shell.h new file mode 100644 index 000000000..1a0df6547 --- /dev/null +++ b/lab1/include/shell.h @@ -0,0 +1,25 @@ +#ifndef _SHELL_H_ +#define _SHELL_H_ + +#define CLI_MAX_CMD 4 +#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; + +int cli_cmd_strcmp(const char*, const char*); +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_hello(); +void do_cmd_info(); +void do_cmd_reboot(); + +#endif /* _SHELL_H_ */ diff --git a/lab1/include/uart1.h b/lab1/include/uart1.h new file mode 100644 index 000000000..05c1cbc36 --- /dev/null +++ b/lab1/include/uart1.h @@ -0,0 +1,10 @@ +#ifndef _UART1_H_ +#define _UART1_H_ + +void uart_init(); +char uart_recv(); +void uart_send(unsigned int c); +void uart_puts(char* str); +void uart_2hex(unsigned int d); + +#endif /*_UART1_H_*/ diff --git a/lab1/kernel8.img b/lab1/kernel8.img new file mode 100755 index 000000000..cff0a113d Binary files /dev/null and b/lab1/kernel8.img differ diff --git a/lab1/makefile b/lab1/makefile new file mode 100644 index 000000000..1b1fe813e --- /dev/null +++ b/lab1/makefile @@ -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 $@ + +kernel8.img: $(SRC_DIR)/link.ld $(OBJ_FILES) + $(ARMGNU)-ld -T $(SRC_DIR)/link.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES) + $(ARMGNU)-objcopy $(BUILD_DIR)/kernel8.elf -O binary kernel8.img + + +all: kernel8.img + +clean: + rm -rf $(BUILD_DIR) *.img + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -display none -serial null -serial stdio + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -display none -S -s + diff --git a/lab1/src/boot.S b/lab1/src/boot.S new file mode 100644 index 000000000..9abdcd801 --- /dev/null +++ b/lab1/src/boot.S @@ -0,0 +1,20 @@ +.section ".text.boot" + +.global _start + +_start: + ldr x1, =_start + mov sp, x1 + ldr x1, =__bss_start + ldr w2, =__bss_size +clear_bss: + cbz w2, run_main + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, clear_bss + +run_main: + bl main +proc_hang: + wfe + b proc_hang diff --git a/lab1/src/link.ld b/lab1/src/link.ld new file mode 100644 index 000000000..877e61169 --- /dev/null +++ b/lab1/src/link.ld @@ -0,0 +1,15 @@ +SECTIONS +{ + . = 0x80000; + .text : { *(.text.boot) *(.text) } + .rodata : { *(.rodata) } + .data : { *(.data) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss) + __bss_end = .; + } +} +# 64bit +__bss_size = (__bss_end - __bss_start) >> 3; diff --git a/lab1/src/main.c b/lab1/src/main.c new file mode 100644 index 000000000..f9996bfe4 --- /dev/null +++ b/lab1/src/main.c @@ -0,0 +1,16 @@ +#include "uart1.h" +#include "shell.h" + +void main(){ + char input_buffer[CMD_MAX_LEN]; + + uart_init(); + cli_print_banner(); + + while(1){ + cli_cmd_clear(input_buffer, CMD_MAX_LEN); + uart_puts("# "); + cli_cmd_read(input_buffer); + cli_cmd_exec(input_buffer); + } +} diff --git a/lab1/src/mbox.c b/lab1/src/mbox.c new file mode 100644 index 000000000..e59dee6ee --- /dev/null +++ b/lab1/src/mbox.c @@ -0,0 +1,23 @@ +#include "bcm2837/rpi_mbox.h" +#include "mbox.h" + +/* Aligned to 16-byte boundary while we have 28-bits for VC */ +volatile unsigned int __attribute__((aligned(16))) pt[64]; + +int mbox_call( mbox_channel_type channel, unsigned int value ) +{ + // Add channel to lower 4 bit + value &= ~(0xF); + value |= channel; + while ( (*MBOX_STATUS & BCM_ARM_VC_MS_FULL) != 0 ) {} + // Write to Register + *MBOX_WRITE = value; + while(1) { + while ( *MBOX_STATUS & BCM_ARM_VC_MS_EMPTY ) {} + // Read from Register + if (value == *MBOX_READ) + return pt[1] == MBOX_REQUEST_SUCCEED; + } + return 0; +} + diff --git a/lab1/src/shell.c b/lab1/src/shell.c new file mode 100644 index 000000000..55be5f683 --- /dev/null +++ b/lab1/src/shell.c @@ -0,0 +1,142 @@ +#include "shell.h" +#include "uart1.h" +#include "mbox.h" +#include "power.h" + +struct CLI_CMDS cmd_list[CLI_MAX_CMD]= +{ + {.command="hello", .help="print Hello World!"}, + {.command="help", .help="print all available commands"}, + {.command="info", .help="get device information via mailbox"}, + {.command="reboot", .help="reboot the device"} +}; + +int cli_cmd_strcmp(const char* p1, const char* p2) +{ + const unsigned char *s1 = (const unsigned char*) p1; + const unsigned char *s2 = (const unsigned char*) p2; + unsigned char c1, c2; + + do { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if ( c1 == '\0' ) return c1 - c2; + } while ( c1 == c2 ); + return c1 - c2; +} + +void cli_cmd_clear(char* buffer, int length) +{ + for(int i=0; i= CMD_MAX_LEN ) break; + + c = uart_recv(); + if ( c == '\n') + { + uart_puts("\r\n"); + break; + } + if ( c > 16 && c < 32 ) continue; + if ( c > 127 ) continue; + buffer[idx++] = c; + uart_send(c); + } +} + +void cli_cmd_exec(char* buffer) +{ + if (cli_cmd_strcmp(buffer, "hello") == 0) { + do_cmd_hello(); + } else if (cli_cmd_strcmp(buffer, "help") == 0) { + do_cmd_help(); + } else if (cli_cmd_strcmp(buffer, "info") == 0) { + do_cmd_info(); + } else if (cli_cmd_strcmp(buffer, "reboot") == 0) { + do_cmd_reboot(); + } else if (*buffer){ + uart_puts(buffer); + uart_puts(": command not found\r\n"); + } +} + +void cli_print_banner() +{ + uart_puts("=======================================\r\n"); + uart_puts(" Welcome to NYCU-OSC 2023 Lab1 Shell \r\n"); + uart_puts("=======================================\r\n"); +} + +void do_cmd_help() +{ + for(int i = 0; i < CLI_MAX_CMD; i++) + { + uart_puts(cmd_list[i].command); + uart_puts("\t\t: "); + uart_puts(cmd_list[i].help); + uart_puts("\r\n"); + } +} + +void do_cmd_hello() +{ + uart_puts("Hello World!\r\n"); +} + +void do_cmd_info() +{ + // print hw revision + pt[0] = 8 * 4; + pt[1] = MBOX_REQUEST_PROCESS; + pt[2] = MBOX_TAG_GET_BOARD_REVISION; + pt[3] = 4; + pt[4] = MBOX_TAG_REQUEST_CODE; + pt[5] = 0; + pt[6] = 0; + pt[7] = MBOX_TAG_LAST_BYTE; + + if (mbox_call(MBOX_TAGS_ARM_TO_VC, (unsigned int)((unsigned long)&pt)) ) { + uart_puts("Hardware Revision\t: "); + uart_2hex(pt[6]); + uart_2hex(pt[5]); + uart_puts("\r\n"); + } + // print arm memory + pt[0] = 8 * 4; + pt[1] = MBOX_REQUEST_PROCESS; + pt[2] = MBOX_TAG_GET_ARM_MEMORY; + pt[3] = 8; + pt[4] = MBOX_TAG_REQUEST_CODE; + pt[5] = 0; + pt[6] = 0; + pt[7] = MBOX_TAG_LAST_BYTE; + + if (mbox_call(MBOX_TAGS_ARM_TO_VC, (unsigned int)((unsigned long)&pt)) ) { + uart_puts("ARM Memory Base Address\t: "); + uart_2hex(pt[5]); + uart_puts("\r\n"); + uart_puts("ARM Memory Size\t\t: "); + uart_2hex(pt[6]); + uart_puts("\r\n"); + } +} + +void do_cmd_reboot() +{ + uart_puts("Reboot in 5 seconds ...\r\n\r\n"); + volatile unsigned int* rst_addr = (unsigned int*)PM_RSTC; + *rst_addr = PM_PASSWORD | 0x20; + volatile unsigned int* wdg_addr = (unsigned int*)PM_WDOG; + *wdg_addr = PM_PASSWORD | 5; +} + diff --git a/lab1/src/uart1.c b/lab1/src/uart1.c new file mode 100644 index 000000000..75f51acc1 --- /dev/null +++ b/lab1/src/uart1.c @@ -0,0 +1,66 @@ +#include "bcm2837/rpi_gpio.h" +#include "bcm2837/rpi_uart1.h" +#include "uart1.h" + +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLES |= 1; // enable UART1 + *AUX_MU_CNTL_REG = 0; // disable TX/RX + + /* configure UART */ + *AUX_MU_IER_REG = 0; // disable interrupt + *AUX_MU_LCR_REG = 3; // 8 bit data size + *AUX_MU_MCR_REG = 0; // disable flow control + *AUX_MU_BAUD_REG = 270; // 115200 baud rate + *AUX_MU_IIR_REG = 6; // disable FIFO + + /* map UART1 to GPIO pins */ + r = *GPFSEL1; + r &= ~(7<<12); // clean gpio14 + r |= 2<<12; // set gpio14 to alt5 + r &= ~(7<<15); // clean gpio15 + r |= 2<<15; // set gpio15 to alt5 + *GPFSEL1 = r; + + /* enable pin 14, 15 - ref: Page 101 */ + *GPPUD = 0; + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; + + *AUX_MU_CNTL_REG = 3; // enable TX/RX +} + +char uart_recv() { + char r; + while(!(*AUX_MU_LSR_REG & 0x01)){}; + r = (char)(*AUX_MU_IO_REG); + return r=='\r'?'\n':r; +} + +void uart_send(unsigned int c) { + while(!(*AUX_MU_LSR_REG & 0x20)){}; + *AUX_MU_IO_REG = c; +} + +void uart_puts(char *str) { + while(*str) { + if(*str=='\n') + uart_send('\r'); + uart_send(*str++); + } +} + +void uart_2hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + n=(d>>c)&0xF; + n+=n>9?0x37:0x30; + uart_send(n); + } +}