hw3 for me2150
This commit is contained in:
parent
4a682e604a
commit
2980d41cb4
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
# If you would like to choose a different path to the SDK, you can pass it as an
|
# If you would like to choose a different path to the SDK, you can pass it as an
|
||||||
# argument.
|
# argument.
|
||||||
ifndef MICROKIT_SDK
|
ifndef MICROKIT_SDK
|
||||||
MICROKIT_SDK := ../microkit-sdk-1.4.0
|
MICROKIT_SDK := ../microkit-sdk-1.4.1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# In case the default compiler triple doesn't work for you or your package manager
|
# In case the default compiler triple doesn't work for you or your package manager
|
||||||
BIN
ME_2150/microkit_tutorial/microkit_tutorial/solutions/build/client.elf
Executable file
BIN
ME_2150/microkit_tutorial/microkit_tutorial/solutions/build/client.elf
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
ME_2150/microkit_tutorial/microkit_tutorial/solutions/build/serial_server.elf
Executable file
BIN
ME_2150/microkit_tutorial/microkit_tutorial/solutions/build/serial_server.elf
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
ME_2150/microkit_tutorial/microkit_tutorial/solutions/build/wordle_server.elf
Executable file
BIN
ME_2150/microkit_tutorial/microkit_tutorial/solutions/build/wordle_server.elf
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
ME_2150/microkit_tutorial/microkit_tutorial/tutorial/build/smc.o
Normal file
BIN
ME_2150/microkit_tutorial/microkit_tutorial/tutorial/build/smc.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
ME_2150/microkit_tutorial/microkit_tutorial/tutorial/build/vmm.elf
Executable file
BIN
ME_2150/microkit_tutorial/microkit_tutorial/tutorial/build/vmm.elf
Executable file
Binary file not shown.
BIN
ME_2150/microkit_tutorial/microkit_tutorial/tutorial/build/vmm.o
Normal file
BIN
ME_2150/microkit_tutorial/microkit_tutorial/tutorial/build/vmm.o
Normal file
Binary file not shown.
@ -4,13 +4,14 @@
|
|||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "wordle.h"
|
#include "wordle.h"
|
||||||
|
|
||||||
|
#define SERIAL_CHANNEL 1
|
||||||
|
#define WORDLE_CHANNEL 2
|
||||||
|
|
||||||
uintptr_t serial_to_client_vaddr;
|
uintptr_t serial_to_client_vaddr;
|
||||||
uintptr_t client_to_serial_vaddr;
|
uintptr_t client_to_serial_vaddr;
|
||||||
|
|
||||||
#define MOVE_CURSOR_UP "\033[5A"
|
#define MOVE_CURSOR_UP "\033[5A"
|
||||||
#define CLEAR_TERMINAL_BELOW_CURSOR "\033[0J"
|
#define CLEAR_TERMINAL_BELOW_CURSOR "\033[0J"
|
||||||
#define SERIAL_SERVER_CHANNEL_ID 1
|
|
||||||
#define WORDLE_CHANNEL 2
|
|
||||||
|
|
||||||
#define INVALID_CHAR (-1)
|
#define INVALID_CHAR (-1)
|
||||||
|
|
||||||
@ -28,16 +29,14 @@ static int curr_letter = 0;
|
|||||||
|
|
||||||
void wordle_server_send() {
|
void wordle_server_send() {
|
||||||
// Implement this function to send the word over PPC
|
// Implement this function to send the word over PPC
|
||||||
|
for (int i = 0; i < WORD_LENGTH; i++) {
|
||||||
|
microkit_mr_set(i, table[curr_row][i].ch);
|
||||||
|
}
|
||||||
|
microkit_ppcall(WORDLE_CHANNEL, microkit_msginfo_new(0, WORD_LENGTH));
|
||||||
// After doing the PPC, the Wordle server should have updated
|
// After doing the PPC, the Wordle server should have updated
|
||||||
// the message-registers containing the state of each character.
|
// the message-registers containing the state of each character.
|
||||||
// Look at the message registers and update the `table` accordingly.
|
// Look at the message registers and update the `table` accordingly.
|
||||||
for (int i = 0; i < WORD_LENGTH; i++) {
|
for (int i = 0; i < WORD_LENGTH; i++) {
|
||||||
microkit_mr_set(i, table[curr_row][i].ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
microkit_ppcall(WORDLE_CHANNEL, microkit_msginfo_new(0, WORD_LENGTH));
|
|
||||||
|
|
||||||
for (int i = 0; 1 < WORD_LENGTH; i++) {
|
|
||||||
table[curr_row][i].state = microkit_mr_get(i);
|
table[curr_row][i].state = microkit_mr_get(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +49,7 @@ void serial_send(char *str) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
((char *)client_to_serial_vaddr)[i] = '\0';
|
((char *)client_to_serial_vaddr)[i] = '\0';
|
||||||
microkit_notify(SERIAL_SERVER_CHANNEL_ID);
|
microkit_notify(SERIAL_CHANNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function prints a CLI Wordle using pretty colours for what characters
|
// This function prints a CLI Wordle using pretty colours for what characters
|
||||||
@ -144,11 +143,11 @@ void init(void) {
|
|||||||
|
|
||||||
void notified(microkit_channel channel) {
|
void notified(microkit_channel channel) {
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
case SERIAL_SERVER_CHANNEL_ID:{
|
case SERIAL_CHANNEL: {
|
||||||
char ch = ((char *)serial_to_client_vaddr)[0];
|
char ch = ((char *)serial_to_client_vaddr)[0];
|
||||||
add_char_to_table(ch);
|
add_char_to_table(ch);
|
||||||
print_table(true);
|
print_table(true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,154 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <microkit.h>
|
||||||
|
#include "printf.h"
|
||||||
|
#include "wordle.h"
|
||||||
|
|
||||||
|
uintptr_t serial_to_client_vaddr;
|
||||||
|
uintptr_t client_to_serial_vaddr;
|
||||||
|
|
||||||
|
#define MOVE_CURSOR_UP "\033[6A"
|
||||||
|
#define CLEAR_TERMINAL_BELOW_CURSOR "\033[0J"
|
||||||
|
#define SERIAL_SERVER_CHANNEL_ID 1
|
||||||
|
#define WORDLE_CHANNEL 2
|
||||||
|
|
||||||
|
#define INVALID_CHAR (-1)
|
||||||
|
|
||||||
|
struct wordle_char {
|
||||||
|
int ch;
|
||||||
|
enum character_state state;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store game state
|
||||||
|
static struct wordle_char table[NUM_TRIES][WORD_LENGTH];
|
||||||
|
// Use these global variables to keep track of the character index that the
|
||||||
|
// player is currently trying to input.
|
||||||
|
static int curr_row = 0;
|
||||||
|
static int curr_letter = 0;
|
||||||
|
|
||||||
|
void wordle_server_send() {
|
||||||
|
// Implement this function to send the word over PPC
|
||||||
|
// After doing the PPC, the Wordle server should have updated
|
||||||
|
// the message-registers containing the state of each character.
|
||||||
|
// Look at the message registers and update the `table` accordingly.
|
||||||
|
for (int i = 0; i < WORD_LENGTH; i++) {
|
||||||
|
microkit_mr_set(i, table[curr_row][i].ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
microkit_ppcall(WORDLE_CHANNEL, microkit_msginfo_new(0, WORD_LENGTH));
|
||||||
|
|
||||||
|
for (int i = 0; 1 < WORD_LENGTH; i++) {
|
||||||
|
table[curr_row][i].state = microkit_mr_get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_send(char *str) {
|
||||||
|
// Implement this function to get the serial server to print the string.
|
||||||
|
int i = 0;
|
||||||
|
while (str[i] != '\0') {
|
||||||
|
((char *)client_to_serial_vaddr)[i] = str[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
((char *)client_to_serial_vaddr)[i] = '\0';
|
||||||
|
microkit_notify(SERIAL_SERVER_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function prints a CLI Wordle using pretty colours for what characters
|
||||||
|
// are correct, or correct but in the wrong place etc.
|
||||||
|
void print_table(bool clear_terminal) {
|
||||||
|
if (clear_terminal) {
|
||||||
|
// Assuming we have already printed a Wordle table, this will clear the
|
||||||
|
// table we have already printed and then print the updated one. This
|
||||||
|
// is done by moving the cursor up 5 lines and then clearing everything
|
||||||
|
// below it.
|
||||||
|
serial_send(MOVE_CURSOR_UP);
|
||||||
|
serial_send(CLEAR_TERMINAL_BELOW_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int row = 0; row < NUM_TRIES; row++) {
|
||||||
|
for (int letter = 0; letter < WORD_LENGTH; letter++) {
|
||||||
|
serial_send("[");
|
||||||
|
enum character_state state = table[row][letter].state;
|
||||||
|
int ch = table[row][letter].ch;
|
||||||
|
if (ch != INVALID_CHAR) {
|
||||||
|
switch (state) {
|
||||||
|
case INCORRECT: break;
|
||||||
|
case CORRECT_PLACEMENT: serial_send("\x1B[32m"); break;
|
||||||
|
case INCORRECT_PLACEMENT: serial_send("\x1B[33m"); break;
|
||||||
|
default:
|
||||||
|
// Print out error messages/debug info via debug output
|
||||||
|
microkit_dbg_puts("CLIENT|ERROR: unexpected character state\n");
|
||||||
|
}
|
||||||
|
char ch_str[] = { ch, '\0' };
|
||||||
|
serial_send(ch_str);
|
||||||
|
// Reset colour
|
||||||
|
serial_send("\x1B[0m");
|
||||||
|
} else {
|
||||||
|
serial_send(" ");
|
||||||
|
}
|
||||||
|
serial_send("] ");
|
||||||
|
}
|
||||||
|
serial_send("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_table() {
|
||||||
|
for (int row = 0; row < NUM_TRIES; row++) {
|
||||||
|
for (int letter = 0; letter < WORD_LENGTH; letter++) {
|
||||||
|
table[row][letter].ch = INVALID_CHAR;
|
||||||
|
table[row][letter].state = INCORRECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool char_is_backspace(int ch) {
|
||||||
|
return (ch == 0x7f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool char_is_valid(int ch) {
|
||||||
|
// Only allow alphabetical letters and do not accept a character if the
|
||||||
|
// current word has already been filled.
|
||||||
|
return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) && curr_letter != WORD_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_char_to_table(char c) {
|
||||||
|
if (char_is_backspace(c)) {
|
||||||
|
if (curr_letter > 0) {
|
||||||
|
curr_letter--;
|
||||||
|
table[curr_row][curr_letter].ch = INVALID_CHAR;
|
||||||
|
}
|
||||||
|
} else if (c != '\r' && c != ' ' && curr_letter != WORD_LENGTH) {
|
||||||
|
table[curr_row][curr_letter].ch = c;
|
||||||
|
curr_letter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user has finished inputting a word, we want to send the
|
||||||
|
// word to the server and move the cursor to the next row.
|
||||||
|
if (c == '\r' && curr_letter == WORD_LENGTH) {
|
||||||
|
wordle_server_send();
|
||||||
|
curr_row += 1;
|
||||||
|
curr_letter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(void) {
|
||||||
|
microkit_dbg_puts("CLIENT: starting\n");
|
||||||
|
serial_send("Welcome to the Wordle client!\n");
|
||||||
|
|
||||||
|
init_table();
|
||||||
|
// Don't want to clear the terminal yet since this is the first time
|
||||||
|
// we are printing it (we want to clear just the Wordle table, not
|
||||||
|
// everything on the terminal).
|
||||||
|
print_table(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void notified(microkit_channel channel) {
|
||||||
|
switch (channel) {
|
||||||
|
case SERIAL_SERVER_CHANNEL_ID:{
|
||||||
|
char ch = ((char *)serial_to_client_vaddr)[0];
|
||||||
|
add_char_to_table(ch);
|
||||||
|
print_table(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -31,6 +31,54 @@
|
|||||||
<end pd="client" id="2" />
|
<end pd="client" id="2" />
|
||||||
<end pd="wordle_server" id="1" />
|
<end pd="wordle_server" id="1" />
|
||||||
</channel>
|
</channel>
|
||||||
|
<!--
|
||||||
|
This is what the virtual machine will use as its "RAM".
|
||||||
|
Remember it does not know it is a VM and so will expect a
|
||||||
|
block of contigious memory as RAM.
|
||||||
|
-->
|
||||||
|
<memory_region name="guest_ram" size="0x10000000" page_size="0x200_000"
|
||||||
|
phys_addr="0x40000000" />
|
||||||
|
<!-- Create a memory region for the ethernet device -->
|
||||||
|
<memory_region name="ethernet" size="0x1000" phys_addr="0xa003000" />
|
||||||
|
<!--
|
||||||
|
Create a memory region for the GIC vCPU, this is part of
|
||||||
|
ARM's hardware virtualisation, I will not go into detail here,
|
||||||
|
but it is necessary for the virtual machine to function.
|
||||||
|
-->
|
||||||
|
<memory_region name="gic_vcpu" size="0x1000" phys_addr="0x8040000" />
|
||||||
|
|
||||||
|
<!-- Create a VMM protection domain -->
|
||||||
|
<protection_domain name="vmm" priority="101">
|
||||||
|
<program_image path="vmm.elf" />
|
||||||
|
<!--
|
||||||
|
Map in the virtual machine's RAM region as the VMM needs
|
||||||
|
access to it as well for starting and setting up the VM.
|
||||||
|
-->
|
||||||
|
<map mr="guest_ram" vaddr="0x40000000" perms="rw"
|
||||||
|
setvar_vaddr="guest_ram_vaddr" />
|
||||||
|
<!--
|
||||||
|
Create the virtual machine, the `id` is used for the
|
||||||
|
VMM to refer to the VM. Similar to channels and IRQs
|
||||||
|
-->
|
||||||
|
<virtual_machine name="linux" priority="100">
|
||||||
|
<vcpu id="0" />
|
||||||
|
<map mr="guest_ram" vaddr="0x40000000" perms="rwx" />
|
||||||
|
<map mr="ethernet" vaddr="0xa003000" perms="rw" cached="false" />
|
||||||
|
<map mr="uart" vaddr="0x9000000" perms="rw" cached="false" />
|
||||||
|
<map mr="gic_vcpu" vaddr="0x8010000" perms="rw" cached="false" />
|
||||||
|
</virtual_machine>
|
||||||
|
<!--
|
||||||
|
We want the VMM to receive the ethernet interrupts, which it
|
||||||
|
will then deliver to the VM
|
||||||
|
-->
|
||||||
|
<irq irq="79" id="2" trigger="edge" />
|
||||||
|
</protection_domain>
|
||||||
|
|
||||||
|
<channel>
|
||||||
|
<end pd="vmm" id="1" />
|
||||||
|
<end pd="wordle_server" id="2" />
|
||||||
|
</channel>
|
||||||
|
|
||||||
|
|
||||||
</system>
|
</system>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user