nexus-am/SPEC.md

4.5 KiB
Raw Blame History

The Abstract Machine Specification

注意事项:

  • 所有扩展的函数/数据结构需要在扩展初始化后调用(例如调用IOE中的函数需在_ioe_init()之后)。

AM中用到的数据结构

  • _Area代表一段连续的内存,组成[start, end)的左闭右开区间。
  • _RegSet代表体系结构相关的寄存器组。GPR系列寄存器定义了一些可以用来使用的寄存器(用于ABI)。GPR1GPR4为可读寄存器,GPRx为可写寄存器。例如在x86中#define GPR1 eax。使用regs->GPR1来读取寄存器的数值。

体系结构相关代码规范

每个体系结构在arch/中包含一个同名目录,例如mips32-npc, mips32-qemu, x86-qemu第一个词是ISA第二个词是运行平台。对于每一个体系结构目录例如arch/mips32-npc),包含:

  • README.md相关说明。
  • include/存放相关的头文件。
  • include/arch.h描述体系结构相关的信息,包括:
    • 整数类型size_t, off_t的定义。
    • typedef struct _RegSet {} _Regset;代表所有体系结构寄存器。
  • src/存放相关的源代码文件。
  • img/存放制作镜像必要的文件。执行img/burn target files能将files对应的文件列表(.a)链接,并烧录成名为target的镜像。

Turing Machine (内存计算机)

数据结构

  • extern _Area _heap; 一段可读、可写、可执行的内存,作为可分配的堆区。

TRM API

  • void _putc(char ch); 调试输出一个字符。输出到何处由具体平台决定(例如qemu将输出到串口因此使用serial=stdio就能在终端接收到调试信息对Linux native输出到本地控制台)。
  • void _halt(int code); 终止运行并报告返回代码。code为0表示正常终止。

IO Extension (输入/输出扩展)

数据结构与静态数据

  • _Device代表一个设备描述结构体,包含:
    • uint32_t id:设备编号;
    • const char *name:设备名称;
    • size_t (*read)(intptr_t reg, void *buf, size_t size): 从设备控制寄存器reg读取size字节;
    • size_t (*write)(intptr_t reg, void *buf, size_t size): 向设备控制寄存器reg写入size字节。

每个设备支持的读/写规范不同请参考AM设备手册。不支持读/写的设备相应read/writeNULL

IOE API

  • void _ioe_init(); 初始化Extension。
  • _Device *_device(int n);返回系统中编号为n的设备。系统中从1开始连续的设备可用(返回非NULL)。若系统中有10个设备_device(1)_device(10)会返回非NULL指针,其他数值会返回空指针。

Asynchronous Extension (异步执行扩展)

数据结构与静态数据

  • _Event表示一个异步(异常/中断)事件,包含:
    • int event: _EVENT_XXX指定的事件编号
    • intptr_t cause: 产生异步事件的原因

ASYE API

  • void _asye_init(_RegSet* (*l)(Event ev, _RegSet *regs));初始化Extension。初始化后并不响应异步事件。l是监听中断/异常事件的回调函数。在中断/异常事件到来时调用l(ev, regs)。中断结束后将返回到返回值指定的寄存器现场(可以返回传入的参数或NULL)。系统事件:
    • _EVENT_IRQ_TIMER:时钟中断(无cause)
    • _EVENT_IRQ_IODEV:I/O设备中断(无cause)
    • _EVENT_ERROR:一般错误(无cause)
    • _EVENT_PAGEFAULT:页错误(cause是_PROT_XXX的值ref是缺页的地址)
    • _EVENT_TRAP:内核态自陷(无cause)
    • _EVENT_SYSCALL: 系统调用(无cause)
  • _RegSet *_make(_Area kstack, void (*entry)(void *), void *arg);创建内核上下文,堆栈为kstack所描述的区域,内核上下文从entry(arg) 开始执行。
  • void _yield();:让出当前处理器的执行,使用自陷指令保存当前寄存器现场,并调用注册的l
  • int _set_intr(int enable):根据enable == 0关闭中断,否则打开中断。
  • int _get_intr():返回当前处理器的中断状态(0关闭/1打开)。

Protection Extension (存储保护扩展)

数据结构与静态数据

  • _Protect描述一个被保护的地址空间,包含:
    • _Area area: 可以使用的地址空间
    • ptr: 体系结构相关的指针供AM内部使用

PTE API

(调整中)

Multi-Processor Extension (多处理器扩展)

MPE API

  • void _mpe_init(void (*entry)());启动多处理器。
  • int _ncpu();返回number of CPU。
  • int _cpu();返回当前CPU的编号(从0开始)。
  • intptr_t _atomic_xchg(volatile void *addr, intptr_t newval);原子交换两数。保证内存顺序一致性。