mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-21 22:23:05 +00:00
Basic exceptions, irq, cache mgmt support
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
73e79c5372
commit
81aaf2ed35
17 changed files with 447 additions and 57 deletions
9
Makefile
9
Makefile
|
@ -8,8 +8,9 @@ LDFLAGS := -T m1n1.ld -EL -maarch64elf --no-undefined -X -shared -Bsymbolic \
|
|||
-z notext --no-apply-dynamic-relocs --orphan-handling=warn --strip-debug \
|
||||
-z nocopyreloc --gc-sections -pie
|
||||
|
||||
OBJECTS := adt.o bootlogo_128.o bootlogo_256.o fb.o main.o proxy.o start.o startup.o \
|
||||
string.o uart.o uartproxy.o utils.o utils_asm.o vsprintf.o
|
||||
OBJECTS := adt.o bootlogo_128.o bootlogo_256.o exception.o exception_asm.o fb.o \
|
||||
main.o memory.o proxy.o start.o startup.o string.o uart.o uartproxy.o utils.o \
|
||||
utils_asm.o vsprintf.o
|
||||
|
||||
BUILD_OBJS := $(patsubst %,build/%,$(OBJECTS))
|
||||
NAME := m1n1
|
||||
|
@ -42,14 +43,14 @@ build/%.o: src/%.c
|
|||
build/$(NAME).elf: $(BUILD_OBJS) m1n1.ld
|
||||
@echo " LD $@"
|
||||
@$(LD) $(LDFLAGS) -o $@ $(BUILD_OBJS)
|
||||
|
||||
|
||||
build/$(NAME).macho: build/$(NAME).elf
|
||||
@echo " MACHO $@"
|
||||
@$(OBJCOPY) -O binary $< $@
|
||||
|
||||
build/build_tag.h:
|
||||
@echo " TAG $@"
|
||||
@echo "#define BUILD_TAG \"$$(git describe --always --dirty)\"" > $@
|
||||
@echo "#define BUILD_TAG \"$$(git describe --always --dirty)\"" > $@
|
||||
|
||||
build/%.bin: data/%.png
|
||||
@echo " IMG $@"
|
||||
|
|
10
m1n1.ld
10
m1n1.ld
|
@ -30,7 +30,7 @@ SECTIONS {
|
|||
LONG(_cmd_end - _cmd_start); /* sizeofcmds */
|
||||
LONG(4); /* flags */
|
||||
LONG(0); /* reserved */
|
||||
|
||||
|
||||
_cmd_start = .;
|
||||
|
||||
/* unix_thread (entrypoint) */
|
||||
|
@ -41,7 +41,7 @@ SECTIONS {
|
|||
. += 32 * 8; /* useless registers */
|
||||
QUAD(_start + _va_off) /* pc */
|
||||
. += 8; /* useless registers */
|
||||
|
||||
|
||||
ASSERT(. - _cmd_start == 0x120, "Bad unix_thread structure");
|
||||
|
||||
/* segment: mach-o structures */
|
||||
|
@ -57,7 +57,7 @@ SECTIONS {
|
|||
LONG(PROT_READ); /* initprot */
|
||||
LONG(0); /* nsects */
|
||||
LONG(0); /* flags */
|
||||
|
||||
|
||||
/* segment: text */
|
||||
LONG(0x19); /* type = SEGMENT_64 */
|
||||
LONG(0x48); /* cmdsize */
|
||||
|
@ -101,7 +101,7 @@ SECTIONS {
|
|||
LONG(0); /* flags */
|
||||
|
||||
_cmd_end = .;
|
||||
|
||||
|
||||
. = ALIGN(0x4000);
|
||||
_hdr_end = .;
|
||||
} :hdr
|
||||
|
@ -171,7 +171,7 @@ SECTIONS {
|
|||
*(.data.rel.ro)
|
||||
}
|
||||
ASSERT(SIZEOF(.empty) == 0, "Unexpected sections detected!")
|
||||
|
||||
|
||||
.got.plt (NOLOAD) : {
|
||||
*(.got.plt)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ print("Loading %d bytes to 0x%x" % (len(payload), new_base))
|
|||
|
||||
iface.writemem(new_base + 0x4000, payload[0x4000:], True)
|
||||
|
||||
entry = new_base + 0x4000
|
||||
entry = new_base + 0x4800
|
||||
|
||||
print("Jumping to 0x%x" % entry)
|
||||
|
||||
|
|
|
@ -259,10 +259,17 @@ class M1N1Proxy:
|
|||
P_MEMSET16 = 0x206
|
||||
P_MEMSET8 = 0x207
|
||||
|
||||
P_DC_FLUSHRANGE = 0x300
|
||||
P_DC_INVALRANGE = 0x301
|
||||
P_DC_FLUSHALL = 0x302
|
||||
P_IC_INVALALL = 0x303
|
||||
P_IC_IALLUIS = 0x300
|
||||
P_IC_IALLU = 0x301
|
||||
P_IC_IVAU = 0x302
|
||||
P_DC_IVAC = 0x303
|
||||
P_DC_ISW = 0x304
|
||||
P_DC_CSW = 0x305
|
||||
P_DC_CISW = 0x306
|
||||
P_DC_ZVA = 0x307
|
||||
P_DC_CVAC = 0x308
|
||||
P_DC_CVAU = 0x309
|
||||
P_DC_CIVAC = 0x30a
|
||||
|
||||
def __init__(self, iface, debug=False):
|
||||
self.debug = debug
|
||||
|
@ -417,15 +424,29 @@ class M1N1Proxy:
|
|||
self.request(self.P_MEMSET16, dst, src, size)
|
||||
def memset8(self, dst, src, size):
|
||||
self.request(self.P_MEMSET8, dst, src, size)
|
||||
|
||||
def dc_flushrange(self, addr, size):
|
||||
self.request(self.P_DC_FLUSHRANGE, addr, size)
|
||||
def dc_invalrange(self, addr, size):
|
||||
self.request(self.P_DC_INVALRANGE, addr, size)
|
||||
def dc_flushall(self):
|
||||
self.request(self.P_DC_FLUSHALL)
|
||||
def ic_invalall(self):
|
||||
self.request(self.P_IC_INVALALL)
|
||||
|
||||
def ic_ialluis(self):
|
||||
self.request(self.P_IC_IALLUIS)
|
||||
def ic_iallu(self):
|
||||
self.request(self.P_IC_IALLU)
|
||||
def ic_ivau(self, addr, size):
|
||||
self.request(self.P_IC_IVAU, addr, size)
|
||||
def ic_ivac(self, addr, size):
|
||||
self.request(self.P_IC_IVAC, addr, size)
|
||||
def dc_isw(self, sw):
|
||||
self.request(self.P_DC_ISW, sw)
|
||||
def dc_csw(self, sw):
|
||||
self.request(self.P_DC_CSW, sw)
|
||||
def dc_cisw(self, sw):
|
||||
self.request(self.P_DC_CISW, sw)
|
||||
def dc_zva(self, addr, size):
|
||||
self.request(self.P_DC_ZVA, addr, size)
|
||||
def dc_cvac(self, addr, size):
|
||||
self.request(self.P_DC_CVAC, addr, size)
|
||||
def dc_cvau(self, addr, size):
|
||||
self.request(self.P_DC_CVAU, addr, size)
|
||||
def dc_civac(self, addr, size):
|
||||
self.request(self.P_DC_CIVAC, addr, size)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import serial
|
||||
|
|
84
src/exception.c
Normal file
84
src/exception.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "uart.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern char _vectors_start[0];
|
||||
|
||||
void exception_initialize(void)
|
||||
{
|
||||
printf("Initializing exceptions...\n");
|
||||
|
||||
msr(vbar_el2, _vectors_start);
|
||||
}
|
||||
|
||||
void print_regs(u64 *regs)
|
||||
{
|
||||
u64 sp = ((u64)(regs)) - (8 * 31);
|
||||
|
||||
printf("Running in EL%d\n", mrs(CurrentEL) >> 2);
|
||||
printf("Registers: (@%p)\n", regs);
|
||||
printf(" x0-x3: %016lx %016lx %016lx %016lx\n", regs[0], regs[1], regs[2],
|
||||
regs[3]);
|
||||
printf(" x4-x7: %016lx %016lx %016lx %016lx\n", regs[4], regs[5], regs[6],
|
||||
regs[7]);
|
||||
printf(" x8-x11: %016lx %016lx %016lx %016lx\n", regs[8], regs[9], regs[10],
|
||||
regs[11]);
|
||||
printf("x12-x15: %016lx %016lx %016lx %016lx\n", regs[12], regs[13],
|
||||
regs[14], regs[15]);
|
||||
printf("x16-x19: %016lx %016lx %016lx %016lx\n", regs[16], regs[17],
|
||||
regs[18], regs[19]);
|
||||
printf("x20-x23: %016lx %016lx %016lx %016lx\n", regs[20], regs[21],
|
||||
regs[22], regs[23]);
|
||||
printf("x24-x27: %016lx %016lx %016lx %016lx\n", regs[24], regs[25],
|
||||
regs[26], regs[27]);
|
||||
printf("x28-x30: %016lx %016lx %016lx\n", regs[28], regs[29], regs[30]);
|
||||
|
||||
u64 elr = mrs(elr_el2);
|
||||
|
||||
printf("PC: 0x%lx (rel: 0x%lx)\n", elr, elr - (u64)_base);
|
||||
printf("SPSEL: 0x%lx\n", mrs(spsel));
|
||||
printf("SP: 0x%lx\n", sp);
|
||||
printf("SPSR_EL2: 0x%x\n", mrs(spsr_el2));
|
||||
}
|
||||
|
||||
void exc_sync(u64 *regs)
|
||||
{
|
||||
uart_puts("Exception: SYNC");
|
||||
|
||||
print_regs(regs);
|
||||
reboot();
|
||||
}
|
||||
|
||||
void exc_irq(u64 *regs)
|
||||
{
|
||||
uart_puts("Exception: IRQ");
|
||||
|
||||
u32 reason = read32(0x23b102004);
|
||||
|
||||
printf(" type: %d num: %d\n", reason >> 16, reason & 0xffff);
|
||||
|
||||
// print_regs(regs);
|
||||
}
|
||||
|
||||
void exc_fiq(u64 *regs)
|
||||
{
|
||||
uart_puts("Exception: FIQ");
|
||||
|
||||
u32 timer_ctl = mrs(CNTP_CTL_EL0);
|
||||
|
||||
if (timer_ctl == 0x5) {
|
||||
uart_puts(" timer IRQ, masking");
|
||||
msr(CNTP_CTL_EL0, 7);
|
||||
}
|
||||
|
||||
// print_regs(regs);
|
||||
}
|
||||
|
||||
void exc_serr(u64 *regs)
|
||||
{
|
||||
printf("Exception: SError\n");
|
||||
|
||||
print_regs(regs);
|
||||
reboot();
|
||||
}
|
8
src/exception.h
Normal file
8
src/exception.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef __EXCEPTION_H__
|
||||
#define __EXCEPTION_H__
|
||||
|
||||
void exception_initialize(void);
|
||||
|
||||
#endif
|
84
src/exception_asm.S
Normal file
84
src/exception_asm.S
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* spDx-License-Identifier: MIT */
|
||||
|
||||
.globl exc_sync
|
||||
.globl exc_irq
|
||||
.globl exc_fiq
|
||||
.globl exc_serr
|
||||
.globl _vectors_start
|
||||
|
||||
.globl _v_sp0_sync
|
||||
.type _v_sp0_sync, @function
|
||||
_v_sp0_sync:
|
||||
str x30, [sp, #-16]!
|
||||
bl _exc_entry
|
||||
bl exc_sync
|
||||
|
||||
b _exc_return
|
||||
|
||||
.globl _v_sp0_irq
|
||||
.type _v_sp0_irq, @function
|
||||
_v_sp0_irq:
|
||||
str x30, [sp, #-16]!
|
||||
bl _exc_entry
|
||||
bl exc_irq
|
||||
|
||||
b _exc_return
|
||||
|
||||
.globl _v_sp0_fiq
|
||||
.type _v_sp0_fiq, @function
|
||||
_v_sp0_fiq:
|
||||
str x30, [sp, #-16]!
|
||||
bl _exc_entry
|
||||
bl exc_fiq
|
||||
|
||||
b _exc_return
|
||||
|
||||
.globl _v_sp0_serr
|
||||
.type _v_sp0_serr, @function
|
||||
_v_sp0_serr:
|
||||
str x30, [sp, #-16]!
|
||||
bl _exc_entry
|
||||
bl exc_serr
|
||||
|
||||
b _exc_return
|
||||
|
||||
.globl push_hi_regs
|
||||
.type push_hi_regs, @function
|
||||
push_hi_regs:
|
||||
|
||||
_exc_entry:
|
||||
stp x28, x29, [sp, #-16]!
|
||||
stp x26, x27, [sp, #-16]!
|
||||
stp x24, x25, [sp, #-16]!
|
||||
stp x22, x23, [sp, #-16]!
|
||||
stp x20, x21, [sp, #-16]!
|
||||
stp x18, x19, [sp, #-16]!
|
||||
stp x16, x17, [sp, #-16]!
|
||||
stp x14, x15, [sp, #-16]!
|
||||
stp x12, x13, [sp, #-16]!
|
||||
stp x10, x11, [sp, #-16]!
|
||||
stp x8, x9, [sp, #-16]!
|
||||
stp x6, x7, [sp, #-16]!
|
||||
stp x4, x5, [sp, #-16]!
|
||||
stp x2, x3, [sp, #-16]!
|
||||
stp x0, x1, [sp, #-16]!
|
||||
|
||||
mov x0, sp
|
||||
ret
|
||||
|
||||
.globl _exc_return
|
||||
.type _exc_return, @function
|
||||
_exc_return:
|
||||
ldp x0, x1, [sp], #16
|
||||
ldp x2, x3, [sp], #16
|
||||
ldp x4, x5, [sp], #16
|
||||
ldp x6, x7, [sp], #16
|
||||
ldp x8, x9, [sp], #16
|
||||
ldp x10, x11, [sp], #16
|
||||
ldp x12, x13, [sp], #16
|
||||
ldp x14, x15, [sp], #16
|
||||
|
||||
add sp, sp, #112
|
||||
|
||||
ldr x30, [sp], #16
|
||||
eret
|
15
src/main.c
15
src/main.c
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "../build/build_tag.h"
|
||||
|
||||
//#define LOGO
|
||||
// #define LOGO
|
||||
|
||||
void print_info(void)
|
||||
{
|
||||
|
@ -65,7 +65,9 @@ void m1n1_main(void)
|
|||
{
|
||||
printf("\n\nm1n1 v%s\n", BUILD_TAG);
|
||||
printf("Copyright (C) 2021 The Asahi Linux Contributors\n");
|
||||
printf("Licensed under the MIT license\n");
|
||||
printf("Licensed under the MIT license\n\n");
|
||||
|
||||
printf("Running in EL%d\n\n", mrs(CurrentEL) >> 2);
|
||||
|
||||
#ifdef LOGO
|
||||
fb_init();
|
||||
|
@ -75,15 +77,6 @@ void m1n1_main(void)
|
|||
print_info();
|
||||
disable_wdt();
|
||||
|
||||
/*
|
||||
u64 dtaddr = ((u64)cur_boot_args.devtree) - cur_boot_args.virt_base +
|
||||
cur_boot_args.phys_base;*/
|
||||
|
||||
// hexdump((void *)dtaddr, cur_boot_args.devtree_size);
|
||||
//
|
||||
// while (1)
|
||||
// uart_putbyte(uart_getbyte());
|
||||
|
||||
printf("Running proxy...\n");
|
||||
uartproxy_run();
|
||||
|
||||
|
|
24
src/memory.c
Normal file
24
src/memory.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "memory.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define CACHE_LINE_SIZE 64
|
||||
|
||||
#define CACHE_RANGE_OP(func, op) \
|
||||
void func(void *addr, size_t length) \
|
||||
{ \
|
||||
u64 p = (u64)addr; \
|
||||
u64 end = p + length; \
|
||||
while (p < end) { \
|
||||
cacheop(op, p); \
|
||||
p += CACHE_LINE_SIZE; \
|
||||
} \
|
||||
}
|
||||
|
||||
CACHE_RANGE_OP(ic_ivau_range, "ic ivau")
|
||||
CACHE_RANGE_OP(dc_ivac_range, "dc ivac")
|
||||
CACHE_RANGE_OP(dc_zva_range, "dc zva")
|
||||
CACHE_RANGE_OP(dc_cvac_range, "dc cvac")
|
||||
CACHE_RANGE_OP(dc_cvau_range, "dc cvau")
|
||||
CACHE_RANGE_OP(dc_civac_range, "dc civac")
|
15
src/memory.h
Normal file
15
src/memory.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void ic_ivau_range(void *addr, size_t length);
|
||||
void dc_ivac_range(void *addr, size_t length);
|
||||
void dc_zva_range(void *addr, size_t length);
|
||||
void dc_cvac_range(void *addr, size_t length);
|
||||
void dc_cvau_range(void *addr, size_t length);
|
||||
void dc_civac_range(void *addr, size_t length);
|
||||
|
||||
#endif
|
43
src/proxy.c
43
src/proxy.c
|
@ -1,11 +1,10 @@
|
|||
#include "proxy.h"
|
||||
#include "memory.h"
|
||||
#include "types.h"
|
||||
#include "uart.h"
|
||||
#include "utils.h"
|
||||
#include "xnuboot.h"
|
||||
|
||||
extern char _base[0];
|
||||
|
||||
int proxy_process(ProxyRequest *request, ProxyReply *reply)
|
||||
{
|
||||
callfunc *f;
|
||||
|
@ -145,13 +144,39 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply)
|
|||
request->args[2]);
|
||||
break;
|
||||
|
||||
/*
|
||||
case P_DC_FLUSHRANGE: dc_flushrange((void*)request->args[0],
|
||||
request->args[1]); break; case P_DC_INVALRANGE:
|
||||
dc_invalidaterange((void*)request->args[0], request->args[1]);
|
||||
break; case P_DC_FLUSHALL: dc_flushall(); break; case
|
||||
P_IC_INVALALL: ic_invalidateall(); break;
|
||||
*/
|
||||
case P_IC_IALLUIS:
|
||||
ic_ialluis();
|
||||
break;
|
||||
case P_IC_IALLU:
|
||||
ic_iallu();
|
||||
break;
|
||||
case P_IC_IVAU:
|
||||
ic_ivau_range((void *)request->args[0], request->args[1]);
|
||||
break;
|
||||
case P_DC_IVAC:
|
||||
dc_ivac_range((void *)request->args[0], request->args[1]);
|
||||
break;
|
||||
case P_DC_ISW:
|
||||
dc_isw((void *)request->args[0]);
|
||||
break;
|
||||
case P_DC_CSW:
|
||||
dc_csw((void *)request->args[0]);
|
||||
break;
|
||||
case P_DC_CISW:
|
||||
dc_cisw((void *)request->args[0]);
|
||||
break;
|
||||
case P_DC_ZVA:
|
||||
dc_zva_range((void *)request->args[0], request->args[1]);
|
||||
break;
|
||||
case P_DC_CVAC:
|
||||
dc_cvac_range((void *)request->args[0], request->args[1]);
|
||||
break;
|
||||
case P_DC_CVAU:
|
||||
dc_cvau_range((void *)request->args[0], request->args[1]);
|
||||
break;
|
||||
case P_DC_CIVAC:
|
||||
dc_civac_range((void *)request->args[0], request->args[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
reply->status = S_BADCMD;
|
||||
|
|
15
src/proxy.h
15
src/proxy.h
|
@ -41,10 +41,17 @@ typedef enum {
|
|||
P_MEMSET16,
|
||||
P_MEMSET8,
|
||||
|
||||
P_DC_FLUSHRANGE = 0x300, // Cache and memory ops
|
||||
P_DC_INVALRANGE,
|
||||
P_DC_FLUSHALL,
|
||||
P_IC_INVALALL,
|
||||
P_IC_IALLUIS = 0x300, // Cache and memory ops
|
||||
P_IC_IALLU,
|
||||
P_IC_IVAU,
|
||||
P_DC_IVAC,
|
||||
P_DC_ISW,
|
||||
P_DC_CSW,
|
||||
P_DC_CISW,
|
||||
P_DC_ZVA,
|
||||
P_DC_CVAC,
|
||||
P_DC_CVAU,
|
||||
P_DC_CIVAC,
|
||||
|
||||
} ProxyOp;
|
||||
|
||||
|
|
98
src/start.S
98
src/start.S
|
@ -4,11 +4,68 @@
|
|||
#define UTRSTAT 0x010
|
||||
#define UTXH 0x020
|
||||
|
||||
#define WDT_BASE 0x23d2b0000
|
||||
#define WDT_COUNT 0x10
|
||||
#define WDT_ALARM 0x14
|
||||
#define WDT_CTL 0x1c
|
||||
|
||||
.extern _start_c
|
||||
.extern _stack_bot
|
||||
.extern _v_sp0_sync
|
||||
.extern _v_sp0_irq
|
||||
.extern _v_sp0_fiq
|
||||
.extern _v_sp0_serr
|
||||
|
||||
.section .init, "ax"
|
||||
|
||||
.globl _vectors_start
|
||||
_vectors_start:
|
||||
|
||||
mov x9, '0'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, '1'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, '2'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, '3'
|
||||
b exc_unk
|
||||
.align 7
|
||||
b _v_sp0_sync
|
||||
.align 7
|
||||
b _v_sp0_irq
|
||||
.align 7
|
||||
b _v_sp0_fiq
|
||||
.align 7
|
||||
b _v_sp0_serr
|
||||
.align 7
|
||||
mov x9, 'a'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 'b'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 'c'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 'd'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 'p'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 'q'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 'r'
|
||||
b exc_unk
|
||||
.align 7
|
||||
mov x9, 's'
|
||||
b exc_unk
|
||||
.align 7
|
||||
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
|
@ -46,6 +103,33 @@ _start:
|
|||
bl _start_c
|
||||
b .
|
||||
|
||||
.globl exc_unk
|
||||
.type exc_unk, @function
|
||||
exc_unk:
|
||||
mov w0, '\r'
|
||||
bl debug_putc
|
||||
mov w0, '\n'
|
||||
bl debug_putc
|
||||
mov w0, '!'
|
||||
bl debug_putc
|
||||
mov w0, 'E'
|
||||
bl debug_putc
|
||||
mov w0, 'x'
|
||||
bl debug_putc
|
||||
mov w0, 'C'
|
||||
bl debug_putc
|
||||
mov w0, ':'
|
||||
bl debug_putc
|
||||
mov w0, w9
|
||||
bl debug_putc
|
||||
mov w0, '!'
|
||||
bl debug_putc
|
||||
mov w0, '\r'
|
||||
bl debug_putc
|
||||
mov w0, '\n'
|
||||
bl debug_putc
|
||||
b reboot
|
||||
|
||||
.globl debug_putc
|
||||
.type debug_putc, @function
|
||||
debug_putc:
|
||||
|
@ -58,4 +142,16 @@ debug_putc:
|
|||
str w0, [x1, UTXH]
|
||||
ret
|
||||
|
||||
.pool
|
||||
.globl reboot
|
||||
.type reboot, @function
|
||||
reboot:
|
||||
ldr x1, =WDT_BASE
|
||||
mov w0, #0x100000
|
||||
str w0, [x1, #WDT_ALARM]
|
||||
mov w0, #0
|
||||
str w0, [x1, #WDT_COUNT]
|
||||
mov w0, #4
|
||||
str w0, [x1, #WDT_CTL]
|
||||
b .
|
||||
|
||||
.pool
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include "exception.h"
|
||||
#include "string.h"
|
||||
#include "types.h"
|
||||
#include "uart.h"
|
||||
|
@ -79,5 +80,6 @@ void _start_c(void *boot_args, void *base)
|
|||
adt = (void *)(((u64)cur_boot_args.devtree) - cur_boot_args.virt_base +
|
||||
cur_boot_args.phys_base);
|
||||
|
||||
exception_initialize();
|
||||
m1n1_main();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void uart_init(void);
|
||||
|
||||
void uart_putbyte(u8 c);
|
||||
|
|
28
src/utils.h
28
src/utils.h
|
@ -193,6 +193,33 @@ static inline u8 mask8(u64 addr, u8 clear, u8 set)
|
|||
return data;
|
||||
}
|
||||
|
||||
#define mrs(reg) \
|
||||
({ \
|
||||
u64 val; \
|
||||
__asm__ volatile("mrs\t%0, " #reg : "=r"(val)); \
|
||||
val; \
|
||||
})
|
||||
|
||||
#define msr(reg, val) ({ __asm__ volatile("msr\t" #reg ", %0" : : "r"(val)); })
|
||||
|
||||
#define sysop(op) __asm__ volatile(op)
|
||||
|
||||
#define cacheop(op, val) ({ __asm__ volatile(op ", %0" : : "r"(val)); })
|
||||
|
||||
#define ic_ialluis() sysop("ic ialluis")
|
||||
#define ic_iallu() sysop("ic iallu")
|
||||
#define ic_iavau(p) cacheop("ic ivau", p)
|
||||
#define dc_ivac(p) cacheop("dc ivac", p)
|
||||
#define dc_isw(p) cacheop("dc isw", p)
|
||||
#define dc_csw(p) cacheop("dc csw", p)
|
||||
#define dc_cisw(p) cacheop("dc cisw", p)
|
||||
#define dc_zva(p) cacheop("dc zva", p)
|
||||
#define dc_cvac(p) cacheop("dc cvac", p)
|
||||
#define dc_cvau(p) cacheop("dc cvau", p)
|
||||
#define dc_civac(p) cacheop("dc civac", p)
|
||||
|
||||
extern char _base[0];
|
||||
|
||||
/*
|
||||
* These functions are guaranteed to copy by reading from src and writing to dst
|
||||
* in <n>-bit units If size is not aligned, the remaining bytes are not copied
|
||||
|
@ -211,5 +238,6 @@ void regdump(u64 addr, int len);
|
|||
int sprintf(char *str, const char *fmt, ...);
|
||||
int debug_printf(const char *fmt, ...);
|
||||
void udelay(u32 d);
|
||||
void reboot(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,7 +11,7 @@ memcpy64:
|
|||
str x3, [x0], #8
|
||||
subs x2, x2, #8
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memset64
|
||||
|
@ -22,7 +22,7 @@ memset64:
|
|||
1: str x1, [x0], #8
|
||||
subs x2, x2, #8
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memcpy32
|
||||
|
@ -30,11 +30,11 @@ memset64:
|
|||
memcpy32:
|
||||
ands x2, x2, #~3
|
||||
beq 2f
|
||||
1: ldr x3, [x1], #4
|
||||
1: ldr w3, [x1], #4
|
||||
str w3, [x0], #4
|
||||
subs x2, x2, #4
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memset32
|
||||
|
@ -45,7 +45,7 @@ memset32:
|
|||
1: str w1, [x0], #4
|
||||
subs x2, x2, #4
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memcpy16
|
||||
|
@ -57,7 +57,7 @@ memcpy16:
|
|||
strh w3, [x0], #2
|
||||
subs x2, x2, #2
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memset16
|
||||
|
@ -68,7 +68,7 @@ memset16:
|
|||
1: strh w1, [x0], #2
|
||||
subs x2, x2, #2
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memcpy8
|
||||
|
@ -80,7 +80,7 @@ memcpy8:
|
|||
strb w3, [x0], #1
|
||||
subs x2, x2, #1
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
||||
.globl memset8
|
||||
|
@ -91,5 +91,5 @@ memset8:
|
|||
1: strb w1, [x0], #1
|
||||
subs x2, x2, #1
|
||||
bne 1b
|
||||
2:
|
||||
2:
|
||||
ret
|
||||
|
|
Loading…
Reference in a new issue