├── .gitignore ├── LICENSE ├── README.md ├── doc ├── boot.txt ├── hal.txt ├── interposer.txt ├── kernel.txt └── process.txt ├── src ├── arch │ ├── arm │ │ ├── armv7 │ │ │ ├── common │ │ │ │ └── include │ │ │ │ │ ├── atomic.h │ │ │ │ │ ├── bootparam.h │ │ │ │ │ ├── context.h │ │ │ │ │ ├── data.h │ │ │ │ │ ├── memlayout.h │ │ │ │ │ ├── memory.h │ │ │ │ │ └── reg.h │ │ │ ├── hal │ │ │ │ ├── cpu │ │ │ │ │ ├── cpuid.c │ │ │ │ │ ├── mp.c │ │ │ │ │ └── topo.c │ │ │ │ ├── hal.c │ │ │ │ ├── hal.ld │ │ │ │ ├── include │ │ │ │ │ ├── cpu.h │ │ │ │ │ ├── int.h │ │ │ │ │ ├── kernel.h │ │ │ │ │ ├── mem.h │ │ │ │ │ ├── pic.h │ │ │ │ │ ├── time.h │ │ │ │ │ └── vecnum.h │ │ │ │ ├── int │ │ │ │ │ ├── context.c │ │ │ │ │ ├── entry.S │ │ │ │ │ ├── int.c │ │ │ │ │ ├── restore.S │ │ │ │ │ └── syscall.c │ │ │ │ ├── kernel │ │ │ │ │ ├── dispatch.c │ │ │ │ │ ├── kernel.c │ │ │ │ │ └── mzone.c │ │ │ │ ├── mem │ │ │ │ │ ├── map.c │ │ │ │ │ ├── palloc.c │ │ │ │ │ └── tlb.c │ │ │ │ ├── pic │ │ │ │ │ ├── timer.c │ │ │ │ │ └── work.c │ │ │ │ └── time │ │ │ │ │ └── time.c │ │ │ ├── kernel │ │ │ │ ├── kernel.ld │ │ │ │ └── syscall │ │ │ │ │ └── ksys_syscall.c │ │ │ ├── klibc │ │ │ │ └── sys │ │ │ │ │ └── do_syscall.c │ │ │ ├── loader │ │ │ │ ├── include │ │ │ │ │ └── setup.h │ │ │ │ ├── loader.ld │ │ │ │ ├── setup.c │ │ │ │ └── start.S │ │ │ └── tmake.arch │ │ └── armv8 │ │ │ ├── common │ │ │ └── include │ │ │ │ ├── atomic.h │ │ │ │ ├── bootparam.h │ │ │ │ ├── context.h │ │ │ │ ├── data.h │ │ │ │ ├── memlayout.h │ │ │ │ ├── memory.h │ │ │ │ └── reg.h │ │ │ ├── hal │ │ │ ├── hal.ld │ │ │ └── include │ │ │ │ └── vecnum.h │ │ │ ├── kernel │ │ │ ├── kernel.ld │ │ │ └── syscall │ │ │ │ └── ksys_syscall.c │ │ │ ├── klibc │ │ │ └── sys │ │ │ │ └── do_syscall.c │ │ │ ├── loader │ │ │ ├── hal.c │ │ │ ├── loader.ld │ │ │ └── start.S │ │ │ └── tmake.arch │ ├── ia32 │ │ ├── boot │ │ │ └── floppy │ │ │ │ ├── boot.asm │ │ │ │ ├── floppy.c │ │ │ │ └── floppy.ld │ │ ├── common │ │ │ └── include │ │ │ │ ├── atomic.h │ │ │ │ ├── bootparam.h │ │ │ │ ├── context.h │ │ │ │ ├── data.h │ │ │ │ ├── memlayout.h │ │ │ │ ├── memlayout.inc │ │ │ │ └── memory.h │ │ ├── hal │ │ │ ├── acpi │ │ │ │ ├── acpi.c │ │ │ │ ├── fadt.c │ │ │ │ └── madt.c │ │ │ ├── apic │ │ │ │ ├── apic.c │ │ │ │ ├── i8259a.c │ │ │ │ ├── ioapic.c │ │ │ │ ├── ipi.c │ │ │ │ ├── lapic.c │ │ │ │ └── timer.c │ │ │ ├── bios │ │ │ │ └── ebda.c │ │ │ ├── cpu │ │ │ │ ├── cpuid.c │ │ │ │ ├── mp.c │ │ │ │ ├── mps.c │ │ │ │ ├── msr.c │ │ │ │ └── topo.c │ │ │ ├── drv │ │ │ │ └── keyboard.c │ │ │ ├── exec │ │ │ │ ├── elf.c │ │ │ │ └── exec.c │ │ │ ├── hal.c │ │ │ ├── include │ │ │ │ ├── acpi.h │ │ │ │ ├── apic.h │ │ │ │ ├── bios.h │ │ │ │ ├── cpu.h │ │ │ │ ├── drv.h │ │ │ │ ├── exec.h │ │ │ │ ├── font.h │ │ │ │ ├── i8259a.h │ │ │ │ ├── int.h │ │ │ │ ├── kernel.h │ │ │ │ ├── lib.h │ │ │ │ ├── mem.h │ │ │ │ ├── mps.h │ │ │ │ ├── periph.h │ │ │ │ ├── syscall.h │ │ │ │ ├── task.h │ │ │ │ └── time.h │ │ │ ├── int │ │ │ │ ├── handler.asm │ │ │ │ ├── idt.c │ │ │ │ └── int.c │ │ │ ├── kernel │ │ │ │ ├── initk.c │ │ │ │ ├── mzone.c │ │ │ │ └── wrapk.c │ │ │ ├── lib │ │ │ │ ├── bit2.c │ │ │ │ ├── io.c │ │ │ │ └── misc.c │ │ │ ├── mem │ │ │ │ ├── gdt.c │ │ │ │ ├── map.c │ │ │ │ ├── palloc.c │ │ │ │ └── tlb.c │ │ │ ├── periph │ │ │ │ └── video.c │ │ │ ├── syscall │ │ │ │ ├── syscall.c │ │ │ │ └── sysenter.asm │ │ │ ├── task │ │ │ │ ├── context.c │ │ │ │ └── tss.c │ │ │ └── time │ │ │ │ ├── pit.c │ │ │ │ ├── rtc.c │ │ │ │ ├── tick.c │ │ │ │ └── time.c │ │ ├── kernel │ │ │ └── syscall │ │ │ │ └── ksys_syscall.c │ │ ├── klibc │ │ │ └── sys │ │ │ │ └── do_syscall.c │ │ ├── loader │ │ │ ├── font.h │ │ │ ├── loader.h │ │ │ ├── pm_setup.inc │ │ │ ├── protected.c │ │ │ ├── protected.ld │ │ │ ├── real.c │ │ │ ├── real.ld │ │ │ └── start.asm │ │ └── tmake.arch │ ├── mips │ │ ├── common │ │ │ └── include │ │ │ │ ├── asm.h │ │ │ │ ├── bootparam.h │ │ │ │ ├── context.h │ │ │ │ └── reg.h │ │ ├── hal │ │ │ ├── cpu │ │ │ │ ├── cpuid.c │ │ │ │ ├── mp.c │ │ │ │ └── topo.c │ │ │ ├── hal.c │ │ │ ├── include │ │ │ │ ├── cpu.h │ │ │ │ ├── int.h │ │ │ │ ├── kernel.h │ │ │ │ ├── lib.h │ │ │ │ ├── mem.h │ │ │ │ ├── periph.h │ │ │ │ ├── pic.h │ │ │ │ ├── time.h │ │ │ │ └── vecnum.h │ │ │ ├── int │ │ │ │ ├── context.c │ │ │ │ ├── int.c │ │ │ │ └── syscall.c │ │ │ ├── kernel │ │ │ │ ├── dispatch.c │ │ │ │ ├── kernel.c │ │ │ │ └── mzone.c │ │ │ ├── lib │ │ │ │ └── debug.c │ │ │ ├── mem │ │ │ │ └── palloc.c │ │ │ ├── periph │ │ │ │ ├── i8253.c │ │ │ │ ├── i8259.c │ │ │ │ ├── periph.c │ │ │ │ ├── rtc.c │ │ │ │ ├── uart.c │ │ │ │ └── video.c │ │ │ ├── pic │ │ │ │ ├── pic.c │ │ │ │ └── timer.c │ │ │ └── time │ │ │ │ ├── tick.c │ │ │ │ └── time.c │ │ ├── kernel │ │ │ └── syscall │ │ │ │ └── ksys_syscall.c │ │ ├── klibc │ │ │ ├── klibc.ld │ │ │ └── sys │ │ │ │ └── do_syscall.c │ │ ├── loader │ │ │ ├── loader.c │ │ │ ├── periph.c │ │ │ ├── periph.h │ │ │ └── start.S │ │ ├── mips32 │ │ │ ├── common │ │ │ │ └── include │ │ │ │ │ ├── atomic.h │ │ │ │ │ ├── cp0.h │ │ │ │ │ ├── memlayout.h │ │ │ │ │ ├── memory.h │ │ │ │ │ └── page.h │ │ │ ├── hal │ │ │ │ ├── hal.ld │ │ │ │ ├── int │ │ │ │ │ ├── entry.S │ │ │ │ │ └── restore.S │ │ │ │ └── mem │ │ │ │ │ ├── map.c │ │ │ │ │ └── tlb.c │ │ │ ├── kernel │ │ │ │ └── kernel.ld │ │ │ ├── loader │ │ │ │ └── loader.ld │ │ │ ├── mips32b │ │ │ │ ├── common │ │ │ │ │ └── include │ │ │ │ │ │ └── data.h │ │ │ │ └── tmake.arch │ │ │ ├── mips32l │ │ │ │ ├── common │ │ │ │ │ └── include │ │ │ │ │ │ └── data.h │ │ │ │ └── tmake.arch │ │ │ └── tmake.inc │ │ └── mips64 │ │ │ ├── common │ │ │ └── include │ │ │ │ ├── atomic.h │ │ │ │ ├── cp0.h │ │ │ │ ├── memlayout.h │ │ │ │ ├── memory.h │ │ │ │ └── page.h │ │ │ ├── hal │ │ │ ├── hal.ld │ │ │ ├── int │ │ │ │ ├── entry.S │ │ │ │ └── restore.S │ │ │ └── mem │ │ │ │ ├── map.c │ │ │ │ └── tlb.c │ │ │ ├── kernel │ │ │ └── kernel.ld │ │ │ ├── loader │ │ │ └── loader.ld │ │ │ ├── mips64b │ │ │ ├── common │ │ │ │ └── include │ │ │ │ │ └── data.h │ │ │ └── tmake.arch │ │ │ ├── mips64l │ │ │ ├── common │ │ │ │ └── include │ │ │ │ │ └── data.h │ │ │ └── tmake.arch │ │ │ └── tmake.inc │ ├── ppc32 │ │ ├── common │ │ │ └── include │ │ │ │ ├── asm.h │ │ │ │ ├── atomic.h │ │ │ │ ├── bootparam.h │ │ │ │ ├── context.h │ │ │ │ ├── data.h │ │ │ │ ├── memlayout.h │ │ │ │ └── memory.h │ │ ├── hal │ │ │ ├── cpu │ │ │ │ ├── cpuid.c │ │ │ │ ├── mp.c │ │ │ │ └── topo.c │ │ │ ├── hal.c │ │ │ ├── hal.ld │ │ │ ├── include │ │ │ │ ├── cpu.h │ │ │ │ ├── int.h │ │ │ │ ├── kernel.h │ │ │ │ ├── lib.h │ │ │ │ ├── mem.h │ │ │ │ ├── time.h │ │ │ │ └── vecnum.h │ │ │ ├── int │ │ │ │ ├── context.c │ │ │ │ ├── entry.S │ │ │ │ ├── int.c │ │ │ │ ├── pagefault.c │ │ │ │ ├── restore.S │ │ │ │ ├── syscall.c │ │ │ │ └── work.c │ │ │ ├── kernel │ │ │ │ ├── dispatch.c │ │ │ │ ├── kernel.c │ │ │ │ └── mzone.c │ │ │ ├── lib │ │ │ │ └── debug.c │ │ │ ├── mem │ │ │ │ ├── map.c │ │ │ │ ├── palloc.c │ │ │ │ ├── pht.c │ │ │ │ └── tlb.c │ │ │ └── time │ │ │ │ ├── tick.c │ │ │ │ └── time.c │ │ ├── kernel │ │ │ ├── kernel.ld │ │ │ └── syscall │ │ │ │ └── ksys_syscall.c │ │ ├── klibc │ │ │ └── sys │ │ │ │ └── do_syscall.c │ │ ├── loader │ │ │ ├── loader.c │ │ │ ├── loader.ld │ │ │ └── start.S │ │ └── tmake.arch │ └── sparc │ │ ├── hal │ │ ├── cpu │ │ │ └── mp.c │ │ ├── hal.c │ │ ├── hal.ld │ │ ├── include │ │ │ ├── cpu.h │ │ │ ├── int.h │ │ │ ├── lib.h │ │ │ └── periph.h │ │ ├── int │ │ │ └── int.c │ │ ├── lib │ │ │ └── debug.c │ │ └── periph │ │ │ └── print.c │ │ ├── kernel │ │ └── syscall │ │ │ └── ksys_syscall.c │ │ ├── klibc │ │ └── sys │ │ │ └── do_syscall.c │ │ └── sparcv8 │ │ ├── common │ │ └── include │ │ │ ├── atomic.h │ │ │ ├── bootparam.h │ │ │ ├── context.h │ │ │ ├── data.h │ │ │ ├── memlayout.h │ │ │ └── memory.h │ │ ├── sun4m │ │ └── loader │ │ │ ├── loader.ld │ │ │ └── start.S │ │ └── tmake.arch ├── common │ └── include │ │ ├── compiler.h │ │ ├── coreimg.h │ │ ├── elf32.h │ │ ├── errno.h │ │ ├── floppyimg.h │ │ ├── kdisp.h │ │ ├── kexport.h │ │ ├── ofw.h │ │ ├── proc.h │ │ ├── syscall.h │ │ ├── ua.h │ │ ├── urs.h │ │ └── vgafont.h ├── driver │ ├── bus │ │ └── system │ │ │ └── sysbus.c │ ├── console │ │ ├── console.c │ │ └── stdio.c │ ├── devfs │ │ ├── devfs.c │ │ └── tree.c │ ├── driver.c │ ├── include │ │ ├── bus │ │ │ └── sysbus.h │ │ ├── console.h │ │ ├── devfs.h │ │ └── keyboard.h │ ├── keyboard │ │ └── keyboard.c │ └── pseudo │ │ └── null │ │ └── null.c ├── hal │ ├── cpu │ │ └── percpu.c │ ├── fb │ │ └── draw.c │ ├── include │ │ ├── bit.h │ │ ├── bootparam.h │ │ ├── debug.h │ │ ├── fb.h │ │ ├── kalloc.h │ │ ├── percpu.h │ │ ├── print.h │ │ ├── string.h │ │ └── vector.h │ ├── int │ │ └── vector.c │ ├── lib │ │ ├── bit.c │ │ ├── bootparam.c │ │ ├── halt.c │ │ └── string.c │ ├── mem │ │ └── kalloc.c │ └── print │ │ └── kprintf.c ├── init │ └── init.py ├── kernel │ ├── coreimg │ │ ├── coreimg.c │ │ ├── fs.c │ │ └── startup.c │ ├── ds │ │ ├── hashtable.c │ │ └── list.c │ ├── exec │ │ ├── copy.c │ │ ├── elf.c │ │ └── exec.c │ ├── include │ │ ├── coreimg.h │ │ ├── ds.h │ │ ├── exec.h │ │ ├── hal.h │ │ ├── kapi.h │ │ ├── lib.h │ │ ├── mem.h │ │ ├── proc.h │ │ ├── sync.h │ │ └── syscall.h │ ├── kapi │ │ ├── heap.c │ │ ├── interrupt.c │ │ ├── kapi.c │ │ ├── kmap.c │ │ ├── process.c │ │ └── thread.c │ ├── kernel.c │ ├── lib │ │ └── string.c │ ├── mem │ │ ├── malloc.c │ │ ├── palloc.c │ │ ├── pfn.c │ │ └── salloc.c │ ├── proc │ │ ├── asid.c │ │ ├── dalloc.c │ │ ├── dummy.c │ │ ├── futex.c │ │ ├── heap.c │ │ ├── kmap.c │ │ ├── monitor.c │ │ ├── process.c │ │ ├── sched.c │ │ ├── thread.c │ │ └── tlb.c │ ├── sync │ │ └── spinlock.c │ └── syscall │ │ ├── interrupt.c │ │ ├── ioport.c │ │ ├── ipc.c │ │ ├── kputs.c │ │ ├── ksys.c │ │ ├── syscall.c │ │ └── time.c ├── klibc │ ├── include │ │ ├── assert.h │ │ ├── kthread.h │ │ ├── stdarg.h │ │ ├── stdio.h │ │ ├── stdlib.h │ │ ├── stdstruct.h │ │ ├── string.h │ │ ├── sys.h │ │ └── time.h │ ├── kthread │ │ ├── mutex.c │ │ ├── thread.c │ │ └── tls.c │ ├── start.c │ ├── stdio │ │ ├── kprintf.c │ │ └── vsnprintf.c │ ├── stdlib │ │ ├── halloc.c │ │ ├── malloc.c │ │ └── salloc.c │ ├── stdstruct │ │ ├── dlist.c │ │ └── hash.c │ ├── string │ │ ├── mem.c │ │ └── str.c │ ├── sys │ │ ├── heap.c │ │ ├── interrupt.c │ │ ├── kapi.c │ │ ├── kmap.c │ │ ├── msg.c │ │ ├── process.c │ │ ├── stdio.c │ │ ├── sys.c │ │ ├── syscall.c │ │ ├── thread.c │ │ └── urs.c │ └── time │ │ └── time.c ├── loader │ ├── cmdline │ │ └── cmdline.c │ ├── exec │ │ └── exec.c │ ├── firmware │ │ └── ofw │ │ │ └── ofw.c │ ├── include │ │ ├── arg.h │ │ ├── cmdline.h │ │ ├── exec.h │ │ ├── firmware │ │ │ └── ofw.h │ │ ├── lib.h │ │ ├── mempool.h │ │ ├── obp.h │ │ ├── periph │ │ │ └── bcm2835.h │ │ └── print.h │ ├── lib │ │ ├── bss.c │ │ ├── debug.c │ │ ├── endian.c │ │ ├── math.c │ │ └── string.c │ ├── mempool │ │ └── mempool.c │ ├── obp │ │ └── obp.c │ ├── periph │ │ └── bcm2835 │ │ │ ├── bcm2835.c │ │ │ ├── framebuffer.c │ │ │ ├── gpio.c │ │ │ ├── led.c │ │ │ ├── mailbox.c │ │ │ ├── pl011.c │ │ │ ├── power.c │ │ │ ├── timer.c │ │ │ └── uart.c │ └── print │ │ ├── draw.c │ │ └── lprintf.c ├── mach │ ├── generic │ │ └── README.md │ ├── mac │ │ └── hal │ │ │ ├── include │ │ │ └── periph.h │ │ │ └── periph │ │ │ ├── escc.c │ │ │ ├── heathrow_pic.c │ │ │ ├── ofw.c │ │ │ ├── openpic.c │ │ │ └── periph.c │ ├── malta │ │ └── spaceholder │ ├── pc │ │ └── spaceholder │ ├── raspi2 │ │ ├── hal │ │ │ ├── include │ │ │ │ └── periph.h │ │ │ └── periph.c │ │ └── loader │ │ │ └── loader.c │ └── sun4m │ │ └── loader │ │ ├── loader.c │ │ └── periph.c ├── shell │ ├── builtin │ │ ├── builtin.c │ │ ├── cat.c │ │ ├── cd.c │ │ ├── date.c │ │ ├── echo.c │ │ ├── hello.c │ │ ├── ls.c │ │ ├── mv.c │ │ ├── pwd.c │ │ ├── rm.c │ │ └── touch.c │ ├── exec.c │ ├── include │ │ ├── builtin.h │ │ └── shell.h │ ├── path.c │ └── shell.c └── system │ ├── fs │ ├── coreimg │ │ └── coreimg.c │ ├── procfs │ │ ├── monitor.c │ │ └── procfs.c │ └── ramfs │ │ └── ramfs.c │ ├── include │ ├── fs.h │ ├── kapi.h │ └── urs.h │ ├── kapi │ ├── file.c │ ├── kapi.c │ └── urs.c │ ├── system.c │ ├── ua │ └── user.c │ └── urs │ └── urs.c ├── tmake ├── tmake.main └── tools ├── coreimg.c ├── floppyimg.c └── tmake.tools /.gitignore: -------------------------------------------------------------------------------- 1 | # Git 2 | /.git 3 | 4 | # Targets 5 | /target 6 | /vm 7 | 8 | # KDevelop 9 | /.kdev4 10 | *.kdev4 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Simplified BSD License 2 | 3 | Copyright (c) 2016, Ruohuang Zheng 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /doc/boot.txt: -------------------------------------------------------------------------------- 1 | Boot Memory Layout 2 | 3 | |=======================| <- a000:0000 4 | | Reserved | 5 | |=======================| <- 9000:0000 6 | | | 7 | | Core Image | 512 KB 8 | | | 9 | |=======================| <- 1000:0000 10 | | Loader Variables | 4 KB 11 | |-----------------------| <- 0000:f000 12 | | Protected | 8 KB 13 | | -----------| <- 0000:d000 14 | | Loader 16 KB Real | 6 KB 15 | | -----------| <- 0000:b800 16 | | Start | 2 KB 17 | |-----------------------| <- 0000:b000 -> Aligned to 4KB in order to start application processors 18 | | Loader Stack / Boot | 4 KB -> If the boot program is too large, 19 | |=-=-=-=-=-=-=-=-=-=-=-=| <- 0000:a000 loader stack may share this area with the boot program before loader starts 20 | | | 21 | | Boot | 9 KB 22 | | | 23 | |-----------------------| <- 0000:7c00 24 | | Boot Stack | 25 | |=======================| <- 0000:7000 -> HAL Start Parameters 26 | | Disk Sector 2 | 27 | |-----------------------| <- 0000:6000 -> BIOS Invoker Registers 28 | | Disk Sector 1 | 29 | |=======================| <- 0000:5000 30 | | | 31 | | Boot Parameters | 8 KB 32 | | | 33 | |=======================| <- 0000:2000 34 | | Reserved | 35 | |=======================| <- 0000:0000 36 | 37 | -------------------------------------------------------------------------------- /doc/interposer.txt: -------------------------------------------------------------------------------- 1 | Interposer Virtual Memory Layout PDE Index : PTE Index 2 | 3 | |=======================| <- 4GB = 0x100000000 4 | | | 1023 : 1023 5 | | HAL and Kernel | | 6 | | Code and Data | 7 | | Per-CPU Data | 8 | | | 1023 : 0 9 | |=======================| <- 4GB - 4MB = 0xFFC00000 10 | | | 11 | | | 12 | | Subsystem Kernel | 13 | | | 14 | | | 15 | |=======================| <- 3GB/2GB 16 | | | 17 | | | 18 | | Fake Physical Memory | 19 | | | 20 | | The interposer || 21 | | thinks this is the | 22 | | physical memory. | 23 | | | 24 | | However, the actual | 25 | | mapping is controlled | 26 | | by Toddler kernel | 27 | | | 28 | | | 29 | |=======================| <- 0 = 0x0 30 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/common/include/bootparam.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_BOOTPARAM__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_BOOTPARAM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | #define VIDEO_NONE 0 8 | #define VIDEO_FRAMEBUFFER 1 9 | #define VIDEO_TEXT 2 10 | #define VIDEO_UART 3 11 | 12 | struct boot_mem_zone { 13 | u64 start_paddr; 14 | u64 len; 15 | u32 type; 16 | } packedstruct; 17 | 18 | struct boot_parameters { 19 | // Boot device 20 | u32 boot_dev; 21 | u32 boot_dev_info; 22 | 23 | // Loader 24 | ulong loader_func_type; 25 | 26 | // AP starter 27 | ulong ap_entry; 28 | ulong ap_page_dir; 29 | ulong ap_stack_top; 30 | 31 | // Paging 32 | ulong hal_page_dir; 33 | 34 | // Core image 35 | ulong coreimg_load_addr; 36 | 37 | // HAL 38 | u32 hal_start_flag; 39 | ulong hal_entry_addr; 40 | ulong hal_vaddr_end; 41 | ulong hal_vspace_end; 42 | 43 | // Kernel 44 | ulong kernel_entry_addr; 45 | 46 | // Video info 47 | u32 video_mode; 48 | u32 cursor_row; 49 | u32 cursor_col; 50 | ulong framebuffer_addr; 51 | u32 res_x; 52 | u32 res_y; 53 | u32 bytes_per_pixel; 54 | u32 bytes_per_line; 55 | 56 | // Address where free memory starts 57 | ulong free_addr_start; 58 | ulong free_pfn_start; 59 | 60 | // Memory size 61 | u64 mem_size; 62 | 63 | // Memory zones 64 | u32 mem_zone_count; 65 | struct boot_mem_zone mem_zones[32]; 66 | } packedstruct; 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/common/include/context.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_CONTEXT__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_CONTEXT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Context 10 | */ 11 | struct context { 12 | u32 pc; 13 | u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; 14 | union { u32 r13; u32 sp; }; 15 | union { u32 r14; u32 lr; }; 16 | u32 cpsr; 17 | } packedstruct; 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 32 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 1 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 0 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/common/include/memlayout.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_MEMLAYOUT__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_MEMLAYOUT__ 3 | 4 | 5 | #include "common/include/memory.h" 6 | 7 | 8 | /* 9 | * Loader 10 | */ 11 | // #define LOADER_MEMPOOL_SIZE (0x10000) // 64KB 12 | 13 | /* 14 | * HAL 15 | */ 16 | #define HAL_VSPACE_END (0xffff0000) // 4GB-64KB, interrupt vector starts @ 0xffff0000 17 | #define HAL_L1TABLE_OFFSET (0xf8000) // 1MB-32KB 18 | 19 | #define HAL_STACK_TOP_VADDR (0xfff88000 - 0x10) // 32KB 20 | 21 | #define PER_CPU_AREA_BASE_VADDR (0xffc00000) // 4GB-4MB 22 | 23 | #define PER_CPU_AREA_PAGE_COUNT (2) 24 | #define PER_CPU_AREA_SIZE (PAGE_SIZE * PER_CPU_AREA_PAGE_COUNT) 25 | #define PER_CPU_DATA_START_OFFSET (0) 26 | #define PER_CPU_STACK_TOP_OFFSET (PER_CPU_AREA_SIZE - 0x10) 27 | 28 | // #define THREAD_CTRL_BLOCK_ALIGNMENT (64) 29 | 30 | 31 | /* 32 | * User address space 33 | */ 34 | #define USER_VADDR_SPACE_END (0xf0000000) // 4GB-256MB 35 | 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/cpu/cpuid.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/cpu.h" 4 | 5 | 6 | /* 7 | * Init 8 | */ 9 | void init_cpuid() 10 | { 11 | kprintf("Detecting CPU information\n"); 12 | } 13 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/cpu/topo.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/cpu.h" 4 | #include "hal/include/periph.h" 5 | 6 | 7 | int num_cpus = 0; 8 | 9 | 10 | void init_topo() 11 | { 12 | kprintf("Detecting processor topology\n"); 13 | 14 | num_cpus = periph_detect_num_cpus(); 15 | 16 | kprintf("\tNumber of logical CPUs: %d\n", num_cpus); 17 | } 18 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/hal.ld: -------------------------------------------------------------------------------- 1 | ENTRY(hal_entry) 2 | 3 | SECTIONS 4 | { 5 | . = 0xfff88000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : 11 | { 12 | *(entry); 13 | *(.text); 14 | } 15 | __text_end = .; 16 | 17 | __rodata_start = .; 18 | .rodata : 19 | { 20 | *(.rodata) 21 | } 22 | __rodata_end = .; 23 | 24 | __data_start = .; 25 | .data : 26 | { 27 | *(.data) 28 | } 29 | __data_end = .; 30 | 31 | __bss_start = .; 32 | .bss : 33 | { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/include/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_CPU__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_CPU__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * CPU ID 10 | */ 11 | extern void init_cpuid(); 12 | 13 | 14 | /* 15 | * Topo 16 | */ 17 | extern int num_cpus; 18 | extern void init_topo(); 19 | 20 | 21 | /* 22 | * MP 23 | */ 24 | extern int get_cpu_id(); 25 | 26 | extern ulong get_per_cpu_area_start_paddr(int cpu_id); 27 | extern ulong get_my_cpu_area_start_paddr(); 28 | 29 | extern ulong get_per_cpu_area_start_vaddr(int cpu_id); 30 | extern ulong get_my_cpu_area_start_vaddr(); 31 | 32 | extern void init_mp(); 33 | 34 | extern void bringup_mp(); 35 | extern void release_mp_lock(); 36 | extern void ap_init_done(); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_KERNEL__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_KERNEL__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/kexport.h" 7 | 8 | 9 | /* 10 | * Memory zone 11 | */ 12 | extern ulong paddr_space_end; 13 | 14 | extern int get_next_mem_zone(struct kernel_mem_zone *cur); 15 | extern void init_kmem_zone(); 16 | 17 | 18 | /* 19 | * General kernel 20 | */ 21 | extern struct kernel_exports *kernel; 22 | 23 | extern void init_kernel(); 24 | extern void kernel_dispatch(struct kernel_dispatch_info *kdi); 25 | 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/include/mem.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_MEM__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_MEM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "hal/include/kalloc.h" 7 | 8 | 9 | /* 10 | * Page allocator 11 | */ 12 | extern ulong palloc(int count); 13 | 14 | 15 | /* 16 | * Mapping 17 | */ 18 | extern void init_user_page_dir(ulong page_dir_pfn); 19 | 20 | extern ulong get_paddr(ulong page_dir_pfn, ulong vaddr); 21 | 22 | extern int user_indirect_map_array( 23 | ulong page_dir_pfn, ulong vaddr, ulong paddr, size_t length, 24 | int exec, int write, int cacheable, int overwrite); 25 | extern int user_indirect_unmap_array(ulong page_dir_pfn, ulong vaddr, ulong paddr, size_t length); 26 | 27 | extern void kernel_map_per_cpu_area(ulong vstart, ulong pstart, ulong size); 28 | 29 | extern void init_map(); 30 | 31 | 32 | /* 33 | * TLB 34 | */ 35 | extern void invalidate_tlb_array(ulong asid, ulong vaddr, size_t size); 36 | extern void init_tlb(); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/include/pic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_PIC__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_PIC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "hal/include/int.h" 7 | 8 | 9 | /* 10 | * Timer 11 | */ 12 | extern int is_generic_timer_asserted(); 13 | extern void start_generic_timer(); 14 | 15 | extern void init_generic_timer(); 16 | extern void init_generic_timer_mp(); 17 | 18 | /* 19 | * Start working 20 | */ 21 | extern void start_working(); 22 | extern void start_working_mp(); 23 | 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/include/time.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_TIME__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_TIME__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "hal/include/int.h" 7 | 8 | 9 | /* 10 | * Tick 11 | */ 12 | // #define BLOCKED_DELAY_TEST_SEC 1 13 | // #define TICK_FREQ 1 14 | // 15 | // extern void change_tick(int freq); 16 | // extern void init_tick(); 17 | // extern void blocked_delay(int ms); 18 | // extern void init_blocked_delay(); 19 | 20 | 21 | /* 22 | * System time 23 | */ 24 | extern void get_system_time(unsigned long *high, unsigned long *low); 25 | // extern int time_interrupt_handler(struct int_context *context, struct kernel_dispatch_info *kdi); 26 | // extern void init_time(); 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/include/vecnum.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_VECNUM__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_VECNUM__ 3 | 4 | 5 | /* 6 | * ARM exception vectors 7 | */ 8 | #define INT_VECTOR_DUMMY 0 9 | 10 | #define INT_VECTOR_RESET 1 11 | #define INT_VECTOR_UNDEFINED 2 12 | #define INT_VECTOR_SVC 3 13 | #define INT_VECTOR_FETCH 4 14 | #define INT_VECTOR_DATA 5 15 | #define INT_VECTOR_RESERVED 6 16 | #define INT_VECTOR_IRQ 7 17 | #define INT_VECTOR_FIQ 8 18 | 19 | 20 | /* 21 | * Internal handlers 22 | */ 23 | #define INT_VECTOR_LOCAL_TIMER 10 24 | #define INT_VECTOR_SYSCALL 11 25 | #define INT_VECTOR_UNKNOWN_DEV 12 26 | #define INT_VECTOR_SPURIOUS_FIQ 13 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/int/restore.S: -------------------------------------------------------------------------------- 1 | .global restore_context_gpr 2 | 3 | restore_context_gpr: 4 | /* Switch to SVC mode */ 5 | cpsid aif, #0x13 6 | 7 | /* Load SPSR */ 8 | ldr r0, [sp, #64] 9 | msr SPSR, r0 10 | 11 | /* Restore user/system SP (R13) and LR (R14) */ 12 | add sp, sp, #4 13 | add r0, sp, #52 14 | ldmfd r0, {sp, lr}^ 15 | 16 | /* Restore user/system R0-R12 */ 17 | ldmfd sp, {r0-r12}^ 18 | nop 19 | 20 | /* Restore PC and trigger SPSR->CPSR */ 21 | sub sp, sp, #4 22 | ldmfd sp, {pc}^ 23 | 24 | /* Should never reach here */ 25 | b . 26 | nop 27 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/kernel/dispatch.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/kdisp.h" 3 | #include "common/include/reg.h" 4 | #include "hal/include/cpu.h" 5 | #include "hal/include/int.h" 6 | #include "hal/include/kernel.h" 7 | 8 | 9 | void kernel_dispatch(struct kernel_dispatch_info *kdi) 10 | { 11 | // int *user_mode = get_per_cpu(int, cur_in_user_mode); 12 | // 13 | // // Save user mode flag 14 | // int user_mode_save = *user_mode; 15 | // 16 | // // Save ASID in TLB EntryHi 17 | // struct cp0_entry_hi old_hi, hi; 18 | // read_cp0_entry_hi(old_hi.value); 19 | // 20 | // // Set ASID to 0 21 | // hi.value = old_hi.value; 22 | // hi.asid = 0; 23 | // write_cp0_entry_hi(hi.value); 24 | // 25 | // // Put us in kernel, so the TLB miss handler can correctly refill the entry 26 | // *user_mode = 0; 27 | 28 | // FIXME 29 | // Maybe interrupts should not be enabled here at all? 30 | // We are still using the context-saving stack! 31 | // Enable interrupts 32 | // enable_local_int(); 33 | 34 | // Then call kernel dispatcher 35 | kernel->dispatch(*get_per_cpu(ulong, cur_running_sched_id), kdi); 36 | 37 | // Restore user mode flag 38 | // *user_mode = user_mode_save; 39 | 40 | // // Restore ASID 41 | // write_cp0_entry_hi(old_hi.value); 42 | } 43 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/mem/palloc.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | #include "common/include/bootparam.h" 4 | #include "hal/include/print.h" 5 | #include "hal/include/bootparam.h" 6 | #include "hal/include/debug.h" 7 | #include "hal/include/string.h" 8 | 9 | 10 | /* 11 | * Allocate a page, returns PFN 12 | */ 13 | ulong palloc(int count) 14 | { 15 | assert(count > 0); 16 | 17 | struct boot_parameters *bp = get_bootparam(); 18 | 19 | ulong result = bp->free_pfn_start; 20 | bp->free_pfn_start += count; 21 | 22 | // Zero the page 23 | memzero((void *)PFN_TO_ADDR(result), PAGE_SIZE * count); 24 | 25 | // kprintf("PAlloc: %lx, count: %d\n", result, count); 26 | 27 | return result; 28 | } 29 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/mem/tlb.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | #include "common/include/reg.h" 4 | #include "common/include/atomic.h" 5 | #include "hal/include/print.h" 6 | #include "hal/include/bit.h" 7 | #include "hal/include/cpu.h" 8 | #include "hal/include/int.h" 9 | #include "hal/include/mem.h" 10 | 11 | 12 | static void invalidate_tlb(ulong asid, ulong vaddr) 13 | { 14 | // kprintf("TLB shootdown @ %lx, ASID: %lx ...", vaddr, asid); 15 | inv_tlb_all(); 16 | atomic_membar(); 17 | } 18 | 19 | void invalidate_tlb_array(ulong asid, ulong vaddr, size_t size) 20 | { 21 | ulong vstart = ALIGN_DOWN(vaddr, PAGE_SIZE); 22 | ulong vend = ALIGN_UP(vaddr + size, PAGE_SIZE); 23 | ulong page_count = (vend - vstart) >> PAGE_BITS; 24 | 25 | ulong i; 26 | ulong vcur = vstart; 27 | for (i = 0; i < page_count; i++) { 28 | invalidate_tlb(asid, vcur); 29 | vcur += PAGE_SIZE; 30 | } 31 | } 32 | 33 | void init_tlb() 34 | { 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/hal/pic/work.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/reg.h" 3 | #include "hal/include/int.h" 4 | #include "hal/include/pic.h" 5 | #include "hal/include/periph.h" 6 | 7 | 8 | void start_working() 9 | { 10 | // Start the generic timer 11 | start_generic_timer(); 12 | 13 | // Start periph 14 | start_periph(); 15 | 16 | // Enable local interrupt 17 | enable_local_int(); 18 | } 19 | 20 | void start_working_mp() 21 | { 22 | // Start the generic timer 23 | start_generic_timer(); 24 | 25 | // Enable local interrupt 26 | enable_local_int(); 27 | } 28 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xfff08000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : 11 | { 12 | *(entry); 13 | *(.text); 14 | } 15 | __text_end = .; 16 | 17 | __rodata_start = .; 18 | .rodata : 19 | { 20 | *(.rodata) 21 | } 22 | __rodata_end = .; 23 | 24 | __data_start = .; 25 | .data : 26 | { 27 | *(.data) 28 | } 29 | __data_end = .; 30 | 31 | __bss_start = .; 32 | .bss : 33 | { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/kernel/syscall/ksys_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/reg.h" 3 | 4 | 5 | no_opt ulong ksys_get_tcb() 6 | { 7 | unsigned long tcb = 0; 8 | read_software_thread_id(tcb); 9 | 10 | return tcb; 11 | } 12 | 13 | no_opt int ksys_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 14 | { 15 | int success = 0; 16 | unsigned long value1 = 0, value2 = 0; 17 | 18 | __asm__ __volatile__ ( 19 | "mov r0, %[num];" 20 | "mov r1, %[p1];" 21 | "mov r2, %[p2];" 22 | "swi 0;" 23 | "mov %[suc], r0;" 24 | "mov %[v1], r1;" 25 | "mov %[v2], r2;" 26 | : [suc] "=r" (success), [v1] "=r" (value1), [v2] "=r" (value2) 27 | : [num] "r" (num), [p1] "r" (param1), [p2] "r" (param2) 28 | : "r0", "r1", "r2", "memory" 29 | ); 30 | 31 | if (out1) *out1 = value1; 32 | if (out2) *out2 = value2; 33 | 34 | return 1; 35 | } 36 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/klibc/sys/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/proc.h" 3 | #include "common/include/reg.h" 4 | #include "klibc/include/stdio.h" 5 | 6 | 7 | no_opt struct thread_control_block *get_tcb() 8 | { 9 | unsigned long tcb = 0; 10 | read_software_thread_id(tcb); 11 | 12 | return (struct thread_control_block *)tcb; 13 | } 14 | 15 | no_opt int do_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 16 | { 17 | int success = 0; 18 | unsigned long value1 = 0, value2 = 0; 19 | 20 | __asm__ __volatile__ ( 21 | "mov r0, %[num];" 22 | "mov r1, %[p1];" 23 | "mov r2, %[p2];" 24 | "swi 0;" 25 | "mov %[suc], r0;" 26 | "mov %[v1], r1;" 27 | "mov %[v2], r2;" 28 | : [suc] "=r" (success), [v1] "=r" (value1), [v2] "=r" (value2) 29 | : [num] "r" (num), [p1] "r" (param1), [p2] "r" (param2) 30 | : "r0", "r1", "r2", "memory" 31 | ); 32 | 33 | if (out1) *out1 = value1; 34 | if (out2) *out2 = value2; 35 | 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/loader/include/setup.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_LOADER_INCLUDE_SETUP__ 2 | #define __ARCH_ARMV7_LOADER_INCLUDE_SETUP__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | extern void setup_paging(ulong page_dir, ulong dram_start_paddr, ulong dram_end_paddr, ulong hal_area_base_paddr); 9 | extern void enable_mmu(ulong page_dir); 10 | extern void enable_caches(); 11 | extern void enable_bpred(); 12 | 13 | extern void call_hal_entry(ulong entry, ulong stack, ulong bp); 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/arch/arm/armv7/loader/loader.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | 4 | /* 5 | * QEMU loads the image to 0x10000, while a real RPi 2 load the image to 0x8000 6 | */ 7 | __LOADER_BASE = 0x10000; 8 | 9 | 10 | SECTIONS 11 | { 12 | . = __LOADER_BASE; 13 | __start = .; 14 | 15 | __text_start = .; 16 | .text : 17 | { 18 | KEEP(*(.text.boot)) 19 | *(.text) 20 | } 21 | __text_end = .; 22 | 23 | __rodata_start = .; 24 | .rodata : 25 | { 26 | *(.rodata) 27 | } 28 | __rodata_end = .; 29 | 30 | __data_start = .; 31 | .data : 32 | { 33 | *(.data) 34 | } 35 | __data_end = .; 36 | 37 | __bss_start = .; 38 | .bss : 39 | { 40 | *(.bss); 41 | } 42 | __bss_end = .; 43 | 44 | /* 45 | * This makes sure two things 46 | * 1. The end of loader image is aligned to 4KB boundary 47 | * 2. The linker does not cut off the zero-byted BSS section from binary 48 | */ 49 | . = ALIGN(4096) - 1; 50 | .fill : 51 | { 52 | BYTE(0xff); 53 | } 54 | 55 | __end = .; 56 | } 57 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/common/include/bootparam.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_BOOTPARAM__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_BOOTPARAM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | #define VIDEO_NONE 0 8 | #define VIDEO_FRAMEBUFFER 1 9 | #define VIDEO_TEXT 2 10 | #define VIDEO_UART 3 11 | 12 | struct boot_mem_zone { 13 | u64 start_paddr; 14 | u64 len; 15 | u32 type; 16 | } packedstruct; 17 | 18 | struct boot_parameters { 19 | // Boot device 20 | u32 boot_dev; 21 | u32 boot_dev_info; 22 | 23 | // Loader 24 | ulong loader_func_type; 25 | 26 | // AP starter 27 | ulong ap_entry; 28 | ulong ap_page_dir; 29 | ulong ap_stack_top; 30 | 31 | // Paging 32 | ulong hal_page_dir; 33 | 34 | // Core image 35 | ulong coreimg_load_addr; 36 | 37 | // HAL 38 | u32 hal_start_flag; 39 | ulong hal_entry_addr; 40 | ulong hal_vaddr_end; 41 | ulong hal_vspace_end; 42 | 43 | // Kernel 44 | ulong kernel_entry_addr; 45 | 46 | // Video info 47 | u32 video_mode; 48 | u32 cursor_row; 49 | u32 cursor_col; 50 | ulong framebuffer_addr; 51 | u32 res_x; 52 | u32 res_y; 53 | u32 bytes_per_pixel; 54 | u32 bytes_per_line; 55 | 56 | // Address where free memory starts 57 | ulong free_addr_start; 58 | ulong free_pfn_start; 59 | 60 | // Memory size 61 | u64 mem_size; 62 | 63 | // Memory zones 64 | u32 mem_zone_count; 65 | struct boot_mem_zone mem_zones[32]; 66 | } packedstruct; 67 | 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/common/include/context.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_CONTEXT__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_CONTEXT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Context 10 | */ 11 | struct context { 12 | u32 pc; 13 | u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; 14 | union { u32 r13; u32 sp; }; 15 | union { u32 r14; u32 lr; }; 16 | u32 cpsr; 17 | } packedstruct; 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARM64_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_ARM64_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 64 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 1 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 0 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/common/include/memlayout.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_COMMON_INCLUDE_MEMLAYOUT__ 2 | #define __ARCH_ARMV7_COMMON_INCLUDE_MEMLAYOUT__ 3 | 4 | 5 | #include "common/include/memory.h" 6 | 7 | 8 | /* 9 | * Loader 10 | */ 11 | // #define LOADER_MEMPOOL_SIZE (0x10000) // 64KB 12 | 13 | /* 14 | * HAL 15 | */ 16 | #define HAL_VSPACE_END (0xffff0000) // 4GB-64KB, interrupt vector starts @ 0xffff0000 17 | #define HAL_L1TABLE_OFFSET (0xf8000) // 1MB-32KB 18 | 19 | #define HAL_STACK_TOP_VADDR (0xfff88000 - 0x10) // 32KB 20 | 21 | #define PER_CPU_AREA_BASE_VADDR (0xffc00000) // 4GB-4MB 22 | 23 | #define PER_CPU_AREA_PAGE_COUNT (2) 24 | #define PER_CPU_AREA_SIZE (PAGE_SIZE * PER_CPU_AREA_PAGE_COUNT) 25 | #define PER_CPU_DATA_START_OFFSET (0) 26 | #define PER_CPU_STACK_TOP_OFFSET (PER_CPU_AREA_SIZE - 0x10) 27 | 28 | // #define THREAD_CTRL_BLOCK_ALIGNMENT (64) 29 | 30 | 31 | /* 32 | * User address space 33 | */ 34 | #define USER_VADDR_SPACE_END (0xf0000000) // 4GB-256MB 35 | 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/hal/hal.ld: -------------------------------------------------------------------------------- 1 | ENTRY(hal_entry) 2 | 3 | SECTIONS 4 | { 5 | . = 0xfff88000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : 11 | { 12 | *(entry); 13 | *(.text); 14 | } 15 | __text_end = .; 16 | 17 | __rodata_start = .; 18 | .rodata : 19 | { 20 | *(.rodata) 21 | } 22 | __rodata_end = .; 23 | 24 | __data_start = .; 25 | .data : 26 | { 27 | *(.data) 28 | } 29 | __data_end = .; 30 | 31 | __bss_start = .; 32 | .bss : 33 | { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/hal/include/vecnum.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_ARMV7_HAL_INCLUDE_VECNUM__ 2 | #define __ARCH_ARMV7_HAL_INCLUDE_VECNUM__ 3 | 4 | 5 | /* 6 | * ARM exception vectors 7 | */ 8 | #define INT_VECTOR_DUMMY 0 9 | 10 | #define INT_VECTOR_RESET 1 11 | #define INT_VECTOR_UNDEFINED 2 12 | #define INT_VECTOR_SVC 3 13 | #define INT_VECTOR_FETCH 4 14 | #define INT_VECTOR_DATA 5 15 | #define INT_VECTOR_RESERVED 6 16 | #define INT_VECTOR_IRQ 7 17 | #define INT_VECTOR_FIQ 8 18 | 19 | 20 | /* 21 | * Internal handlers 22 | */ 23 | #define INT_VECTOR_LOCAL_TIMER 10 24 | #define INT_VECTOR_SYSCALL 11 25 | #define INT_VECTOR_UNKNOWN_DEV 12 26 | #define INT_VECTOR_SPURIOUS_FIQ 13 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xfff08000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : 11 | { 12 | *(entry); 13 | *(.text); 14 | } 15 | __text_end = .; 16 | 17 | __rodata_start = .; 18 | .rodata : 19 | { 20 | *(.rodata) 21 | } 22 | __rodata_end = .; 23 | 24 | __data_start = .; 25 | .data : 26 | { 27 | *(.data) 28 | } 29 | __data_end = .; 30 | 31 | __bss_start = .; 32 | .bss : 33 | { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/kernel/syscall/ksys_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/reg.h" 3 | 4 | 5 | no_opt ulong ksys_get_tcb() 6 | { 7 | unsigned long tcb = 0; 8 | // read_software_thread_id(tcb); 9 | 10 | return tcb; 11 | } 12 | 13 | no_opt int ksys_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 14 | { 15 | int success = 0; 16 | unsigned long value1 = 0, value2 = 0; 17 | 18 | // __asm__ __volatile__ ( 19 | // "mov r0, %[num];" 20 | // "mov r1, %[p1];" 21 | // "mov r2, %[p2];" 22 | // "swi 0;" 23 | // "mov %[suc], r0;" 24 | // "mov %[v1], r1;" 25 | // "mov %[v2], r2;" 26 | // : [suc] "=r" (success), [v1] "=r" (value1), [v2] "=r" (value2) 27 | // : [num] "r" (num), [p1] "r" (param1), [p2] "r" (param2) 28 | // : "r0", "r1", "r2", "memory" 29 | // ); 30 | 31 | if (out1) *out1 = value1; 32 | if (out2) *out2 = value2; 33 | 34 | return 1; 35 | } 36 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/klibc/sys/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/proc.h" 3 | #include "common/include/reg.h" 4 | #include "klibc/include/stdio.h" 5 | 6 | 7 | no_opt struct thread_control_block *get_tcb() 8 | { 9 | unsigned long tcb = 0; 10 | // read_software_thread_id(tcb); 11 | 12 | return (struct thread_control_block *)tcb; 13 | } 14 | 15 | no_opt int do_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 16 | { 17 | int success = 0; 18 | unsigned long value1 = 0, value2 = 0; 19 | 20 | // __asm__ __volatile__ ( 21 | // "mov r0, %[num];" 22 | // "mov r1, %[p1];" 23 | // "mov r2, %[p2];" 24 | // "swi 0;" 25 | // "mov %[suc], r0;" 26 | // "mov %[v1], r1;" 27 | // "mov %[v2], r2;" 28 | // : [suc] "=r" (success), [v1] "=r" (value1), [v2] "=r" (value2) 29 | // : [num] "r" (num), [p1] "r" (param1), [p2] "r" (param2) 30 | // : "r0", "r1", "r2", "memory" 31 | // ); 32 | 33 | if (out1) *out1 = value1; 34 | if (out2) *out2 = value2; 35 | 36 | return 1; 37 | } 38 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/loader/hal.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | void call_hal_entry(ulong entry, ulong stack, ulong bp) 5 | { 6 | // __asm__ __volatile__ ( 7 | // // Move to System mode 8 | // "cpsid aif, #0x1f;" 9 | // 10 | // // Set up stack top 11 | // "mov sp, %[stack];" 12 | // 13 | // // Pass the argument 14 | // "mov r0, %[bp];" 15 | // 16 | // // Call C 17 | // "mov pc, %[hal];" 18 | // : 19 | // : [stack] "r" (stack), [bp] "r" (bp), [hal] "r" (entry) 20 | // : "sp", "r0", "memory" 21 | // ); 22 | } 23 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/loader/loader.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | /* QEMU loads the image to 0x10000, while a real RPi 2 load the image to 0x8000 */ 6 | . = 0x40000000; 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : 11 | { 12 | KEEP(*(.text.boot)) 13 | *(.text) 14 | } 15 | __text_end = .; 16 | 17 | __rodata_start = .; 18 | .rodata : 19 | { 20 | *(.rodata) 21 | } 22 | __rodata_end = .; 23 | 24 | __data_start = .; 25 | .data : 26 | { 27 | *(.data) 28 | } 29 | __data_end = .; 30 | 31 | __bss_start = .; 32 | .bss : 33 | { 34 | *(.bss); 35 | } 36 | __bss_end = .; 37 | 38 | /* 39 | * This makes sure two things 40 | * 1. The end of loader image is aligned to 4KB boundary 41 | * 2. The linker does not cut off the zero-byted BSS section from binary 42 | */ 43 | . = ALIGN(4096) - 1; 44 | .fill : 45 | { 46 | BYTE(0xff); 47 | } 48 | 49 | __end = .; 50 | } 51 | -------------------------------------------------------------------------------- /src/arch/arm/armv8/loader/start.S: -------------------------------------------------------------------------------- 1 | .section ".text.boot" 2 | 3 | 4 | .global _start 5 | .global _start_ap 6 | 7 | 8 | // r15 -> should begin execution at 0x8000. 9 | // r0 -> 0x00000000 10 | // r1 -> 0x00000C42 11 | // r2 -> 0x00000100 - start of ATAGS 12 | _start: 13 | // Go to C! 14 | /* ldr sp, =0x8000 // Setup the stack */ 15 | mov x0, #0xbeef 16 | b . 17 | nop 18 | b loader_entry // Call loader_entry 19 | 20 | // Should never reach here 21 | b . 22 | nop 23 | 24 | 25 | _start_ap: 26 | /* ldr sp, =0x8000 // Setup the stack */ 27 | b loader_ap_entry // Call loader_entry 28 | 29 | // Should never reach here 30 | b . 31 | nop 32 | -------------------------------------------------------------------------------- /src/arch/ia32/boot/floppy/floppy.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0x7e00; 4 | 5 | /* __start = .; 6 | 7 | __text_start = .; 8 | .text : 9 | { 10 | *(.text) 11 | } 12 | __text_end = .; 13 | 14 | __rodata_start = .; 15 | .rodata : 16 | { 17 | *(.rodata) 18 | } 19 | __rodata_end = .; 20 | 21 | __data_start = .; 22 | .data : 23 | { 24 | *(.data) 25 | } 26 | __data_end = .; 27 | 28 | __bss_start = .; 29 | .bss : 30 | { 31 | *(.bss) 32 | } 33 | __bss_end = .; 34 | 35 | __end = .;*/ 36 | 37 | .cseg : 38 | { 39 | *(.text); 40 | } 41 | 42 | .dseg : 43 | { 44 | *(rodata); 45 | } 46 | 47 | /DISCARD/ : 48 | { 49 | *(.eh_frame); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/arch/ia32/common/include/bootparam.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_COMMON_INCLUDE_BOOTPARAM__ 2 | #define __ARCH_IA32_COMMON_INCLUDE_BOOTPARAM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | struct boot_mem_zone { 9 | u64 start_paddr; 10 | u64 len; 11 | u32 type; 12 | } packedstruct; 13 | 14 | struct boot_parameters { 15 | // Boot device 16 | u32 boot_dev; 17 | u32 boot_dev_info; 18 | 19 | // Loader 20 | ulong loader_func_type_ptr; 21 | 22 | // AP and BIOS invoker 23 | ulong ap_entry_addr; 24 | ulong bios_invoker_addr; 25 | ulong ap_page_dir_pfn_ptr; 26 | ulong ap_stack_top_ptr; 27 | 28 | // HAL 29 | u32 hal_start_flag; 30 | u32 hal_entry_addr; 31 | u32 hal_vaddr_end; 32 | u32 hal_vspace_end; 33 | 34 | // Kernel 35 | u32 kernel_entry_addr; 36 | 37 | // Video info 38 | u32 video_mode; 39 | u32 framebuffer_addr; 40 | u32 res_x; 41 | u32 res_y; 42 | u32 bits_per_pixel; 43 | u32 bytes_per_line; 44 | 45 | // Cursor 46 | u32 cursor_row; 47 | u32 cursor_col; 48 | 49 | // EBDA 50 | u32 ebda_addr; 51 | 52 | // First free PFN 53 | u32 free_pfn_start; 54 | 55 | // Memory size 56 | u64 mem_size; 57 | 58 | // Memory zones 59 | u32 mem_zone_count; 60 | struct boot_mem_zone mem_zones[32]; 61 | } packedstruct; 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/arch/ia32/common/include/context.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_COMMON_INCLUDE_CONTEXT__ 2 | #define __ARCH_IA32_COMMON_INCLUDE_CONTEXT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Context 10 | */ 11 | struct context { 12 | // Manually saved/stored 13 | u32 gs; 14 | u32 fs; 15 | u32 es; 16 | u32 ds; 17 | 18 | // pushad/popad 19 | u32 edi; 20 | u32 esi; 21 | u32 ebp; 22 | u32 kernel_esp; // This field has no use, and POPAD will ignore it. It is PUSHAD that saves it automatically 23 | u32 ebx; 24 | u32 edx; 25 | u32 ecx; 26 | u32 eax; 27 | 28 | // Pushed by interrupt handler 29 | u32 vector; 30 | u32 error_code; 31 | 32 | // Pushed by HW upon an interrupt 33 | u32 eip; 34 | u32 cs; 35 | u32 eflags; 36 | u32 esp; 37 | u32 ss; 38 | } packedstruct; 39 | 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/arch/ia32/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_IA32_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifdef asmlinkage 9 | #undef asmlinkage 10 | #endif 11 | #define asmlinkage __attribute__((regparm(0))) 12 | 13 | 14 | #ifndef real_mode 15 | #ifdef __clang__ 16 | #define real_mode __attribute__((noinline)) __attribute__((regparm(3))) __attribute__((optnone)) 17 | #else 18 | #define real_mode __attribute__((noinline)) __attribute__((regparm(3))) __attribute__((optimize("-O0"))) 19 | #endif 20 | #endif 21 | 22 | 23 | #ifndef ARCH_WIDTH 24 | #define ARCH_WIDTH 32 25 | #endif 26 | 27 | #ifndef ARCH_LITTLE_ENDIAN 28 | #define ARCH_LITTLE_ENDIAN 1 29 | #endif 30 | 31 | #ifndef ARCH_BIG_ENDIAN 32 | #define ARCH_BIG_ENDIAN 0 33 | #endif 34 | 35 | 36 | #ifndef NULL 37 | #define NULL ((void *)0) 38 | #endif 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/bios/ebda.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memlayout.h" 3 | #include "hal/include/print.h" 4 | 5 | 6 | ulong ebda_phys_addr; 7 | 8 | 9 | void init_ebda() 10 | { 11 | kprintf("Extended BIOS Data Area\n"); 12 | 13 | u16 ebda_base_addr_from_eda = *((u16 *)POINTER_TO_EBDA_ADDR); 14 | ebda_phys_addr = ((ulong)ebda_base_addr_from_eda) << 4; 15 | 16 | kprintf("\tEBDA Base Address: %p\n", ebda_phys_addr); 17 | } 18 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/cpu/cpuid.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/cpu.h" 4 | 5 | 6 | static int cpuid_supported = 0; 7 | //static int vendor_type = -1; 8 | 9 | 10 | void init_cpuid() 11 | { 12 | ulong val, ret; 13 | 14 | __asm__ __volatile__ 15 | ( 16 | "pushf\n" // read flags 17 | "popl %[ret]\n" 18 | "movl %[ret], %[val]\n" 19 | 20 | "btcl $21, %[val]\n" // swap the ID bit 21 | 22 | "pushl %[val]\n" // propagate the change into flags 23 | "popf\n" 24 | "pushf\n" 25 | "popl %[val]\n" 26 | 27 | "andl $(1 << 21), %[ret]\n" // interrested only in ID bit 28 | "andl $(1 << 21), %[val]\n" 29 | "xorl %[val], %[ret]\n" 30 | : [ret] "=r" (ret), [val] "=r" (val) 31 | ); 32 | 33 | cpuid_supported = (int)ret; 34 | } 35 | 36 | 37 | int cpuid(struct cpuid_reg *reg) 38 | { 39 | if (!cpuid_supported) { 40 | return 0; 41 | } 42 | 43 | __asm__ __volatile__ 44 | ( 45 | "cpuid;" 46 | : "=a" (reg->a), "=b" (reg->b), "=c" (reg->c), "=d" (reg->d) 47 | : "a" (reg->a), "b" (reg->b), "c" (reg->c), "d" (reg->d) 48 | ); 49 | 50 | return 1; 51 | } 52 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/cpu/msr.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/cpu.h" 4 | 5 | 6 | void msr_read(ulong reg, u64* value_out) 7 | { 8 | u32* value32 = (u32*)value_out; 9 | u32 eax = 0; 10 | u32 edx = 0; 11 | 12 | __asm__ __volatile__ 13 | ( 14 | "rdmsr" 15 | : "=a" (eax), "=d" (edx) 16 | : "c" (reg) 17 | ); 18 | 19 | value32[0] = eax; 20 | value32[1] = edx; 21 | } 22 | 23 | void msr_write(ulong reg, u64* value) 24 | { 25 | u32* value32 = (u32*)value; 26 | u32 eax = value32[0]; 27 | u32 edx = value32[1]; 28 | 29 | __asm__ __volatile__ 30 | ( 31 | "wrmsr" 32 | : 33 | : "c" (reg), "a" (eax), "d" (edx) 34 | ); 35 | } 36 | 37 | void msr_timestamp(u64* value) 38 | { 39 | u32* value32 = (u32*)value; 40 | u32 eax = 0; 41 | u32 edx = 0; 42 | 43 | __asm__ __volatile__ 44 | ( 45 | "rdtsc" 46 | : "=a" (eax), "=d" (edx) 47 | : 48 | ); 49 | 50 | value32[0] = eax; 51 | value32[1] = edx; 52 | } 53 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/cpu/topo.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/lib.h" 4 | #include "hal/include/acpi.h" 5 | #include "hal/include/mps.h" 6 | #include "hal/include/cpu.h" 7 | 8 | 9 | int num_cpus = 0; 10 | 11 | 12 | void init_topo() 13 | { 14 | kprintf("Detecting processor topology\n"); 15 | 16 | if (acpi_supported && madt_supported) { 17 | num_cpus = madt_lapic_count; 18 | assert(num_cpus); 19 | } 20 | 21 | else if (mps_supported) { 22 | num_cpus = mps_lapic_count; 23 | assert(num_cpus); 24 | } 25 | 26 | else { 27 | num_cpus = 1; 28 | } 29 | 30 | kprintf("\tNumber of logical CPUs: %d\n", num_cpus); 31 | } 32 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/drv/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/context.h" 3 | #include "common/include/kdisp.h" 4 | #include "hal/include/int.h" 5 | #include "hal/include/lib.h" 6 | #include "hal/include/drv.h" 7 | 8 | 9 | #define KEYBOARD_BUF_SIZE (sizeof(ulong) * 2) 10 | #define CHECK_FLAG(flags, bit) (flags & (0x1 << bit)) 11 | 12 | 13 | static int char_count = 0; 14 | static ulong buf; 15 | 16 | 17 | static void read_scan_code() 18 | { 19 | ulong status = 0; 20 | 21 | char_count = 0; 22 | buf = 0; 23 | status = (u32)io_in8(I8042_IO_STATUS); 24 | 25 | while (CHECK_FLAG(status, I8042_STATUS_UDATA) || CHECK_FLAG(status, I8042_STATUS_KDATA)) { 26 | if (CHECK_FLAG(status, I8042_STATUS_KDATA)) { 27 | //value = io_in8(I8042_IO_BUFFER); 28 | buf <<= 8; 29 | buf |= io_in8(I8042_IO_BUFFER); 30 | char_count++; 31 | } 32 | 33 | status = io_in8(I8042_IO_STATUS); 34 | } 35 | 36 | if (char_count > sizeof(ulong)) { 37 | char_count = sizeof(ulong); 38 | } 39 | } 40 | 41 | void init_keyboard() 42 | { 43 | read_scan_code(); 44 | kprintf("Keyboard initialized\n"); 45 | } 46 | 47 | int keyboard_interrupt_handler(struct int_context *context, struct kernel_dispatch_info *kdi) 48 | { 49 | read_scan_code(); 50 | 51 | kdi->interrupt.param0 = (ulong)char_count; 52 | kdi->interrupt.param1 = buf; 53 | kdi->interrupt.param2 = 1; 54 | 55 | return 1; 56 | } 57 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/bios.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_BIOS__ 2 | #define __ARCH_IA32_HAL_INCLUDE_BIOS__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_CPU__ 2 | #define __ARCH_IA32_HAL_INCLUDE_CPU__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * CPUID 10 | */ 11 | struct cpuid_reg { 12 | ulong a; 13 | ulong b; 14 | ulong c; 15 | ulong d; 16 | }; 17 | 18 | extern void init_cpuid(); 19 | extern int cpuid(struct cpuid_reg *reg); 20 | 21 | 22 | /* 23 | * MSR 24 | */ 25 | extern void msr_read(ulong reg, u64* value_out); 26 | extern void msr_write(ulong reg, u64* value); 27 | extern void msr_timestamp(u64* value); 28 | 29 | 30 | /* 31 | * Topology 32 | */ 33 | extern int num_cpus; 34 | 35 | extern void init_topo(); 36 | 37 | 38 | /* 39 | * MP 40 | */ 41 | extern ulong tcb_padded_size; 42 | extern ulong tcb_area_size; 43 | extern ulong tcb_area_start_vaddr; 44 | 45 | extern ulong get_per_cpu_area_start_vaddr(int cpu_id); 46 | extern ulong get_my_cpu_area_start_vaddr(); 47 | 48 | extern void init_mp(); 49 | extern void bringup_mp(); 50 | extern void release_mp_lock(); 51 | 52 | extern void ap_init_started(); 53 | extern void ap_init_done(); 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/drv.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_DRV__ 2 | #define __HAL_INCLUDE_DRV__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/kdisp.h" 7 | #include "hal/include/int.h" 8 | 9 | 10 | /* 11 | * Keyboard 12 | */ 13 | // Keyboard IO ports 14 | #define I8042_IO_BUFFER 0x60 15 | #define I8042_IO_STATUS 0x64 16 | 17 | // Keyboard interface bits 18 | #define I8042_STATUS_KDATA 0 // keyboard data is in buffer (output buffer is empty) (bit 0) 19 | #define I8042_STATUS_UDATA 1 // user data is in buffer (command buffer is empty) (bit 1) 20 | 21 | // Reset CPU 22 | #define I8042_CMD_RESET 0xFE 23 | 24 | extern void init_keyboard(); 25 | extern int keyboard_interrupt_handler(struct int_context *context, struct kernel_dispatch_info *kdi); 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/exec.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_EXEC__ 2 | #define __ARCH_IA32_HAL_INCLUDE_EXEC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Copy 10 | */ 11 | extern void copy_to_user( 12 | ulong src_start, ulong len, 13 | ulong user_page_dir_pfn, ulong user_start 14 | ); 15 | 16 | 17 | /* 18 | * Load 19 | */ 20 | extern int load_elf_exe( 21 | ulong image_start, ulong dest_page_dir_pfn, 22 | ulong *entry_out, ulong *vaddr_start_out, ulong *vaddr_end_out 23 | ); 24 | 25 | extern int load_exe( 26 | ulong image_start, ulong dest_page_dir_pfn, 27 | ulong *entry_out, ulong *vaddr_start_out, ulong *vaddr_end_out 28 | ); 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_KERNEL__ 2 | #define __ARCH_IA32_HAL_INCLUDE_KERNEL__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/kexport.h" 7 | 8 | 9 | /* 10 | * Wrappers 11 | */ 12 | extern int wrap_user_map(ulong page_dir, ulong vaddr, ulong paddr, size_t size, int exec, int write, int cacheable, int override); 13 | extern int wrap_user_unmap(ulong page_dir_pfn, ulong vaddr, ulong paddr, ulong size); 14 | 15 | extern ulong wrap_get_paddr(ulong page_dir_pfn, ulong vaddr); 16 | extern int wrap_load_exe(ulong image_start, ulong dest_page_dir_pfn, 17 | ulong *entry_out, ulong *vaddr_start_out, ulong *vaddr_end_out); 18 | extern void wrap_init_addr_space(ulong page_dir_pfn); 19 | extern int wrap_get_cur_cpu_id(); 20 | 21 | extern ulong wrap_io_in(ulong port, ulong size); 22 | extern void wrap_io_out(ulong port, ulong size, ulong data); 23 | 24 | extern void wrap_invalidate_tlb(ulong asid, ulong vaddr, size_t size); 25 | 26 | extern void wrap_halt(); 27 | extern void wrap_sleep(); 28 | extern void wrap_yield(); 29 | extern ulong wrap_kget_tcb(); 30 | extern int wrap_ksyscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2); 31 | 32 | 33 | /* 34 | * Mem zone 35 | */ 36 | extern ulong paddr_space_end; 37 | 38 | extern int get_next_mem_zone(struct kernel_mem_zone *cur); 39 | extern void init_kmem_zone(); 40 | extern void full_direct_map(); 41 | 42 | /* 43 | * Init kernel 44 | */ 45 | extern struct kernel_exports *kernel; 46 | 47 | extern void init_kernel(); 48 | extern void kernel_dispatch(struct kernel_dispatch_info *kdi); 49 | 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_LIB__ 2 | #define __ARCH_IA32_HAL_INCLUDE_LIB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/bootparam.h" 7 | #include "hal/include/bit.h" 8 | #include "hal/include/string.h" 9 | #include "hal/include/debug.h" 10 | #include "hal/include/bootparam.h" 11 | 12 | 13 | /* 14 | * IO ports 15 | */ 16 | extern void io_out32(ulong port, ulong value); 17 | extern void io_out16(ulong port, ulong value); 18 | extern void io_out8(ulong port, ulong value); 19 | 20 | extern ulong io_in32(ulong port); 21 | extern ulong io_in16(ulong port); 22 | extern ulong io_in8(ulong port); 23 | 24 | 25 | /* 26 | * Bit manipulation 27 | */ 28 | extern ulong get_bits(ulong value, int low, int high); 29 | extern ulong round_up(ulong value); 30 | extern ulong round_down(ulong value); 31 | 32 | 33 | /* 34 | * Misc 35 | */ 36 | extern void no_opt halt(); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/periph.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_PERIPH__ 2 | #define __ARCH_IA32_HAL_INCLUDE_PERIPH__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | extern void draw_char(char ch); 9 | extern void init_video(); 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/include/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_IA32_HAL_INCLUDE_SYSCALL__ 2 | #define __ARCH_IA32_HAL_INCLUDE_SYSCALL__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/context.h" 7 | 8 | 9 | /* 10 | * C sysenter handler 11 | */ 12 | #define SYSENTER_MSR_CS 0x174 13 | #define SYSENTER_MSR_ESP 0x175 14 | #define SYSENTER_MSR_EIP 0x176 15 | 16 | extern u32 syscall_proxy_entry; 17 | extern void asmlinkage save_context_sysenter(struct context *context); 18 | extern void asmlinkage sysenter_handler_entry(struct context* context); 19 | extern void set_syscall_return(struct context *context, int succeed, ulong return0, ulong return1); 20 | 21 | 22 | /* 23 | * Assembly sysenter handler 24 | */ 25 | extern void sysenter_handler(); 26 | extern void sysenter_proxy_start_origin(); 27 | extern void sysenter_proxy_end_origin(); 28 | 29 | 30 | /* 31 | * General syscall 32 | */ 33 | 34 | void init_syscall_mp(); 35 | void init_syscall(); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/lib/bit2.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | ulong get_bits(ulong value, int low, int high) 5 | { 6 | ulong result = value >> low; 7 | result -= (value >> high) << high; 8 | return result; 9 | } 10 | 11 | ulong round_up(ulong value) 12 | { 13 | int i; 14 | for (i = 0; i < sizeof(ulong) * 8; i++) { 15 | ulong cur = (ulong)0x1 << i; 16 | if (cur >= value) { 17 | return cur; 18 | } 19 | } 20 | 21 | return value; 22 | } 23 | 24 | ulong round_down(ulong value) 25 | { 26 | int i; 27 | for (i = sizeof(ulong) * 8 - 1; i >= 0; i--) { 28 | ulong cur = (ulong)0x1 << i; 29 | if (cur <= value) { 30 | return cur; 31 | } 32 | } 33 | 34 | return value; 35 | } 36 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/lib/misc.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | 4 | 5 | void no_opt halt() 6 | { 7 | do { 8 | __asm__ __volatile__ 9 | ( 10 | "hlt;" 11 | : 12 | : 13 | ); 14 | } while (1); 15 | } 16 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/mem/tlb.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | #include "hal/include/mem.h" 4 | 5 | 6 | static no_opt void invalidate_tlb(ulong vaddr) 7 | { 8 | __asm__ __volatile__ 9 | ( 10 | "invlpg (%%eax);" 11 | : 12 | : "a" (vaddr) 13 | : "memory" 14 | ); 15 | } 16 | 17 | void invalidate_tlb_array(ulong vaddr, size_t size) 18 | { 19 | ulong vstart = (vaddr / PAGE_SIZE) * PAGE_SIZE; 20 | 21 | ulong page_count = size / PAGE_SIZE; 22 | if (size % PAGE_SIZE) { 23 | page_count++; 24 | } 25 | 26 | ulong i; 27 | ulong vcur = vstart; 28 | for (i = 0; i < page_count; i++) { 29 | invalidate_tlb(vcur); 30 | vcur += PAGE_SIZE; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/arch/ia32/hal/time/tick.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/time.h" 4 | 5 | 6 | void change_tick(int freq) 7 | { 8 | pit_gen_tick(freq); 9 | } 10 | 11 | void init_tick() 12 | { 13 | pit_gen_tick(TICK_FREQ); 14 | } 15 | 16 | void blocked_delay(int ms) 17 | { 18 | int loop = ms / PIT_DELAY_MAX_MS; 19 | int last = ms % PIT_DELAY_MAX_MS; 20 | 21 | int i; 22 | for (i = 0; i < loop; i++) { 23 | pit_delay(PIT_DELAY_MAX_MS); 24 | } 25 | if (last) { 26 | pit_delay(last); 27 | } 28 | } 29 | 30 | void init_blocked_delay() 31 | { 32 | kprintf("Testing blocked delay, delay for %d seconds ", BLOCKED_DELAY_TEST_SEC); 33 | 34 | int i; 35 | for (i = 0; i < BLOCKED_DELAY_TEST_SEC; i++) { 36 | blocked_delay(1000); 37 | kprintf("."); 38 | } 39 | 40 | kprintf(" Done!\n"); 41 | } 42 | -------------------------------------------------------------------------------- /src/arch/ia32/kernel/syscall/ksys_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | #define GEN_INT_INSTR(vec) "int $" #vec ";" 5 | 6 | 7 | no_opt ulong ksys_get_tcb() 8 | { 9 | unsigned long addr = 0; 10 | 11 | __asm__ __volatile__ 12 | ( 13 | "xorl %%esi, %%esi;" 14 | "movl %%gs:(%%esi), %%edi;" 15 | : "=D" (addr) 16 | : 17 | : "%esi" 18 | ); 19 | 20 | return addr; 21 | } 22 | 23 | no_opt int ksys_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 24 | { 25 | int succeed = 0; 26 | unsigned long value1 = 0, value2 = 0; 27 | 28 | __asm__ __volatile__ 29 | ( 30 | GEN_INT_INSTR(0x7f) 31 | : "=a" (succeed), "=S" (value1), "=D" (value2) 32 | : "S"(num), "D" (param1), "a" (param2) 33 | : "memory" 34 | ); 35 | 36 | if (out1) { 37 | *out1 = value1; 38 | } 39 | 40 | if (out2) { 41 | *out2 = value2; 42 | } 43 | 44 | return succeed; 45 | } 46 | -------------------------------------------------------------------------------- /src/arch/ia32/klibc/sys/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "common/include/proc.h" 4 | 5 | 6 | no_opt struct thread_control_block *get_tcb() 7 | { 8 | unsigned long addr = 0; 9 | 10 | 11 | __asm__ __volatile__ 12 | ( 13 | "xorl %%esi, %%esi;" 14 | "movl %%gs:(%%esi), %%edi;" 15 | : "=D" (addr) 16 | : 17 | : "%esi" 18 | ); 19 | 20 | return (struct thread_control_block *)addr; 21 | } 22 | 23 | no_opt int do_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 24 | { 25 | int succeed = 0; 26 | unsigned long value1 = 0, value2 = 0; 27 | 28 | __asm__ __volatile__ 29 | ( 30 | "movl %%esp, %%ecx;" 31 | "lea _sysenter_ret, %%edx;" 32 | 33 | "sysenter;" 34 | 35 | ".align 4;" 36 | "_sysenter_ret:;" 37 | : "=a" (succeed), "=S" (value1), "=D" (value2) 38 | : "S"(num), "D" (param1), "a" (param2) 39 | : "%ecx", "%edx" 40 | ); 41 | 42 | if (out1) { 43 | *out1 = value1; 44 | } 45 | 46 | if (out2) { 47 | *out2 = value2; 48 | } 49 | 50 | return 1; 51 | } 52 | -------------------------------------------------------------------------------- /src/arch/ia32/loader/protected.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0xd000; 4 | 5 | .cseg : 6 | { 7 | *(.text); 8 | } 9 | 10 | .dseg : 11 | { 12 | *(rodata); 13 | } 14 | 15 | /DISCARD/ : 16 | { 17 | *(.eh_frame); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/arch/ia32/loader/real.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0xb800; 4 | 5 | .cseg : 6 | { 7 | *(.text); 8 | } 9 | 10 | .dseg : 11 | { 12 | *(rodata); 13 | } 14 | 15 | .sig : AT(0xcffe) 16 | { 17 | SHORT(0xcffe); 18 | } 19 | 20 | /DISCARD/ : 21 | { 22 | *(.eh_frame); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/arch/mips/common/include/bootparam.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS_COMMON_INCLUDE_BOOTPARAM__ 2 | #define __ARCH_MIPS_COMMON_INCLUDE_BOOTPARAM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | #define VIDEO_NONE 0 8 | #define VIDEO_FRAMEBUFFER 1 9 | #define VIDEO_TEXT 2 10 | #define VIDEO_UART 3 11 | 12 | struct boot_mem_zone { 13 | u64 start_paddr; 14 | u64 len; 15 | u32 type; 16 | } packedstruct; 17 | 18 | struct boot_parameters { 19 | // Boot device 20 | int boot_dev; 21 | int boot_dev_info; 22 | 23 | // Loader 24 | ulong loader_func_type_ptr; 25 | 26 | // AP starter 27 | ulong ap_entry_addr; 28 | ulong ap_page_table_ptr; 29 | ulong ap_stack_top_ptr; 30 | 31 | // Core image 32 | ulong coreimg_load_addr; 33 | 34 | // HAL 35 | int hal_start_flag; 36 | ulong hal_entry_addr; 37 | ulong hal_vaddr_end; 38 | ulong hal_vspace_end; 39 | 40 | // Kernel 41 | ulong kernel_entry_addr; 42 | 43 | // Video info 44 | u32 video_mode; 45 | u32 cursor_row; 46 | u32 cursor_col; 47 | ulong framebuffer_addr; 48 | u32 res_x; 49 | u32 res_y; 50 | u32 bytes_per_pixel; 51 | u32 bytes_per_line; 52 | 53 | // Address where free memory starts 54 | ulong free_addr_start; 55 | ulong free_pfn_start; 56 | 57 | // Memory size 58 | u64 mem_size; 59 | 60 | // Memory zones 61 | int mem_zone_count; 62 | struct boot_mem_zone mem_zones[32]; 63 | } packedstruct; 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/arch/mips/common/include/context.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS_COMMON_INCLUDE_CONTEXT__ 2 | #define __ARCH_MIPS_COMMON_INCLUDE_CONTEXT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Context 10 | */ 11 | struct context { 12 | ulong zero; 13 | ulong at; 14 | ulong v0, v1; 15 | ulong a0, a1, a2, a3; 16 | ulong t0, t1, t2, t3, t4, t5, t6, t7; 17 | ulong s0, s1, s2, s3, s4, s5, s6, s7; 18 | ulong t8, t9; 19 | ulong k0, k1; 20 | ulong gp; 21 | ulong sp; 22 | ulong fp; 23 | ulong ra; 24 | 25 | ulong pc; 26 | ulong delay_slot; 27 | } packedstruct; 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/arch/mips/hal/cpu/topo.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/cpu.h" 4 | 5 | 6 | int num_cpus = 0; 7 | 8 | 9 | void init_topo() 10 | { 11 | kprintf("Detecting processor topology\n"); 12 | 13 | num_cpus = 1; 14 | 15 | kprintf("\tNumber of logical CPUs: %d\n", num_cpus); 16 | } 17 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_CPU__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_CPU__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * CPU ID 10 | */ 11 | extern void init_cpuid(); 12 | extern int read_cpu_config(int index, u32 *value); 13 | 14 | 15 | /* 16 | * Topo 17 | */ 18 | extern int num_cpus; 19 | extern void init_topo(); 20 | 21 | 22 | /* 23 | * MP 24 | */ 25 | extern int get_cpu_id(); 26 | 27 | extern ulong get_per_cpu_area_start_vaddr(int cpu_id); 28 | extern ulong get_my_cpu_area_start_vaddr(); 29 | 30 | extern void init_mp(); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_KERNEL__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_KERNEL__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/kexport.h" 7 | 8 | 9 | /* 10 | * Memory zone 11 | */ 12 | extern ulong paddr_space_end; 13 | 14 | extern int get_next_mem_zone(struct kernel_mem_zone *cur); 15 | extern void init_kmem_zone(); 16 | 17 | 18 | /* 19 | * General kernel 20 | */ 21 | extern struct kernel_exports *kernel; 22 | 23 | extern void init_kernel(); 24 | extern void kernel_dispatch(struct kernel_dispatch_info *kdi); 25 | 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_LIB__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_LIB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/bootparam.h" 7 | #include "hal/include/string.h" 8 | #include "hal/include/bit.h" 9 | #include "hal/include/debug.h" 10 | #include "hal/include/bootparam.h" 11 | 12 | 13 | /* 14 | * Debug 15 | */ 16 | extern void no_opt halt(); 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/mem.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_MEM__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_MEM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/memory.h" 7 | #include "common/include/reg.h" 8 | #include "common/include/page.h" 9 | #include "hal/include/percpu.h" 10 | #include "hal/include/cpu.h" 11 | 12 | 13 | /* 14 | * Map 15 | */ 16 | extern void init_user_page_dir(ulong page_dir_pfn); 17 | 18 | extern ulong get_paddr(ulong page_dir_pfn, ulong vaddr); 19 | 20 | extern int user_indirect_map_array( 21 | ulong page_dir_pfn, ulong vaddr, ulong paddr, size_t length, 22 | int exec, int write, int cacheable, int overwrite); 23 | extern int user_indirect_unmap_array(ulong page_dir_pfn, ulong vaddr, ulong paddr, size_t length); 24 | 25 | 26 | /* 27 | * TLB 28 | */ 29 | struct tlb_entry { 30 | struct cp0_entry_hi hi; 31 | struct cp0_page_mask pm; 32 | 33 | struct cp0_entry_lo lo0; 34 | struct cp0_entry_lo lo1; 35 | } packedstruct; 36 | 37 | ext_per_cpu(struct page_frame *, cur_page_dir); 38 | 39 | extern int tlb_refill_kernel(ulong addr); 40 | extern int tlb_refill_user(ulong addr); 41 | 42 | extern void invalidate_tlb_array(ulong asid, ulong vaddr, size_t size); 43 | 44 | extern void init_tlb(); 45 | 46 | 47 | /* 48 | * KAlloc 49 | */ 50 | extern ulong palloc(int count); 51 | extern void kfree(void *ptr); 52 | extern void *kalloc(size_t size); 53 | extern void init_kalloc(); 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/pic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_PIC__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_PIC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/kdisp.h" 7 | #include "hal/include/int.h" 8 | 9 | 10 | extern void start_working(); 11 | 12 | extern int int_handler_local_timer(struct int_context *context, struct kernel_dispatch_info *kdi); 13 | extern void enable_local_timer_interrupt(); 14 | extern void init_local_timer(); 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/time.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_TIME__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_TIME__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "hal/include/int.h" 7 | 8 | 9 | /* 10 | * Tick 11 | */ 12 | #define BLOCKED_DELAY_TEST_SEC 1 13 | #define TICK_FREQ 1 14 | 15 | extern void change_tick(int freq); 16 | extern void init_tick(); 17 | extern void blocked_delay(int ms); 18 | extern void init_blocked_delay(); 19 | 20 | 21 | /* 22 | * System time 23 | */ 24 | extern void get_system_time(unsigned long *high, unsigned long *low); 25 | extern int time_interrupt_handler(struct int_context *context, struct kernel_dispatch_info *kdi); 26 | extern void init_time(); 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/arch/mips/hal/include/vecnum.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_HAL_INCLUDE_VECNUM__ 2 | #define __ARCH_MIPS32_HAL_INCLUDE_VECNUM__ 3 | 4 | 5 | /* 6 | * Vector numbers for internal exceptions 7 | */ 8 | #define INT_VECTOR_DUMMY 0 9 | 10 | #define INT_VECTOR_TLB_READ_ONLY 1 11 | 12 | #define INT_VECTOR_TLB_MISS_READ 2 13 | #define INT_VECTOR_TLB_MISS_WRITE 3 14 | 15 | #define INT_VECTOR_ADDR_ERR_READ 4 16 | #define INT_VECTOR_ADDR_ERR_WRITE 5 17 | 18 | #define INT_VECTOR_BUS_ERR_READ 6 19 | #define INT_VECTOR_BUS_ERR_WRITE 7 20 | 21 | #define INT_VECTOR_SYSCALL 8 22 | #define INT_VECTOR_BREAK 9 23 | #define INT_VECTOR_TRAP 13 24 | 25 | #define INT_VECTOR_CP_UNUSABLE 11 26 | 27 | #define INT_VECTOR_INT_OVERFLOW 12 28 | #define INT_VECTOR_FP_EXCEPT 15 29 | #define INT_VECTOR_CP2_EXCEPT 16 30 | 31 | #define INT_VECTOR_WATCH 23 32 | #define INT_VECTOR_MACHINE_CHECK 24 33 | #define INT_VECTOR_THREAD 25 34 | 35 | #define INT_VECTOR_CACHE_ERR 30 36 | 37 | #define INT_VECTOR_INSTR_MDMX 22 38 | #define INT_VECTOR_INSTR_DSP 26 39 | 40 | /* 41 | * Vector numbers for internal interrupts 42 | */ 43 | #define INT_VECTOR_LOCAL_TIMER 32 44 | #define INT_VECTOR_PAGE_FAULT 33 45 | 46 | /* 47 | * Vector numbers for external interrupts 48 | */ 49 | #define INT_VECTOR_EXTERNAL_BASE 36 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/arch/mips/hal/kernel/dispatch.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/kdisp.h" 3 | #include "common/include/reg.h" 4 | #include "hal/include/cpu.h" 5 | #include "hal/include/int.h" 6 | #include "hal/include/kernel.h" 7 | 8 | 9 | void kernel_dispatch(struct kernel_dispatch_info *kdi) 10 | { 11 | int *user_mode = get_per_cpu(int, cur_in_user_mode); 12 | 13 | // Save user mode flag 14 | int user_mode_save = *user_mode; 15 | 16 | // Save ASID in TLB EntryHi 17 | struct cp0_entry_hi old_hi, hi; 18 | read_cp0_entry_hi(old_hi.value); 19 | 20 | // Set ASID to 0 21 | hi.value = old_hi.value; 22 | hi.asid = 0; 23 | write_cp0_entry_hi(hi.value); 24 | 25 | // FIXME: this has been set in the general int handler 26 | // Put us in kernel, so the TLB miss handler can correctly refill the entry 27 | *user_mode = 0; 28 | 29 | // FIXME 30 | // Maybe interrupts should not be enabled here at all? 31 | // We are still using the context-saving stack! 32 | // Enable interrupts 33 | // enable_local_int(); 34 | 35 | // Then call kernel dispatcher 36 | kernel->dispatch(*get_per_cpu(ulong, cur_running_sched_id), kdi); 37 | 38 | // Restore user mode flag 39 | *user_mode = user_mode_save; 40 | 41 | // Restore ASID 42 | write_cp0_entry_hi(old_hi.value); 43 | } 44 | -------------------------------------------------------------------------------- /src/arch/mips/hal/lib/debug.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/int.h" 4 | 5 | 6 | void no_opt halt() 7 | { 8 | disable_local_int(); 9 | 10 | do { 11 | __asm__ __volatile__ ( 12 | "nop;" 13 | "wait;" 14 | "nop;" 15 | ); 16 | } while (1); 17 | } 18 | -------------------------------------------------------------------------------- /src/arch/mips/hal/periph/periph.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memlayout.h" 3 | #include "hal/include/periph.h" 4 | 5 | 6 | u32 io_read32(u32 addr) 7 | { 8 | volatile u32 *ptr = (u32 *)(SEG_LOW_DIRECT + addr); 9 | return *ptr; 10 | } 11 | 12 | void io_write32(u32 addr, u32 val) 13 | { 14 | volatile u32 *ptr = (u32 *)(SEG_LOW_DIRECT + addr); 15 | *ptr = val; 16 | } 17 | 18 | u8 io_read8(u32 addr) 19 | { 20 | volatile u8 *ptr = (u8 *)(SEG_LOW_DIRECT + addr); 21 | return *ptr; 22 | } 23 | 24 | void io_write8(u32 addr, u8 val) 25 | { 26 | volatile u8 *ptr = (u8 *)(SEG_LOW_DIRECT + addr); 27 | *ptr = val; 28 | } 29 | 30 | 31 | /* 32 | * Initialization 33 | */ 34 | void init_periph() 35 | { 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/arch/mips/hal/periph/video.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/periph.h" 3 | 4 | 5 | static int is_ascii(char ch) 6 | { 7 | return ch >= 32 && ch <= 126; 8 | } 9 | 10 | 11 | void draw_char(char ch) 12 | { 13 | if (ch == '\n' || ch == '\t' || ch == '\b' || is_ascii(ch)){ 14 | uart_write(ch); 15 | } else { 16 | uart_write('?'); 17 | } 18 | 19 | // if (!is_ascii(ch)) { 20 | // return; 21 | // } 22 | // 23 | // uart_write(ch); 24 | } 25 | 26 | void init_video() 27 | { 28 | } 29 | -------------------------------------------------------------------------------- /src/arch/mips/hal/pic/pic.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/reg.h" 3 | #include "hal/include/int.h" 4 | #include "hal/include/pic.h" 5 | #include "hal/include/periph.h" 6 | 7 | 8 | void start_working() 9 | { 10 | // Enable external interrupt controller 11 | struct cp0_status sr; 12 | read_cp0_status(sr.value); 13 | 14 | sr.im2 = 1; 15 | write_cp0_status(sr.value); 16 | 17 | // Enable 8259 18 | i8259_start(); 19 | 20 | // Enable timer counter interrupt 21 | enable_local_timer_interrupt(); 22 | 23 | // Enable global interrupt 24 | enable_local_int(); 25 | } 26 | -------------------------------------------------------------------------------- /src/arch/mips/hal/pic/timer.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/kdisp.h" 3 | #include "common/include/context.h" 4 | #include "common/include/reg.h" 5 | #include "hal/include/print.h" 6 | #include "hal/include/int.h" 7 | 8 | 9 | static u32 timer_step = 0; 10 | 11 | 12 | static void update_compare() 13 | { 14 | u32 count = 0; 15 | read_cp0_count(count); 16 | 17 | count += timer_step; 18 | write_cp0_compare(count); 19 | 20 | //kprintf("New count: %x\n", count); 21 | } 22 | 23 | int int_handler_local_timer(struct int_context *context, struct kernel_dispatch_info *kdi) 24 | { 25 | //kprintf("Timer!\n"); 26 | 27 | // Set a new value for compare 28 | update_compare(); 29 | 30 | // Can be taken over 31 | return INT_HANDLE_TYPE_TAKEOVER; 32 | } 33 | 34 | void enable_local_timer_interrupt() 35 | { 36 | // Set a new value for compare 37 | update_compare(); 38 | } 39 | 40 | void init_local_timer() 41 | { 42 | // 1G / 10 / 2 = 1,000,000,000 / 10 / 2 = 0x2FAF080 43 | timer_step = 0x2FAF080 / 10; 44 | 45 | set_int_vector(INT_VECTOR_LOCAL_TIMER, int_handler_local_timer); 46 | } 47 | -------------------------------------------------------------------------------- /src/arch/mips/hal/time/tick.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/periph.h" 4 | #include "hal/include/time.h" 5 | 6 | 7 | void change_tick(int freq) 8 | { 9 | pit_gen_tick(freq); 10 | } 11 | 12 | void init_tick() 13 | { 14 | pit_gen_tick(TICK_FREQ); 15 | } 16 | 17 | void blocked_delay(int ms) 18 | { 19 | int loop = ms / I8253_DELAY_MAX_MS; 20 | int last = ms % I8253_DELAY_MAX_MS; 21 | 22 | int i; 23 | for (i = 0; i < loop; i++) { 24 | pit_delay(I8253_DELAY_MAX_MS); 25 | } 26 | if (last) { 27 | pit_delay(last); 28 | } 29 | } 30 | 31 | void init_blocked_delay() 32 | { 33 | kprintf("Testing blocked delay, delay for %d seconds ", BLOCKED_DELAY_TEST_SEC); 34 | 35 | int i; 36 | for (i = 0; i < BLOCKED_DELAY_TEST_SEC; i++) { 37 | blocked_delay(1000); 38 | kprintf("."); 39 | } 40 | 41 | kprintf(" Done!\n"); 42 | } 43 | -------------------------------------------------------------------------------- /src/arch/mips/kernel/syscall/ksys_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | #include "common/include/reg.h" 4 | 5 | 6 | no_opt ulong ksys_get_tcb() 7 | { 8 | unsigned long k1 = 0; 9 | 10 | // k1 - $27 11 | read_k1(k1); 12 | 13 | // Convert k1 to unmapped address so we don't get TLB miss on this 14 | k1 = PHYS_TO_KCODE(k1); 15 | 16 | return k1; 17 | } 18 | 19 | no_opt int ksys_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 20 | { 21 | int succeed = 0; 22 | unsigned long value1 = 0, value2 = 0; 23 | 24 | // v0 -> $2 25 | // a0-a3 -> $4-$7 26 | __asm__ __volatile__ ( 27 | "move $2, %[num];" 28 | "move $4, %[p1];" 29 | "move $5, %[p2];" 30 | "syscall;" 31 | "nop;" 32 | "move %[suc], $2;" 33 | "move %[val1], $4;" 34 | "move %[val2], $5;" 35 | : [suc] "=r" (succeed), [val1] "=r" (value1), [val2] "=r" (value2) 36 | : [num] "r" (num), [p1] "r" (param1), [p2] "r" (param2) 37 | : "$2", "$4", "$5", "$6" 38 | ); 39 | 40 | if (out1) { 41 | *out1 = value1; 42 | } 43 | 44 | if (out2) { 45 | *out2 = value2; 46 | } 47 | 48 | return 1; 49 | } 50 | -------------------------------------------------------------------------------- /src/arch/mips/klibc/klibc.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0x810000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(.text) 11 | } 12 | __text_end = .; 13 | 14 | .reginfo : { 15 | *(.reginfo) 16 | } 17 | 18 | __rodata_start = .; 19 | .rodata : 20 | { 21 | *(.rodata) 22 | } 23 | __rodata_end = .; 24 | 25 | __data_start = .; 26 | .data : 27 | { 28 | *(.data) 29 | } 30 | __data_end = .; 31 | 32 | __bss_start = .; 33 | .bss : { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | -------------------------------------------------------------------------------- /src/arch/mips/klibc/sys/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/proc.h" 3 | #include "common/include/reg.h" 4 | 5 | 6 | no_opt struct thread_control_block *get_tcb() 7 | { 8 | unsigned long k1 = 0; 9 | 10 | // k1 - $27 11 | read_k1(k1); 12 | 13 | return (struct thread_control_block *)k1; 14 | } 15 | 16 | 17 | no_opt int do_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 18 | { 19 | int succeed = 0; 20 | unsigned long value1 = 0, value2 = 0; 21 | 22 | // v0 -> $2 23 | // a0-a3 -> $4-$7 24 | __asm__ __volatile__ ( 25 | "move $2, %[num];" 26 | "move $4, %[p1];" 27 | "move $5, %[p2];" 28 | "syscall;" 29 | "nop;" 30 | "move %[suc], $2;" 31 | "move %[val1], $4;" 32 | "move %[val2], $5;" 33 | : [suc] "=r" (succeed), [val1] "=r" (value1), [val2] "=r" (value2) 34 | : [num] "r" (num), [p1] "r" (param1), [p2] "r" (param2) 35 | : "$2", "$4", "$5", "$6" 36 | ); 37 | 38 | if (out1) { 39 | *out1 = value1; 40 | } 41 | 42 | if (out2) { 43 | *out2 = value2; 44 | } 45 | 46 | return 1; 47 | } 48 | -------------------------------------------------------------------------------- /src/arch/mips/loader/periph.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_LOADER_PERIPH_HH__ 2 | #define __ARCH_MIPS32_LOADER_PERIPH_HH__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/memlayout.h" 7 | 8 | 9 | /* 10 | * Argument 11 | */ 12 | typedef __builtin_va_list va_list; 13 | #define va_start(ap, last) __builtin_va_start(ap, last) 14 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 15 | #define va_end(ap) __builtin_va_end(ap) 16 | 17 | 18 | /* 19 | * UART 20 | * UART0 @ 0x180003f8 21 | * UART2 @ 0x1f000900 22 | */ 23 | #define UART_BASE_ADDR (SOUTH_BRIDGE_BASE_ADDR + 0x3f8) 24 | #define UART_DATA_ADDR (UART_BASE_ADDR + 0x0) 25 | #define UART_INT_ENABLE_ADDR (UART_BASE_ADDR + 0x8) 26 | #define UART_INT_ID_FIFO_ADDR (UART_BASE_ADDR + 0x10) 27 | #define UART_LINE_CTRL_ADDR (UART_BASE_ADDR + 0x18) 28 | #define UART_MODEM_CTRL_ADDR (UART_BASE_ADDR + 0x20) 29 | #define UART_LINE_STAT_ADDR (UART_BASE_ADDR + 0x28) 30 | #define UART_MODEM_STAT_ADDR (UART_BASE_ADDR + 0x30) 31 | #define UART_SCRATCH_ADDR (UART_BASE_ADDR + 0x38) 32 | 33 | #define UART_DIV_LSB_ADDR (UART_BASE_ADDR + 0x0) 34 | #define UART_DIV_MSB_ADDR (UART_BASE_ADDR + 0x8) 35 | 36 | #define UART_MAX_BAUD 1152000 37 | 38 | 39 | 40 | /* 41 | * Functions 42 | */ 43 | extern void uart_init(); 44 | extern char uart_read(); 45 | extern void uart_write(char ch); 46 | 47 | extern void lprintf(char *fmt, ...); 48 | 49 | extern void scan_area(ulong start, ulong len); 50 | 51 | extern void init_periph(); 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/arch/mips/loader/start.S: -------------------------------------------------------------------------------- 1 | #include "common/include/asm.h" 2 | #include "common/include/memlayout.h" 3 | 4 | 5 | LEAF(_start) 6 | .set noreorder 7 | 8 | // Disable watch exception 9 | mtc0 zero, CP0_WATCHLO 10 | mtc0 zero, CP0_WATCHHI 11 | 12 | // Disable kseg0 cache 13 | mfc0 t0, CP0_CONFIG 14 | and t0, ~0x7 15 | ori t0, 0x2 16 | mtc0 t0, CP0_CONFIG 17 | 18 | // Set up stack 19 | li sp, SEG_LOW_CACHED + LOADER_STACK_TOP - 0x10 20 | 21 | // Jump to loader entry 22 | jal loader_entry 23 | nop 24 | 25 | // Should never reach here 26 | stop: 27 | j stop 28 | nop 29 | 30 | END(_start) 31 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/common/include/memlayout.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_COMMON_INCLUDE_MEMLAYOUT__ 2 | #define __ARCH_MIPS32_COMMON_INCLUDE_MEMLAYOUT__ 3 | 4 | 5 | #include "common/include/memory.h" 6 | 7 | 8 | /* 9 | * Segment 10 | */ 11 | #define SEG_USER 0x0 12 | #define SEG_LOW_CACHED 0x80000000 13 | #define SEG_LOW_DIRECT 0xa0000000 14 | #define SEG_KERNEL 0xc0000000 15 | 16 | 17 | /* 18 | * Physical memory window 19 | */ 20 | #define SEG_CACHED 0x80000000 21 | #define SEG_DIRECT 0xa0000000 22 | 23 | 24 | /* 25 | * PIIX4 south bridge 26 | */ 27 | #define SOUTH_BRIDGE_BASE_ADDR 0x18000000 28 | 29 | 30 | /* 31 | * Loader 32 | */ 33 | #define LOADER_STACK_TOP 0x10000 // 64KB 34 | 35 | 36 | /* 37 | * HAL 38 | */ 39 | #define HAL_VSPACE_END 0x80180000 40 | 41 | #define HAL_STACK_TOP_OFFSET (0x11000 - 0x10) 42 | #define HAL_STACK_TOP_ADDR (SEG_LOW_CACHED + HAL_STACK_TOP_OFFSET) 43 | 44 | #define PER_CPU_AREA_PAGE_COUNT (2) 45 | #define PER_CPU_AREA_SIZE (PAGE_SIZE * PER_CPU_AREA_PAGE_COUNT) 46 | #define PER_CPU_DATA_START_OFFSET (0) 47 | #define PER_CPU_TLB_REFILL_STACK_TOP_OFFSET (PER_CPU_AREA_SIZE - PAGE_SIZE - 0x10) 48 | #define PER_CPU_STACK_TOP_OFFSET (PER_CPU_AREA_SIZE - 0x10) 49 | 50 | #define THREAD_CTRL_BLOCK_ALIGNMENT (64) 51 | 52 | 53 | /* 54 | * User address space 55 | */ 56 | #define USER_VADDR_SPACE_END 0x7f000000 57 | 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/common/include/page.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32_COMMON_INCLUDE_PAGE__ 2 | #define __ARCH_MIPS32_COMMON_INCLUDE_PAGE__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Page 10 | */ 11 | struct pde { 12 | u32 present : 1; 13 | u32 write_allow : 1; 14 | u32 exec_allow : 1; 15 | u32 cache_allow : 1; 16 | u32 reserved : 8; 17 | u32 pfn : 20; 18 | } packedstruct; 19 | 20 | struct pte { 21 | u32 present : 1; 22 | u32 write_allow : 1; 23 | u32 exec_allow : 1; 24 | u32 cache_allow : 1; 25 | u32 reserved : 8; 26 | u32 pfn : 20; 27 | } packedstruct; 28 | 29 | struct page_frame { 30 | union { 31 | u8 value_u8[4096]; 32 | u32 value_u32[1024]; 33 | 34 | struct pde value_pde[1024]; 35 | struct pte value_pte[1024]; 36 | }; 37 | } packedstruct; 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/hal/hal.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0x80110000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(entry); 11 | *(.text); 12 | } 13 | __text_end = .; 14 | 15 | .reginfo : { 16 | *(.reginfo) 17 | } 18 | 19 | __rodata_start = .; 20 | .rodata : 21 | { 22 | *(.rodata) 23 | } 24 | __rodata_end = .; 25 | 26 | __data_start = .; 27 | .data : 28 | { 29 | *(.data) 30 | } 31 | __data_end = .; 32 | 33 | __bss_start = .; 34 | .bss : { 35 | *(.bss) 36 | } 37 | __bss_end = .; 38 | 39 | __end = .; 40 | } 41 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/hal/int/restore.S: -------------------------------------------------------------------------------- 1 | #include "common/include/asm.h" 2 | 3 | 4 | .set noreorder 5 | .set noat 6 | 7 | .global restore_context_gpr 8 | 9 | restore_context_gpr: 10 | //lw zero, 0(k0) 11 | lw AT, 4(k0) 12 | lw v0, 8(k0) 13 | lw v1, 12(k0) 14 | lw a0, 16(k0) 15 | lw a1, 20(k0) 16 | lw a2, 24(k0) 17 | lw a3, 28(k0) 18 | lw t0, 32(k0) 19 | lw t1, 36(k0) 20 | lw t2, 40(k0) 21 | lw t3, 44(k0) 22 | lw t4, 48(k0) 23 | lw t5, 52(k0) 24 | lw t6, 56(k0) 25 | lw t7, 60(k0) 26 | lw t8, 64(k0) 27 | lw t9, 68(k0) 28 | lw s0, 72(k0) 29 | lw s1, 76(k0) 30 | lw s2, 80(k0) 31 | lw s3, 84(k0) 32 | lw s4, 88(k0) 33 | lw s5, 92(k0) 34 | lw s6, 96(k0) 35 | lw s7, 100(k0) 36 | //lw k0, 104(k0) 37 | //lw k1, 108(k0) 38 | lw gp, 112(k0) 39 | lw sp, 116(k0) 40 | lw fp, 120(k0) 41 | lw ra, 124(k0) 42 | 43 | eret 44 | nop 45 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0x80182000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(.text) 11 | } 12 | __text_end = .; 13 | 14 | .reginfo : { 15 | *(.reginfo) 16 | } 17 | 18 | __rodata_start = .; 19 | .rodata : 20 | { 21 | *(.rodata) 22 | } 23 | __rodata_end = .; 24 | 25 | __data_start = .; 26 | .data : 27 | { 28 | *(.data) 29 | } 30 | __data_end = .; 31 | 32 | __bss_start = .; 33 | .bss : { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/loader/loader.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0x80010000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(.text) 11 | } 12 | __text_end = .; 13 | 14 | .reginfo : { 15 | *(.reginfo) 16 | } 17 | 18 | __rodata_start = .; 19 | .rodata : 20 | { 21 | *(.rodata) 22 | } 23 | __rodata_end = .; 24 | 25 | __data_start = .; 26 | .data : 27 | { 28 | *(.data) 29 | } 30 | __data_end = .; 31 | 32 | __bss_start = .; 33 | .bss : { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/mips32b/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32B_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_MIPS32B_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 32 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 0 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 1 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/mips32b/tmake.arch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | globals()['mips_endian_prefix'] = 'mips' 5 | 6 | include(arch_dir_map['mips32'] + 'tmake.inc') 7 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/mips32l/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS32L_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_MIPS32L_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 32 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 1 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 0 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/mips/mips32/mips32l/tmake.arch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | globals()['mips_endian_prefix'] = 'mipsel' 5 | 6 | include(arch_dir_map['mips32'] + 'tmake.inc') 7 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/common/include/memlayout.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS64_COMMON_INCLUDE_MEMLAYOUT__ 2 | #define __ARCH_MIPS64_COMMON_INCLUDE_MEMLAYOUT__ 3 | 4 | 5 | #include "common/include/memory.h" 6 | 7 | 8 | /* 9 | * Segment 10 | */ 11 | #define SEG_USER 0x0 12 | #define SEG_LOW_CACHED 0xffffffff80000000ul 13 | #define SEG_LOW_DIRECT 0xffffffffa0000000ul 14 | #define SEG_KERNEL 0xc0000000 15 | 16 | 17 | /* 18 | * Physical memory window 19 | */ 20 | #define SEG_CACHED 0x9000000000000000ul 21 | #define SEG_DIRECT 0x9800000000000000ul 22 | 23 | 24 | /* 25 | * Loader 26 | */ 27 | #define LOADER_STACK_TOP 0x10000 // 64KB 28 | 29 | 30 | /* 31 | * PIIX4 south bridge 32 | */ 33 | #define SOUTH_BRIDGE_BASE_ADDR 0x18000000ul 34 | 35 | 36 | /* 37 | * HAL 38 | */ 39 | #define HAL_VSPACE_END 0xffffffff80180000ul 40 | 41 | #define HAL_STACK_TOP_OFFSET (0x11000 - 0x10) 42 | #define HAL_STACK_TOP_ADDR (SEG_LOW_CACHED + HAL_STACK_TOP_OFFSET) 43 | 44 | #define PER_CPU_AREA_PAGE_COUNT (2) 45 | #define PER_CPU_AREA_SIZE (PAGE_SIZE * PER_CPU_AREA_PAGE_COUNT) 46 | #define PER_CPU_DATA_START_OFFSET (0) 47 | #define PER_CPU_TLB_REFILL_STACK_TOP_OFFSET (PER_CPU_AREA_SIZE - PAGE_SIZE - 0x10) 48 | #define PER_CPU_STACK_TOP_OFFSET (PER_CPU_AREA_SIZE - 0x10) 49 | 50 | #define THREAD_CTRL_BLOCK_ALIGNMENT (64) 51 | 52 | 53 | /* 54 | * User address space 55 | */ 56 | #define USER_VADDR_SPACE_END 0x7f000000 57 | 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/common/include/page.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS64_COMMON_INCLUDE_PAGE__ 2 | #define __ARCH_MIPS64_COMMON_INCLUDE_PAGE__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/memory.h" 7 | 8 | 9 | /* 10 | * Page 11 | */ 12 | struct page_table_entry { 13 | union { 14 | struct { 15 | u64 present : 1; 16 | u64 read_allow : 1; 17 | u64 write_allow : 1; 18 | u64 exec_allow : 1; 19 | u64 cache_allow : 1; 20 | u64 has_next_level : 1; 21 | u64 reserved : 6; 22 | u64 pfn : 52; 23 | }; 24 | 25 | u64 value; 26 | }; 27 | } packedstruct; 28 | 29 | struct page_frame { 30 | union { 31 | u8 bytes[PAGE_SIZE]; 32 | struct page_table_entry entries[PAGE_SIZE / sizeof(struct page_table_entry)]; 33 | }; 34 | } packedstruct; 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/hal/hal.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xffffffff80110000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(entry); 11 | *(.text); 12 | } 13 | __text_end = .; 14 | 15 | .reginfo : { 16 | *(.reginfo) 17 | } 18 | 19 | __rodata_start = .; 20 | .rodata : 21 | { 22 | *(.rodata) 23 | } 24 | __rodata_end = .; 25 | 26 | __data_start = .; 27 | .data : 28 | { 29 | *(.data) 30 | } 31 | __data_end = .; 32 | 33 | __bss_start = .; 34 | .bss : { 35 | *(.bss) 36 | } 37 | __bss_end = .; 38 | 39 | __end = .; 40 | } 41 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/hal/int/restore.S: -------------------------------------------------------------------------------- 1 | #include "common/include/asm.h" 2 | 3 | 4 | .set noreorder 5 | .set noat 6 | 7 | .global restore_context_gpr 8 | 9 | restore_context_gpr: 10 | //ld zero, 0(k0) 11 | ld AT, 8(k0) 12 | ld v0, 16(k0) 13 | ld v1, 24(k0) 14 | ld a0, 32(k0) 15 | ld a1, 40(k0) 16 | ld a2, 48(k0) 17 | ld a3, 56(k0) 18 | ld t0, 64(k0) 19 | ld t1, 72(k0) 20 | ld t2, 80(k0) 21 | ld t3, 88(k0) 22 | ld t4, 96(k0) 23 | ld t5, 104(k0) 24 | ld t6, 112(k0) 25 | ld t7, 120(k0) 26 | ld t8, 128(k0) 27 | ld t9, 136(k0) 28 | ld s0, 144(k0) 29 | ld s1, 152(k0) 30 | ld s2, 160(k0) 31 | ld s3, 168(k0) 32 | ld s4, 176(k0) 33 | ld s5, 184(k0) 34 | ld s6, 192(k0) 35 | ld s7, 200(k0) 36 | //ld k0, 208(k0) 37 | //ld k1, 216(k0) 38 | ld gp, 224(k0) 39 | ld sp, 232(k0) 40 | ld fp, 240(k0) 41 | ld ra, 248(k0) 42 | 43 | eret 44 | nop 45 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xffffffff80182000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(.text) 11 | } 12 | __text_end = .; 13 | 14 | .reginfo : { 15 | *(.reginfo) 16 | } 17 | 18 | __rodata_start = .; 19 | .rodata : 20 | { 21 | *(.rodata) 22 | } 23 | __rodata_end = .; 24 | 25 | __data_start = .; 26 | .data : 27 | { 28 | *(.data) 29 | } 30 | __data_end = .; 31 | 32 | __bss_start = .; 33 | .bss : { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/loader/loader.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xffffffff80010000; 6 | __start = .; 7 | 8 | __text_start = .; 9 | .text : { 10 | *(.text) 11 | } 12 | __text_end = .; 13 | 14 | .reginfo : { 15 | *(.reginfo) 16 | } 17 | 18 | __rodata_start = .; 19 | .rodata : 20 | { 21 | *(.rodata) 22 | } 23 | __rodata_end = .; 24 | 25 | __data_start = .; 26 | .data : 27 | { 28 | *(.data) 29 | } 30 | __data_end = .; 31 | 32 | __bss_start = .; 33 | .bss : { 34 | *(.bss) 35 | } 36 | __bss_end = .; 37 | 38 | __end = .; 39 | } 40 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/mips64b/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS64B_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_MIPS64B_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 64 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 0 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 1 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/mips64b/tmake.arch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | globals()['mips_endian_prefix'] = 'mips64' 5 | 6 | include(arch_dir_map['mips64'] + 'tmake.inc') 7 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/mips64l/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_MIPS64L_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_MIPS64L_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 64 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 1 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 0 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/mips/mips64/mips64l/tmake.arch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | globals()['mips_endian_prefix'] = 'mips64el' 5 | 6 | include(arch_dir_map['mips64'] + 'tmake.inc') 7 | -------------------------------------------------------------------------------- /src/arch/ppc32/common/include/context.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_COMMON_INCLUDE_CONTEXT__ 2 | #define __ARCH_PPC32_COMMON_INCLUDE_CONTEXT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Context 10 | */ 11 | struct context { 12 | u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; 13 | u32 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; 14 | u32 r20, r21, r22, r23, r24, r25, r26, r27, r28, r29; 15 | u32 r30, r31; 16 | u32 lr, cr, ctr, xer, msr, pc; 17 | } packedstruct; 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/arch/ppc32/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_PPC32_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 32 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 0 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 1 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/cpu/topo.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/cpu.h" 4 | 5 | 6 | int num_cpus = 0; 7 | 8 | 9 | void init_topo() 10 | { 11 | kprintf("Detecting processor topology\n"); 12 | 13 | num_cpus = 1; 14 | 15 | kprintf("\tNumber of logical CPUs: %d\n", num_cpus); 16 | } 17 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/hal.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/bootparam.h" 3 | #include "hal/include/lib.h" 4 | #include "hal/include/periph.h" 5 | #include "hal/include/print.h" 6 | #include "hal/include/mem.h" 7 | #include "hal/include/cpu.h" 8 | #include "hal/include/vector.h" 9 | #include "hal/include/int.h" 10 | #include "hal/include/kernel.h" 11 | #include "hal/include/time.h" 12 | 13 | 14 | void entry_func hal_entry(struct boot_parameters *boot_param) 15 | { 16 | init_bootparam(boot_param); 17 | init_print(); 18 | kprintf("We are in HAL!\n"); 19 | 20 | // Init memory management 21 | init_pht(); 22 | init_map(); 23 | init_kalloc(); 24 | 25 | // Init Periph 26 | init_periph(); 27 | 28 | // Init OFW 29 | // init_ofw(); 30 | 31 | // Init CPU 32 | init_cpuid(); 33 | init_topo(); 34 | init_mp(); 35 | 36 | // Init interrupt 37 | init_int_vector(); 38 | init_int(); 39 | init_syscall(); 40 | init_pagefault(); 41 | 42 | // Init kernel 43 | init_kmem_zone(); 44 | init_kernel(); 45 | 46 | // Init timer 47 | init_decrementer(); 48 | 49 | // Start working 50 | kprintf("Will start working!\n"); 51 | start_working(); 52 | 53 | // Should not reach here 54 | // halt(); 55 | while (1); 56 | } 57 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/hal.ld: -------------------------------------------------------------------------------- 1 | ENTRY(hal_entry) 2 | 3 | SECTIONS 4 | { 5 | . = 0xFFF88000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : { 11 | *(entry); 12 | *(.text); 13 | } 14 | __text_end = .; 15 | 16 | __rodata_start = .; 17 | .rodata : 18 | { 19 | *(.rodata) 20 | } 21 | __rodata_end = .; 22 | 23 | __data_start = .; 24 | .data : 25 | { 26 | *(.data) 27 | } 28 | __data_end = .; 29 | 30 | __bss_start = .; 31 | .bss : { 32 | *(.bss) 33 | } 34 | __bss_end = .; 35 | 36 | __end = .; 37 | } 38 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/include/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_HAL_INCLUDE_CPU__ 2 | #define __ARCH_PPC32_HAL_INCLUDE_CPU__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * CPU ID 10 | */ 11 | struct cpu_prop { 12 | int dcache_size, icache_size; 13 | int dcache_sets, icache_sets; 14 | int dcache_block_size, icache_block_size; 15 | 16 | int tlb_sets, tlb_size; 17 | 18 | ulong freq_base, freq_clock, freq_bus; 19 | }; 20 | 21 | struct pvr_record { 22 | ulong pvr; 23 | char *class; 24 | char *model; 25 | char *rev; 26 | }; 27 | 28 | extern struct cpu_prop cpu_info; 29 | 30 | extern void init_cpuid(); 31 | 32 | 33 | /* 34 | * Topo 35 | */ 36 | extern int num_cpus; 37 | extern void init_topo(); 38 | 39 | 40 | /* 41 | * MP 42 | */ 43 | extern int get_cpu_id(); 44 | 45 | extern ulong get_per_cpu_area_start_paddr(int cpu_id); 46 | extern ulong get_my_cpu_area_start_paddr(); 47 | 48 | extern ulong get_per_cpu_area_start_vaddr(int cpu_id); 49 | extern ulong get_my_cpu_area_start_vaddr(); 50 | 51 | extern void init_mp(); 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/include/kernel.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_HAL_INCLUDE_KERNEL__ 2 | #define __ARCH_PPC32_HAL_INCLUDE_KERNEL__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/kexport.h" 7 | 8 | 9 | /* 10 | * Memory zone 11 | */ 12 | extern ulong paddr_space_end; 13 | 14 | extern int get_next_mem_zone(struct kernel_mem_zone *cur); 15 | extern void init_kmem_zone(); 16 | 17 | 18 | /* 19 | * General kernel 20 | */ 21 | extern struct kernel_exports *kernel; 22 | 23 | extern void init_kernel(); 24 | extern void kernel_dispatch(struct kernel_dispatch_info *kdi); 25 | 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_HAL_INCLUDE_LIB__ 2 | #define __ARCH_PPC32_HAL_INCLUDE_LIB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/bootparam.h" 7 | #include "hal/include/string.h" 8 | #include "hal/include/bit.h" 9 | #include "hal/include/bootparam.h" 10 | 11 | 12 | /* 13 | * Debug 14 | */ 15 | extern void halt(); 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/include/time.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_HAL_INCLUDE_TIME__ 2 | #define __ARCH_PPC32_HAL_INCLUDE_TIME__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "hal/include/int.h" 7 | 8 | 9 | /* 10 | * Decrementer 11 | */ 12 | extern void init_decrementer(); 13 | 14 | 15 | /* 16 | * System time 17 | */ 18 | extern void get_system_time(unsigned long *high, unsigned long *low); 19 | // extern int time_interrupt_handler(struct int_context *context, struct kernel_dispatch_info *kdi); 20 | // extern void init_time(); 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/include/vecnum.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_HAL_INCLUDE_VECNUM__ 2 | #define __ARCH_PPC32_HAL_INCLUDE_VECNUM__ 3 | 4 | 5 | /* 6 | * Vector numbers for internal exceptions 7 | */ 8 | #define INT_VECTOR_DUMMY 0 9 | 10 | #define INT_VECTOR_DSI 3 11 | #define INT_VECTOR_ISI 4 12 | #define INT_VECTOR_EXTERNAL 5 13 | #define INT_VECTOR_PROGRAM 7 14 | #define INT_VECTOR_DECREMENTER 10 15 | #define INT_VECTOR_SYSCALL 11 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/int/work.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/int.h" 3 | #include "hal/include/periph.h" 4 | 5 | 6 | /* 7 | * Start working 8 | */ 9 | volatile int work_started = 0; 10 | 11 | 12 | /* 13 | * Start working 14 | */ 15 | void start_working() 16 | { 17 | work_started = 1; 18 | 19 | start_periph(); 20 | 21 | __asm__ __volatile__ ( 22 | "sync;" 23 | ); 24 | 25 | enable_local_int(); 26 | } 27 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/kernel/dispatch.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/kdisp.h" 3 | #include "hal/include/cpu.h" 4 | #include "hal/include/int.h" 5 | #include "hal/include/percpu.h" 6 | #include "hal/include/kernel.h" 7 | 8 | 9 | void kernel_dispatch(struct kernel_dispatch_info *kdi) 10 | { 11 | int *user_mode = get_per_cpu(int, cur_in_user_mode); 12 | 13 | // Save user mode flag 14 | int user_mode_save = *user_mode; 15 | 16 | // // Save ASID in TLB EntryHi 17 | // u32 hi = 0; 18 | // u32 asid = 0; 19 | // __asm__ __volatile__ ( 20 | // "mfc0 %0, $10;" 21 | // : "=r" (hi) 22 | // : 23 | // ); 24 | // asid = hi & 0xff; 25 | // hi &= ~0xff; 26 | // __asm__ __volatile__ ( 27 | // "mtc0 %0, $10;" 28 | // : 29 | // : "r" (hi) 30 | // ); 31 | 32 | // Put us in kernel, so the TLB miss handler can correctly refill the entry 33 | *user_mode = 0; 34 | 35 | // Then call kernel dispatcher 36 | kernel->dispatch(*get_per_cpu(ulong, cur_running_sched_id), kdi); 37 | 38 | // Restore user mode flag 39 | *user_mode = user_mode_save; 40 | 41 | // // Restore ASID 42 | // hi |= asid & 0xff; 43 | // __asm__ __volatile__ ( 44 | // "mtc0 %0, $10;" 45 | // : 46 | // : "r" (hi) 47 | // ); 48 | } 49 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/lib/debug.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/int.h" 4 | 5 | 6 | void no_opt halt() 7 | { 8 | disable_local_int(); 9 | 10 | __asm__ __volatile__ ( 11 | "xor 3, 3, 3;" 12 | "addi 3, 3, 0xbe;" 13 | 14 | "xor 4, 4, 4;" 15 | "addi 4, 4, 0xef;" 16 | ); 17 | 18 | while (1); 19 | } 20 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/mem/tlb.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/lib.h" 3 | #include "hal/include/mem.h" 4 | 5 | 6 | static no_opt void invalidate_tlb(ulong asid, ulong vaddr) 7 | { 8 | // kprintf("TLB shootdown @ %x, ASID: %x ...", vaddr, asid); 9 | 10 | evict_pht(asid, vaddr); 11 | 12 | __asm__ __volatile__ 13 | ( 14 | "tlbie %[addr];" 15 | "eieio;" 16 | "tlbsync;" 17 | "sync;" 18 | : 19 | : [addr]"r"(vaddr) 20 | ); 21 | } 22 | 23 | void invalidate_tlb_array(ulong asid, ulong vaddr, size_t size) 24 | { 25 | ulong vstart = ALIGN_DOWN(vaddr, PAGE_SIZE); 26 | ulong vend = ALIGN_UP(vaddr + size, PAGE_SIZE); 27 | ulong page_count = (vend - vstart) >> PAGE_BITS; 28 | 29 | // kprintf("Invalidate TLB array, vaddr @ %lx, size: %lx, vstart @ %lx, vend @ %lx, pages: %lx\n", 30 | // vaddr, size, vstart, vend, page_count 31 | // ); 32 | 33 | ulong i; 34 | ulong vcur = vstart; 35 | for (i = 0; i < page_count; i++) { 36 | invalidate_tlb(asid, vcur); 37 | vcur += PAGE_SIZE; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/time/tick.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/lib.h" 4 | #include "hal/include/cpu.h" 5 | #include "hal/include/vector.h" 6 | #include "hal/include/int.h" 7 | #include "hal/include/vecnum.h" 8 | 9 | 10 | #define TICK_FREQ 20 11 | 12 | 13 | static ulong decrementer_value = 0; 14 | 15 | 16 | static void restart_decrementer() 17 | { 18 | __asm__ __volatile__ 19 | ( 20 | "mtdec %[dec];" 21 | : 22 | : [dec]"r"(decrementer_value) 23 | ); 24 | } 25 | 26 | static ulong read_decrementer() 27 | { 28 | ulong dec = 0; 29 | 30 | __asm__ __volatile__ 31 | ( 32 | "mfdec %[dec];" 33 | : [dec]"=r"(dec) 34 | : 35 | ); 36 | 37 | return dec; 38 | } 39 | 40 | static int int_handler_decrementer(struct int_context *context, struct kernel_dispatch_info *kdi) 41 | { 42 | // kprintf("Timer @ %p!\n",(void *)read_decrementer()); 43 | 44 | // Restart the decrementer 45 | restart_decrementer(); 46 | 47 | // Can be taken over 48 | return INT_HANDLE_TYPE_TAKEOVER; 49 | } 50 | 51 | void init_decrementer() 52 | { 53 | decrementer_value = cpu_info.freq_base / TICK_FREQ; 54 | kprintf("Decrementer set to %p, tick frequency: %d\n", (void *)decrementer_value, TICK_FREQ); 55 | 56 | set_int_vector(INT_VECTOR_DECREMENTER, int_handler_decrementer); 57 | restart_decrementer(); 58 | } 59 | -------------------------------------------------------------------------------- /src/arch/ppc32/hal/time/time.c: -------------------------------------------------------------------------------- 1 | 2 | void get_system_time(unsigned long *high, unsigned long *low) 3 | { 4 | // kprintf("\tTimestamp: %p-%p\n", 5 | // (unsigned long)(cur_timestamp >> sizeof(unsigned long) * 8), 6 | // (unsigned long)cur_timestamp 7 | // ); 8 | 9 | if (high) { 10 | *high = 0; 11 | } 12 | 13 | if (low) { 14 | *low = 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/arch/ppc32/kernel/kernel.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xFFF08000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : { 11 | *(.text) 12 | } 13 | __text_end = .; 14 | 15 | __rodata_start = .; 16 | .rodata : 17 | { 18 | *(.rodata) 19 | } 20 | __rodata_end = .; 21 | 22 | __data_start = .; 23 | .data : 24 | { 25 | *(.data) 26 | } 27 | __data_end = .; 28 | 29 | __bss_start = .; 30 | .bss : { 31 | *(.bss) 32 | } 33 | __bss_end = .; 34 | 35 | __end = .; 36 | } 37 | -------------------------------------------------------------------------------- /src/arch/ppc32/kernel/syscall/ksys_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | 4 | 5 | no_opt ulong ksys_get_tcb() 6 | { 7 | unsigned long tcb = 0; 8 | 9 | __asm__ __volatile__ 10 | ( 11 | "mr %[reg], 13;" 12 | : [reg]"=r"(tcb) 13 | : 14 | ); 15 | 16 | return tcb; 17 | } 18 | 19 | no_opt int ksys_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 20 | { 21 | register ulong __ppc32_reg_r3 __asm__("3") = num; 22 | register ulong __ppc32_reg_r4 __asm__("4") = param1; 23 | register ulong __ppc32_reg_r5 __asm__("5") = param2; 24 | 25 | __asm__ __volatile__ 26 | ( 27 | "sc;" 28 | : "=r" (__ppc32_reg_r3), "=r" (__ppc32_reg_r4), "=r" (__ppc32_reg_r5) 29 | : "r" (__ppc32_reg_r3), "r" (__ppc32_reg_r4), "r" (__ppc32_reg_r5) 30 | ); 31 | 32 | if (out1) { 33 | *out1 = __ppc32_reg_r4; 34 | } 35 | 36 | if (out2) { 37 | *out2 = __ppc32_reg_r5; 38 | } 39 | 40 | return (int)__ppc32_reg_r3; 41 | } 42 | -------------------------------------------------------------------------------- /src/arch/ppc32/klibc/sys/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/proc.h" 3 | #include "klibc/include/stdio.h" 4 | 5 | 6 | no_opt struct thread_control_block *get_tcb() 7 | { 8 | unsigned long tcb = 0; 9 | 10 | __asm__ __volatile__ 11 | ( 12 | "mr %[reg], 13;" 13 | : [reg]"=r"(tcb) 14 | : 15 | ); 16 | 17 | //kprintf("TCB @ %p\n", tcb); 18 | 19 | return (struct thread_control_block *)tcb; 20 | } 21 | 22 | no_opt int do_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 23 | { 24 | register ulong __ppc32_reg_r3 __asm__("3") = num; 25 | register ulong __ppc32_reg_r4 __asm__("4") = param1; 26 | register ulong __ppc32_reg_r5 __asm__("5") = param2; 27 | 28 | __asm__ __volatile__ 29 | ( 30 | "sc;" 31 | : "=r" (__ppc32_reg_r3), "=r" (__ppc32_reg_r4), "=r" (__ppc32_reg_r5) 32 | : "r" (__ppc32_reg_r3), "r" (__ppc32_reg_r4), "r" (__ppc32_reg_r5) 33 | ); 34 | 35 | if (out1) { 36 | *out1 = __ppc32_reg_r4; 37 | } 38 | 39 | if (out2) { 40 | *out2 = __ppc32_reg_r5; 41 | } 42 | 43 | return 1; //(int)__ppc32_reg_r3; 44 | } 45 | -------------------------------------------------------------------------------- /src/arch/ppc32/loader/loader.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary") 2 | ENTRY(start) 3 | 4 | SECTIONS 5 | { 6 | . = 0x01000000; 7 | 8 | __start = .; 9 | 10 | __text_start = .; 11 | .text : { 12 | *(BOOTSTRAP); 13 | *(.text); 14 | } 15 | __text_end = .; 16 | 17 | __rodata_start = .; 18 | .rodata : { 19 | *(.rodata) 20 | } 21 | __rodata_end = .; 22 | 23 | __data_start = .; 24 | .data : { 25 | *(.data) 26 | } 27 | __data_end = .; 28 | 29 | __bss_start = .; 30 | .bss : { 31 | *(.bss) 32 | } 33 | __bss_end = .; 34 | 35 | __end = .; 36 | } 37 | -------------------------------------------------------------------------------- /src/arch/ppc32/loader/start.S: -------------------------------------------------------------------------------- 1 | #include "common/include/asm.h" 2 | 3 | .global start 4 | .global jump_to_real_mode 5 | .global jump_to_hal 6 | 7 | .section BOOTSTRAP, "ax" 8 | 9 | start: 10 | b loader_entry 11 | nop 12 | 13 | b . 14 | nop 15 | 16 | // r3 = paddr of boot params 17 | // r4 = paddr of "jump_to_hal" 18 | // r5 = paddr of real mode entry point 19 | jump_to_real_mode: 20 | // Disable interrupts 21 | mfmsr r31 22 | rlwinm r31, r31, 0, 17, 15 23 | mtmsr r31 24 | 25 | // Set real mode entry point physical address 26 | mtspr srr0, r5 27 | 28 | // Disable address translation and interrupts 29 | //mfmsr r31 30 | //lis r30, ~0@h 31 | //ori r30, r30, ~(msr_ir | msr_dr | msr_ee)@l 32 | //and r31, r31, r30 33 | li r31, 0 34 | mtspr srr1, r31 35 | 36 | // Go 37 | sync 38 | isync 39 | rfi 40 | 41 | // r3 = paddr of boot params 42 | // r4 = vaddr of HAL entry 43 | jump_to_hal: 44 | // Set HAL entry point 45 | mtspr srr0, r4 46 | 47 | // Set HAL stack 48 | subi sp, r4, 0x10 49 | 50 | // Set exception stack top 51 | //li r31, 0x100 52 | //mtsprg0 r31 53 | 54 | // This forces the usage of sprg0 as exception stack pointer 55 | //li sp, 0 56 | 57 | // Enable address translation 58 | mfmsr r31 59 | ori r31, r31, (msr_ir | msr_dr)@l 60 | mtspr srr1, r31 61 | 62 | // Go! 63 | sync 64 | isync 65 | rfi 66 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/hal.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | struct boot_parameters { 4 | int a; 5 | }; 6 | 7 | void entry_func hal_entry(struct boot_parameters *boot_param) 8 | { 9 | // Should not reach here 10 | // halt(); 11 | while (1); 12 | } 13 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/hal.ld: -------------------------------------------------------------------------------- 1 | ENTRY(hal_entry) 2 | 3 | SECTIONS 4 | { 5 | . = 0xFFF88000; 6 | 7 | __start = .; 8 | 9 | __text_start = .; 10 | .text : { 11 | *(entry); 12 | *(.text); 13 | } 14 | __text_end = .; 15 | 16 | __rodata_start = .; 17 | .rodata : 18 | { 19 | *(.rodata) 20 | } 21 | __rodata_end = .; 22 | 23 | __data_start = .; 24 | .data : 25 | { 26 | *(.data) 27 | } 28 | __data_end = .; 29 | 30 | __bss_start = .; 31 | .bss : { 32 | *(.bss) 33 | } 34 | __bss_end = .; 35 | 36 | __end = .; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/include/cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_SPARC_HAL_INCLUDE_CPU__ 2 | #define __ARCH_SPARC_HAL_INCLUDE_CPU__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * CPU ID 10 | */ 11 | struct cpu_prop { 12 | int dcache_size, icache_size; 13 | int dcache_sets, icache_sets; 14 | int dcache_block_size, icache_block_size; 15 | 16 | int tlb_sets, tlb_size; 17 | 18 | ulong freq_base, freq_clock, freq_bus; 19 | }; 20 | 21 | struct pvr_record { 22 | ulong pvr; 23 | char *class; 24 | char *model; 25 | char *rev; 26 | }; 27 | 28 | extern struct cpu_prop cpu_info; 29 | 30 | extern void init_cpuid(); 31 | 32 | 33 | /* 34 | * Topo 35 | */ 36 | extern int num_cpus; 37 | extern void init_topo(); 38 | 39 | 40 | /* 41 | * MP 42 | */ 43 | extern int get_cpu_id(); 44 | 45 | extern ulong get_per_cpu_area_start_paddr(int cpu_id); 46 | extern ulong get_my_cpu_area_start_paddr(); 47 | 48 | extern ulong get_per_cpu_area_start_vaddr(int cpu_id); 49 | extern ulong get_my_cpu_area_start_vaddr(); 50 | 51 | extern void init_mp(); 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_SPARC_HAL_INCLUDE_LIB__ 2 | #define __ARCH_SPARC_HAL_INCLUDE_LIB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/bootparam.h" 7 | #include "hal/include/string.h" 8 | #include "hal/include/bit.h" 9 | #include "hal/include/debug.h" 10 | #include "hal/include/bootparam.h" 11 | 12 | 13 | /* 14 | * Debug 15 | */ 16 | extern void halt(); 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/include/periph.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_SPARC_HAL_INCLUDE_PERIPH__ 2 | #define __ARCH_SPARC_HAL_INCLUDE_PERIPH__ 3 | 4 | 5 | #include "common/include/ofw.h" 6 | 7 | 8 | /* 9 | * Print 10 | */ 11 | extern void draw_char(char ch); 12 | extern void init_print(); 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/int/int.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | int get_local_int_state() 4 | { 5 | return 0; 6 | } 7 | 8 | void set_local_int_state(int enabled) 9 | { 10 | } 11 | 12 | int disable_local_int() 13 | { 14 | return 0; 15 | } 16 | 17 | void enable_local_int() 18 | { 19 | } 20 | 21 | void restore_local_int(int enabled) 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/lib/debug.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "hal/include/print.h" 3 | #include "hal/include/int.h" 4 | 5 | 6 | void no_opt halt() 7 | { 8 | disable_local_int(); 9 | 10 | // do { 11 | // __asm__ __volatile__ ( 12 | // "nop;" 13 | // "wait;" 14 | // "nop;" 15 | // ); 16 | // } while (1); 17 | 18 | while (1); 19 | } 20 | -------------------------------------------------------------------------------- /src/arch/sparc/hal/periph/print.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/bootparam.h" 3 | #include "hal/include/lib.h" 4 | #include "hal/include/periph.h" 5 | 6 | 7 | static int is_graphic = 0; 8 | 9 | 10 | void draw_char(char ch) 11 | { 12 | // if (is_graphic) { 13 | // fb_draw_char(ch); 14 | // } else { 15 | // escc_draw_char(ch); 16 | // } 17 | } 18 | 19 | void init_print() 20 | { 21 | // struct boot_parameters *bp = get_bootparam(); 22 | // 23 | // switch (bp->video_mode) { 24 | // case VIDEO_FRAMEBUFFER: 25 | // is_graphic = 1; 26 | // init_fb(); 27 | // break; 28 | // case VIDEO_SERIAL: 29 | // init_escc(); 30 | // break; 31 | // default: 32 | // init_escc(); 33 | // break; 34 | // } 35 | } 36 | -------------------------------------------------------------------------------- /src/arch/sparc/kernel/syscall/ksys_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | 4 | 5 | no_opt ulong ksys_get_tcb() 6 | { 7 | unsigned long tcb = 0; 8 | 9 | // __asm__ __volatile__ 10 | // ( 11 | // "mr %[reg], 13;" 12 | // : [reg]"=r"(tcb) 13 | // : 14 | // ); 15 | 16 | return tcb; 17 | } 18 | 19 | no_opt int ksys_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 20 | { 21 | // register ulong __ppc32_reg_r3 __asm__("3") = num; 22 | // register ulong __ppc32_reg_r4 __asm__("4") = param1; 23 | // register ulong __ppc32_reg_r5 __asm__("5") = param2; 24 | // 25 | // __asm__ __volatile__ 26 | // ( 27 | // "sc;" 28 | // : "=r" (__ppc32_reg_r3), "=r" (__ppc32_reg_r4), "=r" (__ppc32_reg_r5) 29 | // : "r" (__ppc32_reg_r3), "r" (__ppc32_reg_r4), "r" (__ppc32_reg_r5) 30 | // ); 31 | // 32 | // if (out1) { 33 | // *out1 = __ppc32_reg_r4; 34 | // } 35 | // 36 | // if (out2) { 37 | // *out2 = __ppc32_reg_r5; 38 | // } 39 | // 40 | // return (int)__ppc32_reg_r3; 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /src/arch/sparc/klibc/sys/do_syscall.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/proc.h" 3 | #include "klibc/include/stdio.h" 4 | 5 | 6 | no_opt struct thread_control_block *get_tcb() 7 | { 8 | unsigned long tcb = 0; 9 | 10 | // __asm__ __volatile__ 11 | // ( 12 | // "mr %[reg], 13;" 13 | // : [reg]"=r"(tcb) 14 | // : 15 | // ); 16 | 17 | //kprintf("TCB @ %p\n", tcb); 18 | 19 | return (struct thread_control_block *)tcb; 20 | } 21 | 22 | no_opt int do_syscall(unsigned long num, unsigned long param1, unsigned long param2, unsigned long *out1, unsigned long *out2) 23 | { 24 | // register ulong __ppc32_reg_r3 __asm__("3") = num; 25 | // register ulong __ppc32_reg_r4 __asm__("4") = param1; 26 | // register ulong __ppc32_reg_r5 __asm__("5") = param2; 27 | // 28 | // __asm__ __volatile__ 29 | // ( 30 | // "sc;" 31 | // : "=r" (__ppc32_reg_r3), "=r" (__ppc32_reg_r4), "=r" (__ppc32_reg_r5) 32 | // : "r" (__ppc32_reg_r3), "r" (__ppc32_reg_r4), "r" (__ppc32_reg_r5) 33 | // ); 34 | // 35 | // if (out1) { 36 | // *out1 = __ppc32_reg_r4; 37 | // } 38 | // 39 | // if (out2) { 40 | // *out2 = __ppc32_reg_r5; 41 | // } 42 | 43 | return 1; //(int)__ppc32_reg_r3; 44 | } 45 | -------------------------------------------------------------------------------- /src/arch/sparc/sparcv8/common/include/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_SPARCV8_COMMON_INCLUDE_ATOMIC__ 2 | #define __ARCH_SPARCV8_COMMON_INCLUDE_ATOMIC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Comapre and swap 10 | */ 11 | static inline int atomic_cas(volatile void *target, ulong old_value, ulong new_value) 12 | { 13 | return 0; 14 | } 15 | 16 | static inline int atomic_cas_uint(volatile void *target, unsigned int old_value, unsigned int new_value) 17 | { 18 | return 0; 19 | } 20 | 21 | 22 | /* 23 | * Read and write 24 | */ 25 | static inline void atomic_write(volatile void *target, unsigned long value) 26 | { 27 | *(unsigned long *)target = value; 28 | } 29 | 30 | 31 | /* 32 | * Fetch and add 33 | */ 34 | static inline void atomic_inc(volatile unsigned long *target) 35 | { 36 | 37 | } 38 | 39 | 40 | /* 41 | * Memory barriers 42 | */ 43 | static inline void atomic_membar() 44 | { 45 | // __asm__ __volatile__ ( "sync;" : : ); 46 | } 47 | 48 | static inline void atomic_readbar() 49 | { 50 | // __asm__ __volatile__ ( "sync;" : : ); 51 | } 52 | 53 | static inline void atomic_writebar() 54 | { 55 | // __asm__ __volatile__ ( "sync;" : : ); 56 | } 57 | 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/arch/sparc/sparcv8/common/include/context.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_SPARCV8_COMMON_INCLUDE_CONTEXT__ 2 | #define __ARCH_SPARCV8_COMMON_INCLUDE_CONTEXT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Context 10 | */ 11 | struct context { 12 | u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; 13 | u32 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; 14 | u32 r20, r21, r22, r23, r24, r25, r26, r27, r28, r29; 15 | u32 r30, r31; 16 | u32 lr, cr, ctr, xer, msr, pc; 17 | } packedstruct; 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/arch/sparc/sparcv8/common/include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_SPARCV8_COMMON_INCLUDE_DATA__ 2 | #define __ARCH_SPARCV8_COMMON_INCLUDE_DATA__ 3 | 4 | 5 | #include "common/include/compiler.h" 6 | 7 | 8 | #ifndef ARCH_WIDTH 9 | #define ARCH_WIDTH 32 10 | #endif 11 | 12 | #ifndef ARCH_LITTLE_ENDIAN 13 | #define ARCH_LITTLE_ENDIAN 0 14 | #endif 15 | 16 | #ifndef ARCH_BIG_ENDIAN 17 | #define ARCH_BIG_ENDIAN 1 18 | #endif 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/arch/sparc/sparcv8/sun4m/loader/loader.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("binary") 2 | ENTRY(start) 3 | 4 | SECTIONS 5 | { 6 | . = 0x4000; 7 | 8 | __start = .; 9 | 10 | __text_start = .; 11 | .text : 12 | { 13 | *(BOOTSTRAP); 14 | *(.text); 15 | } 16 | __text_end = .; 17 | 18 | __rodata_start = .; 19 | .rodata : 20 | { 21 | *(.rodata) 22 | } 23 | __rodata_end = .; 24 | 25 | __data_start = .; 26 | .data : 27 | { 28 | *(.data) 29 | } 30 | __data_end = .; 31 | 32 | __bss_start = .; 33 | .bss : 34 | { 35 | *(.bss); 36 | } 37 | __bss_end = .; 38 | 39 | . = ALIGN(4096); 40 | __initrd_info_start = .; 41 | .initrd_info : 42 | { 43 | /* HdrS */ 44 | LONG(0x48647253); 45 | LONG(0X0); 46 | LONG(0X0); 47 | LONG(0X0); 48 | 49 | /* Initrd load addr */ 50 | LONG(0X0); 51 | /* Initrd size */ 52 | LONG(0x0); 53 | 54 | LONG(0x0); 55 | } 56 | /*. = ALIGN(4096);*/ 57 | __initrd_info_end = .; 58 | 59 | __end = .; 60 | } 61 | -------------------------------------------------------------------------------- /src/arch/sparc/sparcv8/sun4m/loader/start.S: -------------------------------------------------------------------------------- 1 | .global start 2 | 3 | .section BOOTSTRAP, "ax" 4 | 5 | start: 6 | set 0x3f00, %sp 7 | 8 | call loader_entry 9 | nop 10 | 11 | b . 12 | nop 13 | -------------------------------------------------------------------------------- /src/common/include/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_COMPILER__ 2 | #define __COMMON_INCLUDE_COMPILER__ 3 | 4 | 5 | #ifndef asmlinkage 6 | #define asmlinkage 7 | #endif 8 | 9 | 10 | #ifndef packedstruct 11 | #define packedstruct __attribute__((packed)) 12 | #endif 13 | 14 | #ifndef no_inline 15 | #define no_inline __attribute__((noinline)) 16 | #endif 17 | 18 | #ifndef no_opt 19 | #ifdef __clang__ 20 | #define no_opt __attribute__((optnone)) 21 | #else 22 | #define no_opt __attribute__((optimize("-O0"))) 23 | #endif 24 | #endif 25 | 26 | #ifndef weak_func 27 | #define weak_func __attribute__((weak)) 28 | #endif 29 | 30 | #ifndef weak_alias 31 | #define weak_alias(f) __attribute__((weak, alias(#f))) 32 | #endif 33 | 34 | #ifndef entry_func 35 | #define entry_func __attribute__((section("entry"))) 36 | #endif 37 | 38 | 39 | #ifndef NULL 40 | #define NULL ((void *)0) 41 | #endif 42 | 43 | 44 | typedef signed char s8; 45 | typedef signed short s16; 46 | typedef signed int s32; 47 | typedef signed long long s64; 48 | 49 | typedef unsigned char u8; 50 | typedef unsigned short u16; 51 | typedef unsigned int u32; 52 | typedef unsigned long long u64; 53 | 54 | typedef unsigned char uchar; 55 | typedef unsigned short ushort; 56 | typedef unsigned int uint; 57 | typedef unsigned long ulong; 58 | typedef unsigned long long ulonglong; 59 | 60 | #ifndef AVOID_LIBC_CONFLICT 61 | typedef unsigned long size_t; 62 | #endif 63 | 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/common/include/coreimg.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_COREIMG__ 2 | #define __COMMON_INCLUDE_COREIMG__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | struct coreimg_header { 9 | u32 file_count; 10 | u32 image_size; 11 | struct { 12 | u16 major; 13 | u16 minor; 14 | u16 revision; 15 | u16 release; 16 | } version; 17 | u8 architecture; 18 | u8 big_endian; 19 | u8 build_type; 20 | u8 reserved[5]; 21 | u64 time_stamp; 22 | } packedstruct; 23 | 24 | struct coreimg_record { 25 | u8 file_type; 26 | u8 load_type; 27 | u8 compressed; 28 | u8 reserved; 29 | u32 start_offset; 30 | u32 length; 31 | u8 file_name[20]; 32 | } packedstruct; 33 | 34 | struct coreimg_fat { 35 | struct coreimg_header header; 36 | struct coreimg_record records[]; 37 | }; 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/common/include/errno.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_ERRNO__ 2 | #define __COMMON_INCLUDE_ERRNO__ 3 | 4 | 5 | // No error 6 | #define EOK 0 // No error 7 | 8 | // Permission 9 | #define EPERM -1 // Permission denied 10 | 11 | // Resource 12 | #define ENOENT -10 // No such entry 13 | #define ELIMIT -11 // Limit exceeded 14 | #define EBUSY -12 // Resource busy 15 | #define EBADF -13 // Bad file number 16 | #define ECLOSED -14 // File closed 17 | 18 | // Memory 19 | #define ENOMEM -20 // No enough memory 20 | #define EBADMEM -21 // Bad memory address 21 | 22 | // Value 23 | #define EINVAL -20 // Invalid value 24 | #define EOVERFLOW -31 // Value overflow 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/common/include/floppyimg.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_FLOPPYIMG__ 2 | #define __COMMON_INCLUDE_FLOPPYIMG__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | struct floppy_fat_header { 9 | u16 file_count; 10 | u16 fat_count; 11 | 12 | struct { 13 | u16 major; 14 | u16 minor; 15 | u16 revision; 16 | u16 release; 17 | } version; 18 | 19 | u32 create_time; 20 | } packedstruct; 21 | 22 | struct floppy_fat_entry { 23 | u16 start_sector; 24 | u16 sector_count; 25 | u8 file_name[12]; 26 | } packedstruct; 27 | 28 | struct floppy_fat_master { 29 | struct floppy_fat_header header; 30 | struct floppy_fat_entry entries[31]; 31 | } packedstruct; 32 | 33 | struct floppy_fat_slave { 34 | struct floppy_fat_entry entries[32]; 35 | } packedstruct; 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/common/include/kdisp.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_KDISPATCH__ 2 | #define __COMMON_INCLUDE_KDISPATCH__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/context.h" 7 | 8 | 9 | /* 10 | * Kernel dispatch info 11 | */ 12 | enum kernel_dispatch_type { 13 | kdisp_unknown, 14 | kdisp_syscall, 15 | kdisp_interrupt, 16 | kdisp_exception, 17 | 18 | kdisp_page_fault, 19 | kdisp_protection, 20 | kdisp_illegal_instr, 21 | }; 22 | 23 | struct kernel_dispatch_info { 24 | /* 25 | * Filled by HAL 26 | */ 27 | enum kernel_dispatch_type dispatch_type; 28 | 29 | union { 30 | struct { 31 | // Filled by HAL 32 | ulong num; 33 | ulong param0; 34 | ulong param1; 35 | ulong param2; 36 | 37 | // Filled by kernel syscall handler 38 | ulong return0; 39 | ulong return1; 40 | } syscall; 41 | 42 | struct { 43 | // Filled by HAL 44 | ulong vector; 45 | ulong irq; 46 | 47 | ulong param0; 48 | ulong param1; 49 | ulong param2; 50 | } interrupt; 51 | }; 52 | 53 | // Filled by HAL 54 | struct context *context; 55 | 56 | // Filled by kernel 57 | void *worker; 58 | 59 | /* 60 | * Filled by kernel 61 | */ 62 | void *proc; 63 | void *thread; 64 | void *sched; 65 | }; 66 | 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/common/include/proc.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_PROC__ 2 | #define __COMMON_INCLUDE_PROC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Process Control Block 10 | */ 11 | struct process_control_block { 12 | struct process_control_block *self; 13 | 14 | ulong proc_id; 15 | } packedstruct; 16 | 17 | 18 | /* 19 | * Thread Control Block 20 | */ 21 | struct thread_control_block { 22 | struct thread_control_block *self; 23 | 24 | ulong proc_id; 25 | ulong thread_id; 26 | 27 | ulong cpu_id; 28 | 29 | void *tls; 30 | void *msg_send; 31 | void *msg_recv; 32 | } packedstruct; 33 | 34 | 35 | /* 36 | * KMap 37 | */ 38 | enum kmap_region { 39 | kmap_none, 40 | kmap_coreimg, 41 | }; 42 | 43 | 44 | /* 45 | * Process monitor 46 | */ 47 | enum proc_monitor_type { 48 | pm_none, 49 | pm_create_before, 50 | pm_create_after, 51 | pm_terminate_before, 52 | pm_terminate_after, 53 | pm_type_count, 54 | }; 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/common/include/ua.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_INCLUDE_UA__ 2 | #define __COMMON_INCLUDE_UA__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * User ID 10 | */ 11 | #define UA_USER_ID_ROOT 0 12 | #define UA_USER_ID_SYSTEM 1 13 | #define UA_USER_ID_ALLOC_BASE 1000 14 | 15 | /* 16 | * Group ID 17 | */ 18 | #define UA_GROUP_ID_ROOT 0 19 | #define UA_GROUP_ID_SYSTEM 1 20 | #define UA_GROUP_ID_ALLOC_BASE 1000 21 | 22 | /* 23 | * Permissions 24 | */ 25 | #define UA_OWNER_PERM_NONE 0 26 | #define UA_OWNER_PERM_EXEC 0x100 27 | #define UA_OWNER_PERM_WRITE 0x200 28 | #define UA_OWNER_PERM_READ 0x400 29 | #define UA_OWNER_PERM_ALL (UA_OWNER_PERM_EXEC | UA_OWNER_PERM_WRITE | UA_OWNER_PERM_READ) 30 | 31 | #define UA_GROUP_PERM_NONE 0 32 | #define UA_GROUP_PERM_EXEC 0x10 33 | #define UA_GROUP_PERM_WRITE 0x20 34 | #define UA_GROUP_PERM_READ 0x40 35 | #define UA_GROUP_PERM_ALL (UA_GROUP_PERM_EXEC | UA_GROUP_PERM_WRITE | UA_GROUP_PERM_READ) 36 | 37 | #define UA_OTHER_PERM_NONE 0 38 | #define UA_OTHER_PERM_EXEC 0x1 39 | #define UA_OTHER_PERM_WRITE 0x2 40 | #define UA_OTHER_PERM_READ 0x4 41 | #define UA_OTHER_PERM_ALL (UA_OTHER_PERM_EXEC | UA_OTHER_PERM_WRITE | UA_OTHER_PERM_READ) 42 | 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/driver/bus/system/sysbus.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "driver/include/devfs.h" 3 | 4 | 5 | static struct dev_tree_node *sysbus_node = NULL; 6 | 7 | 8 | void init_sysbus() 9 | { 10 | sysbus_node = dev_tree_create(DEV_NODE_BUS, "sysbus"); 11 | } 12 | -------------------------------------------------------------------------------- /src/driver/devfs/tree.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/assert.h" 4 | #include "klibc/include/stdstruct.h" 5 | #include "klibc/include/stdlib.h" 6 | #include "klibc/include/string.h" 7 | #include "driver/include/devfs.h" 8 | 9 | 10 | static unsigned long node_salloc_id = -1; 11 | static volatile struct dev_tree_node *root; 12 | 13 | void init_dev_tree() 14 | { 15 | node_salloc_id = salloc_create(sizeof(struct dev_tree_node), 0, NULL, NULL); 16 | } 17 | 18 | struct dev_tree_node *dev_tree_create(int type, char *name) 19 | { 20 | struct dev_tree_node *node = (struct dev_tree_node *)salloc(node_salloc_id); 21 | node->type = type; 22 | node->name = strdup(name); 23 | 24 | return node; 25 | } 26 | 27 | 28 | int dev_tree_attach(struct dev_tree_node *parent, struct dev_tree_node *node) 29 | { 30 | // Add the new node to the tree 31 | if (!parent) { 32 | assert(!root); 33 | root = node; 34 | } 35 | 36 | else { 37 | dlist_push_back(&parent->nexts, node); 38 | } 39 | 40 | return EOK; 41 | } 42 | -------------------------------------------------------------------------------- /src/driver/driver.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "klibc/include/stdio.h" 3 | #include "klibc/include/sys.h" 4 | #include "driver/include/devfs.h" 5 | #include "driver/include/bus/sysbus.h" 6 | #include "driver/include/keyboard.h" 7 | #include "driver/include/console.h" 8 | 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | kprintf("Toddler driver process started!\n"); 13 | 14 | // Initialize DevFS 15 | init_dev_tree(); 16 | init_devfs(); 17 | 18 | // Initialize the system bus 19 | init_sysbus(); 20 | 21 | // Initialize logical drivers 22 | init_console(); 23 | init_stdio_kapi(); 24 | 25 | // Initialize devices 26 | init_keyboard(); 27 | 28 | // Register KAPI handlers 29 | //kapi_init(); 30 | //kprintf("Driver KAPI handlers initialized!\n"); 31 | 32 | // Init done 33 | kapi_process_started(0); 34 | 35 | // Done 36 | do { 37 | syscall_yield(); 38 | } while (1); 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/driver/include/bus/sysbus.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRIVER_INCLUDE_BUS_SYSBUS__ 2 | #define __DRIVER_INCLUDE_BUS_SYSBUS__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | extern void init_sysbus(); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/driver/include/console.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRIVER_INCLUDE_CONSOLE__ 2 | #define __DRIVER_INCLUDE_CONSOLE__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "klibc/include/kthread.h" 7 | 8 | 9 | #define STDIO_BUF_SIZE 32 10 | 11 | 12 | struct stdio_buffer { 13 | char data[STDIO_BUF_SIZE]; 14 | int size; 15 | volatile int index; 16 | }; 17 | 18 | 19 | struct console { 20 | unsigned long id; 21 | char *name; 22 | int enabled; 23 | int activated; 24 | 25 | // stdio 26 | struct stdio_buffer stdin_buf; 27 | kthread_mutex_t stdin_mutex; 28 | }; 29 | 30 | 31 | /* 32 | * Console 33 | */ 34 | unsigned long create_console(char *name); 35 | 36 | struct console *get_console(unsigned long console_id); 37 | int activate_console(unsigned long console_id); 38 | unsigned long get_activated_console_id(); 39 | 40 | void init_console(); 41 | 42 | 43 | /* 44 | * Stdio 45 | */ 46 | extern int stdin_write(unsigned long console_id, char *buf, size_t size); 47 | extern void init_stdio_kapi(); 48 | 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/driver/include/devfs.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRIVER_INCLUDE_DEVFS__ 2 | #define __DRIVER_INCLUDE_DEVFS__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "klibc/include/stdstruct.h" 7 | 8 | 9 | /* 10 | * Device tree 11 | */ 12 | struct dev_ops { 13 | // Generic operations 14 | int (*init)(); 15 | 16 | // Block operations 17 | int (*enumerate)(); 18 | 19 | // Raw/Block operations 20 | int (*open)(); 21 | int (*close)(); 22 | int (*read)(); 23 | int (*write)(); 24 | int (*seek)(); 25 | int (*ioctl)(); 26 | }; 27 | 28 | struct dev_desc { 29 | unsigned long dev_id; 30 | 31 | // Driver specific descriptor 32 | void *driver_dev_desc; 33 | }; 34 | 35 | enum dev_tree_node_type { 36 | DEV_NODE_UNKNOWN, 37 | DEV_NODE_DIR, 38 | DEV_NODE_BUS, 39 | DEV_NODE_RAW, 40 | DEV_NODE_BLOCK, 41 | }; 42 | 43 | struct dev_tree_node { 44 | int type; 45 | char *name; 46 | struct dev_ops ops; 47 | struct dev_desc desc; 48 | 49 | dlist_t nexts; 50 | }; 51 | 52 | extern void init_dev_tree(); 53 | extern struct dev_tree_node *dev_tree_create(int type, char *name); 54 | extern int dev_tree_attach(struct dev_tree_node *parent, struct dev_tree_node *node); 55 | 56 | 57 | /* 58 | * Device FS 59 | */ 60 | struct open_desc { 61 | unsigned long open_id; 62 | }; 63 | 64 | extern void init_devfs(); 65 | 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/driver/include/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRIVER_INCLUDE_KEYBOARD__ 2 | #define __DRIVER_INCLUDE_KEYBOARD__ 3 | 4 | #include "common/include/data.h" 5 | #include "common/include/syscall.h" 6 | 7 | 8 | extern void init_keyboard(); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/driver/pseudo/null/null.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/urs.h" 3 | #include "klibc/include/stdstruct.h" 4 | #include "driver/include/devfs.h" 5 | 6 | 7 | /* 8 | * Initialize the driver 9 | */ 10 | static int init() 11 | { 12 | } 13 | 14 | /* 15 | * Register/unregister a device 16 | */ 17 | static int dev_plugg(unsigned long node_id, struct dev_desc *desc) 18 | { 19 | } 20 | 21 | static int dev_eject(unsigned long node_id, struct dev_desc *desc) 22 | { 23 | } 24 | 25 | static int dev_gone(unsigned long node_id, struct dev_desc *desc) 26 | { 27 | } 28 | 29 | 30 | /* 31 | * Regular device operations 32 | */ 33 | static int open(struct dev_desc *desc, struct open_desc *inst) 34 | { 35 | } 36 | 37 | static int close(struct dev_desc *desc, struct open_desc *inst) 38 | { 39 | } 40 | 41 | static int read(struct dev_desc *desc, struct open_desc *inst, void *buf, unsigned long count, unsigned long *actual) 42 | { 43 | } 44 | 45 | static int write(struct dev_desc *desc, struct open_desc *inst, void *buf, unsigned long count, unsigned long *actual) 46 | { 47 | } 48 | 49 | static int seek(struct dev_desc *desc, struct open_desc *inst, u64 offset, enum urs_seek_from from, u64 *newpos) 50 | { 51 | } 52 | 53 | static int ioctl(struct dev_desc *desc, struct open_desc *inst, unsigned long action, unsigned long value) 54 | { 55 | } 56 | 57 | 58 | /* 59 | * Register the driver 60 | */ 61 | int register_pseudo_null() 62 | { 63 | } 64 | -------------------------------------------------------------------------------- /src/hal/cpu/percpu.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | #include "common/include/memlayout.h" 4 | #include "hal/include/print.h" 5 | #include "hal/include/debug.h" 6 | #include "hal/include/bit.h" 7 | 8 | 9 | static int cur_per_cpu_offset = 0; 10 | 11 | 12 | /* 13 | * Arch-specific get_my_cpu_area_start_vaddr 14 | */ 15 | weak_func ulong get_my_cpu_area_start_vaddr() 16 | { 17 | return 0; 18 | } 19 | 20 | 21 | static void init_per_cpu_var(int *offset, size_t size) 22 | { 23 | assert(cur_per_cpu_offset + size < PAGE_SIZE); 24 | 25 | *offset = cur_per_cpu_offset; 26 | cur_per_cpu_offset += ALIGN_UP(size, sizeof(ulong)); 27 | } 28 | 29 | void *access_per_cpu_var(int *offset, size_t size) 30 | { 31 | if (*offset == -1) { 32 | init_per_cpu_var(offset, size); 33 | } 34 | 35 | return (void *)(get_my_cpu_area_start_vaddr() + PER_CPU_DATA_START_OFFSET + *offset); 36 | } 37 | -------------------------------------------------------------------------------- /src/hal/include/bit.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_BIT__ 2 | #define __HAL_INCLUDE_BIT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Alignment 10 | */ 11 | #ifndef ALIGN_UP 12 | #define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) 13 | #endif 14 | 15 | #ifndef ALIGN_DOWN 16 | #define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) 17 | #endif 18 | 19 | 20 | /* 21 | * First non-zero bit from the left 22 | */ 23 | extern int fnzb32(u32 arg); 24 | extern int fnzb64(u64 arg); 25 | 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/hal/include/bootparam.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_BOOTPARAM__ 2 | #define __HAL_INCLUDE_BOOTPARAM__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/bootparam.h" 7 | 8 | 9 | /* 10 | * Boot parameters 11 | */ 12 | extern struct boot_parameters *get_bootparam(); 13 | extern void init_bootparam(struct boot_parameters *bootparam); 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/hal/include/fb.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_FB__ 2 | #define __HAL_INCLUDE_FB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | extern void fb_draw_char(char ch); 9 | extern void init_fb_draw_char(void *f, int w, int h, int d, int p); 10 | 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /src/hal/include/kalloc.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_KALLOC__ 2 | #define __HAL_INCLUDE_KALLOC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * HAL memory pool 10 | */ 11 | extern void kfree(void *ptr); 12 | extern void *kalloc(size_t size); 13 | extern void init_kalloc(); 14 | 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /src/hal/include/percpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_PERCPU__ 2 | #define __HAL_INCLUDE_PERCPU__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Per-CPU var 10 | */ 11 | #ifndef dec_per_cpu 12 | #define dec_per_cpu(type, name) int __##name##_per_cpu_offset = -1 13 | #endif 14 | 15 | #ifndef ext_per_cpu 16 | #define ext_per_cpu(type, name) extern int __##name##_per_cpu_offset 17 | #endif 18 | 19 | #ifndef get_per_cpu 20 | #define get_per_cpu(type, name) ((type *)access_per_cpu_var(&__##name##_per_cpu_offset, sizeof(type))) 21 | #endif 22 | 23 | extern void *access_per_cpu_var(int *id, size_t size); 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/hal/include/print.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_PRINT__ 2 | #define __HAL_INCLUDE_PRINT__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | #define TAB_WIDTH 4 9 | 10 | 11 | extern asmlinkage int kprintf(char *fmt, ...) __attribute__((format(printf, 1, 2))); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/hal/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_STRING__ 2 | #define __HAL_INCLUDE_STRING__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * String 10 | */ 11 | extern int strcmp(char *s1, char *s2); 12 | 13 | 14 | /* 15 | * Memory 16 | */ 17 | extern void memcpy(void *dest, void *src, size_t count); 18 | extern void memset(void *src, int value, size_t size); 19 | extern void memzero(void *src, size_t size); 20 | extern int memcmp(void *src1, void *src2, size_t len); 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/hal/include/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_INCLUDE_VECTOR__ 2 | #define __HAL_INCLUDE_VECTOR__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/context.h" 7 | #include "common/include/kdisp.h" 8 | 9 | 10 | /* 11 | * Handle type 12 | */ 13 | #define INT_HANDLE_TYPE_TAKEOVER 0 14 | #define INT_HANDLE_TYPE_HAL 1 15 | #define INT_HANDLE_TYPE_KERNEL 2 16 | 17 | 18 | /* 19 | * Interrupt handler 20 | */ 21 | struct int_context { 22 | ulong vector; 23 | ulong error_code; 24 | 25 | struct context *context; 26 | }; 27 | 28 | typedef int (*int_handler)(struct int_context *intc, struct kernel_dispatch_info *kdi); 29 | 30 | 31 | /* 32 | * Interrupt vectors 33 | */ 34 | #define INT_VECTOR_ALLOC_START 64 35 | #define INT_VECTOR_ALLOC_END 255 36 | #define INT_VECTOR_COUNT (INT_VECTOR_ALLOC_END + 1) 37 | 38 | enum int_vector_state { 39 | int_vector_unknown, 40 | int_vector_reserved, 41 | int_vector_free, 42 | int_vector_allocated, 43 | int_vector_other 44 | }; 45 | 46 | extern void init_int_vector(); 47 | extern int set_int_vector(int vector, int_handler hdlr); 48 | extern int alloc_int_vector(int_handler hdlr); 49 | extern void free_int_vector(int vector); 50 | extern int_handler get_int_handler(int vector); 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/hal/lib/bit.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | /* 5 | * First non-zero bit from the left 6 | */ 7 | int fnzb32(u32 arg) 8 | { 9 | int n = 0; 10 | 11 | if (arg >> 16) { 12 | arg >>= 16; 13 | n += 16; 14 | } 15 | 16 | if (arg >> 8) { 17 | arg >>= 8; 18 | n += 8; 19 | } 20 | 21 | if (arg >> 4) { 22 | arg >>= 4; 23 | n += 4; 24 | } 25 | 26 | if (arg >> 2) { 27 | arg >>= 2; 28 | n += 2; 29 | } 30 | 31 | if (arg >> 1) { 32 | arg >>= 1; 33 | n += 1; 34 | } 35 | 36 | return n; 37 | } 38 | 39 | int fnzb64(u64 arg) 40 | { 41 | int n = 0; 42 | 43 | if (arg >> 32) { 44 | arg >>= 32; 45 | n += 32; 46 | } 47 | 48 | return n + fnzb32((u32)arg); 49 | } 50 | -------------------------------------------------------------------------------- /src/hal/lib/bootparam.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/bootparam.h" 3 | 4 | 5 | static struct boot_parameters *boot_param; 6 | 7 | 8 | struct boot_parameters *get_bootparam() 9 | { 10 | return boot_param; 11 | } 12 | 13 | void init_bootparam(struct boot_parameters *bootparam) 14 | { 15 | boot_param = bootparam; 16 | } 17 | -------------------------------------------------------------------------------- /src/hal/lib/halt.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | weak_func void halt() 5 | { 6 | while (1); 7 | } 8 | -------------------------------------------------------------------------------- /src/hal/lib/string.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | /* 5 | * String 6 | */ 7 | int strcmp(char *s1, char *s2) 8 | { 9 | int result = 0; 10 | 11 | while (*s1 || *s2) { 12 | if (!s1 && !s2) { 13 | return 0; 14 | } 15 | 16 | if (*s1 != *s2) { 17 | return *s1 > *s2 ? 1 : -1; 18 | } 19 | 20 | s1++; 21 | s2++; 22 | } 23 | 24 | return result; 25 | } 26 | 27 | 28 | /* 29 | * Memory 30 | */ 31 | void memcpy(void *dest, void *src, size_t count) 32 | { 33 | ulong i; 34 | 35 | u8 *s = (u8 *)src; 36 | u8 *d = (u8 *)dest; 37 | 38 | for (i = 0; i < count; i++) { 39 | d[i] = s[i]; 40 | } 41 | 42 | } 43 | 44 | void memset(void *src, int value, size_t size) 45 | { 46 | ulong i; 47 | u8 *ptr = (u8 *)src; 48 | 49 | for (i = 0; i < size; i++) { 50 | ptr[i] = (u8)value; 51 | } 52 | 53 | } 54 | 55 | void memzero(void *src, size_t size) 56 | { 57 | ulong i; 58 | u8 *ptr = (u8 *)src; 59 | 60 | for (i = 0; i < size; i++) { 61 | ptr[i] = (u8)0x0; 62 | } 63 | 64 | } 65 | 66 | int memcmp(void *src1, void *src2, size_t len) 67 | { 68 | u8 *cmp1 = (u8 *)src1; 69 | u8 *cmp2 = (u8 *)src2; 70 | 71 | ulong i; 72 | int result = 0; 73 | 74 | for (i = 0; i < len; i++) { 75 | if (cmp1[i] > cmp2[i]) { 76 | return 1; 77 | } else if (cmp1[i] < cmp2[i]) { 78 | return -1; 79 | } 80 | } 81 | 82 | return result; 83 | } 84 | -------------------------------------------------------------------------------- /src/hal/mem/kalloc.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/bootparam.h" 3 | #include "hal/include/print.h" 4 | #include "hal/include/bootparam.h" 5 | #include "hal/include/debug.h" 6 | #include "hal/include/string.h" 7 | #include "hal/include/bit.h" 8 | 9 | 10 | 11 | static ulong mempool_limit = 0; 12 | 13 | 14 | void kfree(void *ptr) 15 | { 16 | warn("HAL memory allocator does not support free, request ignored\n"); 17 | } 18 | 19 | void *kalloc(size_t size) 20 | { 21 | assert(mempool_limit > 0); 22 | struct boot_parameters *bp = get_bootparam(); 23 | 24 | void *result = (void *)mempool_limit; 25 | mempool_limit += ALIGN_UP(size, sizeof(ulong)); 26 | 27 | kprintf("\tMempool alloced @ %p, avail range @ %p to %p, allocatable size: %d KB\n", 28 | result, (void *)mempool_limit, (void *)bp->hal_vspace_end, 29 | (int)((bp->hal_vspace_end - mempool_limit) >> 10) 30 | ); 31 | 32 | assert(mempool_limit <= bp->hal_vspace_end); 33 | 34 | return result; 35 | } 36 | 37 | void init_kalloc() 38 | { 39 | kprintf("Initializing HAL memory allocator\n"); 40 | 41 | struct boot_parameters *bp = get_bootparam(); 42 | mempool_limit = bp->hal_vaddr_end; 43 | 44 | kprintf("\tMempool range @ %p to %p, allocatable size: %d KB\n", 45 | (void *)mempool_limit, (void *)bp->hal_vspace_end, 46 | (int)((bp->hal_vspace_end - mempool_limit) >> 10) 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /src/init/init.py: -------------------------------------------------------------------------------- 1 | print('hello world line 1') 2 | print('hello world line 2') 3 | print('hello world line 3') 4 | print('hello world line 4') -------------------------------------------------------------------------------- /src/kernel/exec/exec.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "kernel/include/exec.h" 3 | 4 | 5 | int load_exec( 6 | ulong image_start, ulong dest_page_dir_pfn, 7 | ulong *entry_out, ulong *vaddr_start_out, ulong *vaddr_end_out 8 | ) 9 | { 10 | return load_elf_exec(image_start, dest_page_dir_pfn, entry_out, vaddr_start_out, vaddr_end_out); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/kernel/include/coreimg.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_INCLUDE_COREIMG__ 2 | #define __KERNEL_INCLUDE_COREIMG__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Core image 10 | */ 11 | extern void init_coreimg(); 12 | extern int get_core_file_count(); 13 | extern int get_core_file_name(int index, char *buf, size_t buf_size); 14 | extern int get_core_file_index(const char *name); 15 | extern ulong get_core_file_size(int index); 16 | extern void *get_core_file_addr_by_index(int index); 17 | extern void *get_core_file_addr_by_name(char *name); 18 | 19 | 20 | /* 21 | * FS 22 | */ 23 | extern void init_coreimgfs(); 24 | 25 | 26 | /* 27 | * Start up 28 | */ 29 | extern void startup_process_started(ulong proc_id); 30 | extern void start_user(); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/kernel/include/exec.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_INCLUDE_EXEC__ 2 | #define __KERNEL_INCLUDE_EXEC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * ELF 10 | */ 11 | extern int load_elf_exec( 12 | ulong image_start, ulong dest_page_dir_pfn, 13 | ulong *entry_out, ulong *vaddr_start_out, ulong *vaddr_end_out); 14 | 15 | /* 16 | * Copy 17 | */ 18 | extern void cross_as_copy( 19 | ulong src_page_dir_pfn, ulong src_start, ulong len, 20 | ulong dest_page_dir_pfn, ulong dest_start); 21 | extern void copy_to_user( 22 | ulong src_start, ulong len, 23 | ulong user_page_dir_pfn, ulong user_start); 24 | 25 | 26 | /* 27 | * Load executable 28 | */ 29 | extern int load_exec( 30 | ulong image_start, ulong dest_page_dir_pfn, 31 | ulong *entry_out, ulong *vaddr_start_out, ulong *vaddr_end_out 32 | ); 33 | 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /src/kernel/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_INCLUDE_LIB__ 2 | #define __KERNEL_INCLUDE_LIB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Alignment 10 | */ 11 | #ifndef ALIGN_UP 12 | #define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) 13 | #endif 14 | 15 | #ifndef ALIGN_DOWN 16 | #define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) 17 | #endif 18 | 19 | 20 | /* 21 | * Str 22 | */ 23 | extern size_t strlen(const char *s); 24 | extern int strcmp(const char *s1, const char *s2); 25 | extern void strcpy(char *dest, const char *src); 26 | extern char *strdup(const char *s); 27 | 28 | 29 | /* 30 | * Mem 31 | */ 32 | extern void memcpy(void *dest, void *src, size_t count); 33 | extern void memset(void *src, int value, size_t size); 34 | extern void memzero(void *src, size_t size); 35 | extern int memcmp(void *src1, void *src2, size_t len); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/kernel/include/sync.h: -------------------------------------------------------------------------------- 1 | #ifndef __KERNEL_INCLUDE_SYNC__ 2 | #define __KERNEL_INCLUDE_SYNC__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/atomic.h" 7 | 8 | 9 | /* 10 | * Generic atomic types 11 | */ 12 | typedef struct { 13 | volatile ulong value; 14 | } atomic_t; 15 | 16 | 17 | /* 18 | * Spin lock 19 | */ 20 | typedef struct { 21 | union { 22 | volatile ulong value; 23 | struct { 24 | volatile ulong locked : 1; 25 | volatile ulong int_enabled : 1; 26 | }; 27 | }; 28 | } spinlock_t; 29 | 30 | 31 | extern void spin_init(spinlock_t *lock); 32 | extern void spin_lock(spinlock_t *lock); 33 | extern void spin_unlock(spinlock_t *lock); 34 | extern void spin_lock_int(spinlock_t *lock); 35 | extern void spin_unlock_int(spinlock_t *lock); 36 | 37 | 38 | /* 39 | * Spin-based readers-writer lock 40 | */ 41 | typedef struct { 42 | union { 43 | volatile ulong value; 44 | struct { 45 | volatile ulong locked : 1; 46 | volatile ulong int_enabled : 1; 47 | volatile ulong counter : sizeof(ulong) * 8 - 2; 48 | }; 49 | }; 50 | } rwlock_t; 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/kernel/kapi/interrupt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * KAPI Handling - Interrupt 3 | */ 4 | #include "common/include/syscall.h" 5 | #include "kernel/include/hal.h" 6 | #include "kernel/include/mem.h" 7 | #include "kernel/include/proc.h" 8 | #include "kernel/include/syscall.h" 9 | #include "kernel/include/kapi.h" 10 | 11 | 12 | asmlinkage void reg_interrupt_handler(struct kernel_msg_handler_arg *arg) 13 | { 14 | // Get the params 15 | struct process *p = arg->sender_thread->proc; 16 | ulong irq = arg->msg->params[0].value; 17 | ulong thread_entry = arg->msg->params[1].value; 18 | 19 | reg_interrupt(p, irq, thread_entry); 20 | 21 | run_thread(arg->sender_thread); 22 | terminate_thread_self(arg->handler_thread); 23 | sfree(arg); 24 | 25 | // Wait for this thread to be terminated 26 | ksys_unreachable(); 27 | } 28 | 29 | asmlinkage void unreg_interrupt_handler(struct kernel_msg_handler_arg *arg) 30 | { 31 | // Get the params 32 | struct process *p = arg->sender_thread->proc; 33 | ulong irq = arg->msg->params[0].value; 34 | 35 | unreg_interrupt(p, irq); 36 | 37 | run_thread(arg->sender_thread); 38 | terminate_thread_self(arg->handler_thread); 39 | sfree(arg); 40 | 41 | // Wait for this thread to be terminated 42 | ksys_unreachable(); 43 | } 44 | -------------------------------------------------------------------------------- /src/kernel/kapi/kmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * KAPI Handling - KMap 3 | */ 4 | #include "kernel/include/hal.h" 5 | #include "kernel/include/mem.h" 6 | #include "kernel/include/proc.h" 7 | #include "kernel/include/kapi.h" 8 | 9 | 10 | /* 11 | * KMap 12 | */ 13 | asmlinkage void kmap_handler(struct kernel_msg_handler_arg *arg) 14 | { 15 | struct thread *t = arg->sender_thread; 16 | struct process *p = t->proc; 17 | 18 | // Do KMap 19 | enum kmap_region region = (enum kmap_region)arg->msg->params[0].value; 20 | unsigned long vaddr = kmap(p, region); 21 | 22 | // Reply 23 | msg_t *m = create_response_msg(t); 24 | set_msg_param_value(m, vaddr); 25 | 26 | // Resume caller thread 27 | run_thread(t); 28 | 29 | // Clean up 30 | terminate_thread_self(arg->handler_thread); 31 | sfree(arg); 32 | 33 | // Wait for this thread to be terminated 34 | ksys_unreachable(); 35 | } 36 | -------------------------------------------------------------------------------- /src/kernel/kapi/process.c: -------------------------------------------------------------------------------- 1 | /* 2 | * KAPI Handling - Process 3 | */ 4 | #include "kernel/include/hal.h" 5 | #include "kernel/include/mem.h" 6 | #include "kernel/include/proc.h" 7 | #include "kernel/include/kapi.h" 8 | #include "kernel/include/coreimg.h" 9 | 10 | 11 | /* 12 | * Process started signal 13 | */ 14 | asmlinkage void process_started_handler(struct kernel_msg_handler_arg *arg) 15 | { 16 | struct thread *t = arg->sender_thread; 17 | startup_process_started(t->proc_id); 18 | 19 | // Resume sender thread 20 | run_thread(t); 21 | 22 | // Clean up 23 | terminate_thread_self(arg->handler_thread); 24 | sfree(arg); 25 | 26 | // Wait for this thread to be terminated 27 | ksys_unreachable(); 28 | } 29 | 30 | 31 | /* 32 | * Process control 33 | */ 34 | asmlinkage void process_exit_handler(struct kernel_msg_handler_arg *arg) 35 | { 36 | 37 | } 38 | 39 | 40 | /* 41 | * Process event monitor 42 | */ 43 | asmlinkage void process_monitor_reg_handler(struct kernel_msg_handler_arg *arg) 44 | { 45 | struct thread *t = arg->sender_thread; 46 | 47 | enum proc_monitor_type type = (enum proc_monitor_type)arg->msg->params[0].value; 48 | unsigned long func_num = arg->msg->params[1].value; 49 | unsigned long opcode = arg->msg->params[2].value; 50 | 51 | register_process_monitor(type, t->proc_id, func_num, opcode); 52 | 53 | // Resume sender thread 54 | run_thread(t); 55 | 56 | // Clean up 57 | terminate_thread_self(arg->handler_thread); 58 | sfree(arg); 59 | 60 | // Wait for this thread to be terminated 61 | ksys_unreachable(); 62 | } 63 | -------------------------------------------------------------------------------- /src/kernel/proc/asid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel ASID manager 3 | */ 4 | 5 | 6 | #include "common/include/data.h" 7 | #include "kernel/include/hal.h" 8 | #include "kernel/include/sync.h" 9 | #include "kernel/include/proc.h" 10 | 11 | 12 | static spinlock_t lock; 13 | static ulong cur_asid = 1; 14 | 15 | 16 | void init_asid() 17 | { 18 | spin_init(&lock); 19 | } 20 | 21 | void asid_release() 22 | { 23 | } 24 | 25 | ulong asid_alloc() 26 | { 27 | ulong asid = 0; 28 | 29 | spin_lock_int(&lock); 30 | 31 | asid = cur_asid; 32 | cur_asid++; 33 | 34 | atomic_membar(); 35 | spin_unlock_int(&lock); 36 | 37 | return asid; 38 | } 39 | 40 | ulong asid_recycle() 41 | { 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/kernel/proc/dummy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel threads 3 | */ 4 | 5 | 6 | #include "common/include/data.h" 7 | #include "common/include/memory.h" 8 | #include "kernel/include/hal.h" 9 | #include "kernel/include/sync.h" 10 | #include "kernel/include/mem.h" 11 | #include "kernel/include/syscall.h" 12 | #include "kernel/include/proc.h" 13 | 14 | 15 | asmlinkage void kernel_idle_thread(ulong param) 16 | { 17 | do { 18 | // spin_lock_int(&dummy_thread_lock); 19 | // int index = param; 20 | // kprintf("This is kernel dummy thread #%d on CPU #%d!\n", index, hal->get_cur_cpu_id()); 21 | // spin_unlock_int(&dummy_thread_lock); 22 | // hal->loop(); 23 | while (1); 24 | } while (1); 25 | } 26 | 27 | asmlinkage void kernel_demo_thread(ulong param) 28 | { 29 | do { 30 | int index = param; 31 | int cpu_id = hal->get_cur_cpu_id(); 32 | // kprintf("Kernel demo thread #%d on CPU #%d%s!\n", index, cpu_id , index == cpu_id ? ", Thread ID == CPU ID" : ""); 33 | //hal->yield(); 34 | ksys_yield(); 35 | } while (1); 36 | } 37 | 38 | asmlinkage void kernel_tclean_thread(ulong param) 39 | { 40 | struct process *p = (struct process *)param; 41 | 42 | do { 43 | // kprintf("Cleaning thrads\n"); 44 | destroy_absent_threads(p); 45 | //buddy_print(); 46 | //hal->yield(); 47 | ksys_yield(); 48 | } while (1); 49 | } 50 | -------------------------------------------------------------------------------- /src/kernel/proc/futex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Thread fast user-space mutex 3 | */ 4 | 5 | #include "common/include/data.h" 6 | #include "kernel/include/hal.h" 7 | #include "kernel/include/mem.h" 8 | #include "kernel/include/ds.h" 9 | #include "kernel/include/proc.h" 10 | 11 | 12 | static int futex_table_entry_salloc_id = -1; 13 | static int thread_list_node_salloc_id = -1; 14 | 15 | 16 | /* 17 | * Init 18 | */ 19 | void init_futex() 20 | { 21 | } 22 | 23 | 24 | /* 25 | * Simple futex 26 | */ 27 | void sfutex_wait(ulong vaddr, struct thread *t) 28 | { 29 | } 30 | 31 | void sfutex_release(ulong vaddr, struct thread *t) 32 | { 33 | } 34 | -------------------------------------------------------------------------------- /src/kernel/proc/kmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * KMap - Map kernel memory to user process 3 | */ 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/proc.h" 7 | #include "common/include/coreimg.h" 8 | #include "kernel/include/hal.h" 9 | #include "kernel/include/mem.h" 10 | #include "kernel/include/proc.h" 11 | 12 | 13 | static unsigned long do_kmap_coreimg(struct process *p) 14 | { 15 | // Get the image location and size 16 | unsigned long coreimg_addr = hal->coreimg_load_addr; 17 | struct coreimg_header *header = (struct coreimg_header *)hal->coreimg_load_addr; 18 | unsigned long size = header->image_size; 19 | 20 | // Allocate a block in virtual address space 21 | unsigned long user_vaddr = dalloc(p, size); 22 | assert(user_vaddr); 23 | 24 | // Map the image to the block 25 | int succeed = hal->map_user( 26 | p->page_dir_pfn, 27 | user_vaddr, coreimg_addr, size, 28 | 0, 0, 1, 0 29 | ); 30 | assert(succeed); 31 | 32 | // Done 33 | return user_vaddr; 34 | } 35 | 36 | unsigned long kmap(struct process *p, enum kmap_region region) 37 | { 38 | // First of all check if the user process has the permission 39 | 40 | // Do the mapping 41 | switch (region) { 42 | case kmap_coreimg: 43 | return do_kmap_coreimg(p); 44 | case kmap_none: 45 | default: 46 | return 0; 47 | } 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /src/kernel/syscall/ioport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * System call worker thread - read and write IO ports 3 | */ 4 | #include "common/include/kdisp.h" 5 | #include "kernel/include/hal.h" 6 | #include "kernel/include/syscall.h" 7 | 8 | 9 | void io_in_worker(struct kernel_dispatch_info *disp_info) 10 | { 11 | // Get the params 12 | struct process *p = disp_info->proc; 13 | ulong addr = disp_info->syscall.param0; 14 | ulong size = disp_info->syscall.param1; 15 | ulong result = 0; 16 | 17 | switch (p->type) { 18 | case process_kernel: 19 | case process_system: 20 | case process_driver: 21 | case process_emulate: 22 | result = hal->io_in(addr, size); 23 | break; 24 | default: 25 | // Crash the process 26 | break; 27 | } 28 | 29 | // disp_info->syscall.return0 = result; 30 | set_syscall_return(disp_info->thread, result, 0); 31 | } 32 | 33 | void io_out_worker(struct kernel_dispatch_info *disp_info) 34 | { 35 | // Get the params 36 | struct process *p = disp_info->proc; 37 | ulong addr = disp_info->syscall.param0; 38 | ulong size = disp_info->syscall.param1; 39 | ulong value = disp_info->syscall.param2; 40 | 41 | switch (p->type) { 42 | case process_kernel: 43 | case process_system: 44 | case process_driver: 45 | case process_emulate: 46 | hal->io_out(addr, size, value); 47 | break; 48 | default: 49 | // Crash the process 50 | break; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/kernel/syscall/ksys.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "common/include/proc.h" 4 | #include "kernel/include/hal.h" 5 | #include "kernel/include/syscall.h" 6 | 7 | 8 | msg_t *ksys_msg() 9 | { 10 | struct thread_control_block *tcb = ksys_get_tcb(); 11 | if (!tcb) { 12 | return NULL; 13 | } 14 | 15 | msg_t *msg = tcb->msg_send; 16 | msg->mailbox_id = IPC_MAILBOX_NONE; 17 | msg->opcode = IPC_OPCODE_NONE; 18 | msg->func_num = 0; 19 | msg->param_count = 0; 20 | 21 | msg->msg_size = (int)sizeof(msg_t); 22 | if (msg->msg_size % (int)sizeof(unsigned long)) { 23 | msg->msg_size /= (int)sizeof(unsigned long); 24 | msg->msg_size++; 25 | msg->msg_size *= (int)sizeof(unsigned long); 26 | } 27 | 28 | return msg; 29 | } 30 | 31 | static msg_t *get_recv_msg() 32 | { 33 | struct thread_control_block *tcb = ksys_get_tcb(); 34 | if (!tcb) { 35 | return NULL; 36 | } 37 | 38 | msg_t *msg = tcb->msg_recv; 39 | return msg; 40 | } 41 | 42 | msg_t *ksys_request() 43 | { 44 | int succeed = ksys_syscall(SYSCALL_REQUEST, 0, 0, NULL, NULL); 45 | // kprintf("ksys request: %d\n", succeed); 46 | // if (succeed) { 47 | return get_recv_msg(); 48 | // } else { 49 | // return NULL; 50 | // } 51 | } 52 | 53 | void ksys_yield() 54 | { 55 | ksys_syscall(SYSCALL_YIELD, 0, 0, NULL, NULL); 56 | } 57 | 58 | void ksys_unreachable() 59 | { 60 | do { 61 | ksys_syscall(SYSCALL_YIELD, 0, 0, NULL, NULL); 62 | } while (1); 63 | 64 | kprintf("Unreachable: should never reach here!\n"); 65 | while (1); 66 | } 67 | -------------------------------------------------------------------------------- /src/kernel/syscall/time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * System call worker thread - time 3 | */ 4 | #include "common/include/kdisp.h" 5 | #include "kernel/include/hal.h" 6 | #include "kernel/include/syscall.h" 7 | 8 | 9 | void time_worker(struct kernel_dispatch_info *disp_info) 10 | { 11 | // Get time 12 | unsigned long high = 0; 13 | unsigned long low = 0; 14 | hal->time(&high, &low); 15 | 16 | set_syscall_return(disp_info->thread, high, low); 17 | } 18 | -------------------------------------------------------------------------------- /src/klibc/include/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_ASSERT__ 2 | #define __KLIBC_INCLUDE_ASSERT__ 3 | 4 | 5 | #include "klibc/include/stdio.h" 6 | 7 | 8 | #ifdef assert 9 | #undef assert 10 | #endif 11 | 12 | #define assert(exp) do { \ 13 | if (!(exp)) { \ 14 | kprintf("[ASSERT] Failed: "); \ 15 | kprintf(#exp); \ 16 | kprintf("\n"); \ 17 | kprintf("[SRC] File: %s, Base: %s, Line: %d\n", __FILE__, __BASE_FILE__, __LINE__); \ 18 | } \ 19 | } while (0) 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/klibc/include/kthread.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_KTHREAD__ 2 | #define __KLIBC_INCLUDE_KTHREAD__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "klibc/include/stdarg.h" 7 | 8 | 9 | /* 10 | * TLS 11 | */ 12 | extern unsigned long ktls_alloc(size_t size); 13 | extern void *ktls_access(unsigned long tls_offset); 14 | extern void init_tls(); 15 | 16 | 17 | /* 18 | * Thread control 19 | */ 20 | struct kthread { 21 | volatile unsigned long thread_id; 22 | volatile unsigned long return_value; 23 | 24 | volatile int started; 25 | volatile int terminated; 26 | }; 27 | 28 | typedef volatile struct kthread kthread_t; 29 | 30 | typedef unsigned long (*start_routine_t)(unsigned long); 31 | 32 | extern void init_kthread(); 33 | extern int kthread_create(kthread_t *thread, start_routine_t start, unsigned long arg); 34 | extern kthread_t *kthread_self(); 35 | extern void kthread_exit(unsigned long retval); 36 | extern void kthread_kill(kthread_t *thread, unsigned long retval); 37 | 38 | 39 | /* 40 | * Mutex 41 | */ 42 | #define KTHREAD_MUTEX_INIT { 0 } 43 | 44 | typedef struct kthread_mutex { 45 | volatile unsigned long value; 46 | } kthread_mutex_t; 47 | 48 | extern void kthread_mutex_init(kthread_mutex_t *mutex); 49 | extern void kthread_mutex_destroy(kthread_mutex_t *mutex); 50 | 51 | extern void kthread_mutex_lock(kthread_mutex_t *mutex); 52 | extern int kthread_mutex_trylock(kthread_mutex_t *mutex); 53 | extern int kthread_mutex_unlock(kthread_mutex_t *mutex); 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/klibc/include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_STDARG__ 2 | #define __KLIBC_INCLUDE_STDARG__ 3 | 4 | 5 | typedef __builtin_va_list va_list; 6 | #define va_start(ap, last) __builtin_va_start(ap, last) 7 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 8 | #define va_end(ap) __builtin_va_end(ap) 9 | 10 | 11 | // typedef void * va_list; 12 | // 13 | // 14 | // #define va_start(ap, last) ap = (va_list)(void *)(&last); ap += sizeof(last) 15 | // #define va_arg(ap, type) *((type *)ap); ap += sizeof(type) 16 | // #define va_end(ap) 17 | // #define va_copy(dest, src) dest = src 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/klibc/include/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_STDIO__ 2 | #define __KLIBC_INCLUDE_STDIO__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "klibc/include/stdarg.h" 7 | 8 | 9 | extern int asmlinkage kprintf(char *fmt, ...); 10 | extern int asmlinkage ksnprintf(char *buf, size_t size, char *fmt, ...); 11 | extern int asmlinkage vsnprintf(char *buf, size_t size, char *fmt, va_list ap); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/klibc/include/stdlib.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_STDLIB__ 2 | #define __KLIBC_INCLUDE_STDLIB__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Heap alloc 10 | */ 11 | #define HALLOC_CHUNK_SIZE (32 * 1024) 12 | 13 | extern void init_halloc(); 14 | extern void *halloc(); 15 | extern void hfree(void *addr); 16 | 17 | 18 | /* 19 | * Struct alloc 20 | */ 21 | typedef void (*salloc_callback_t)(void* entry); 22 | 23 | extern void init_salloc(); 24 | extern int salloc_create(size_t size, size_t align, salloc_callback_t construct, salloc_callback_t destruct); 25 | extern void *salloc(int obj_id); 26 | extern void sfree(void *ptr); 27 | 28 | 29 | /* 30 | * Malloc 31 | */ 32 | extern void init_malloc(); 33 | extern void *malloc(size_t size); 34 | extern void *calloc(int count, size_t size); 35 | extern void free(void *size); 36 | extern void test_malloc(); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/klibc/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_STRING__ 2 | #define __KLIBC_INCLUDE_STRING__ 3 | 4 | 5 | /* 6 | * String 7 | */ 8 | extern size_t strlen(const char *s); 9 | extern int strcmp(const char *s1, const char *s2); 10 | extern void strcpy(char *dest, const char *src); 11 | extern char *strdup(const char *str); 12 | 13 | 14 | /* 15 | * Memory 16 | */ 17 | extern void memcpy(void *dest, const void *src, size_t count); 18 | extern void memset(void *src, int value, size_t size); 19 | extern void memzero(void *src, size_t size); 20 | extern int memcmp(const void *src1, const void *src2, size_t len); 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/klibc/include/time.h: -------------------------------------------------------------------------------- 1 | #ifndef __KLIBC_INCLUDE_TIME__ 2 | #define __KLIBC_INCLUDE_TIME__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | typedef u64 time_t; 9 | 10 | extern time_t time(); 11 | 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/klibc/kthread/mutex.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/atomic.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/sys.h" 5 | #include "klibc/include/kthread.h" 6 | 7 | 8 | void kthread_mutex_init(kthread_mutex_t *mutex) 9 | { 10 | mutex->value = 0; 11 | } 12 | 13 | void kthread_mutex_destroy(kthread_mutex_t *mutex) 14 | { 15 | mutex->value = 0; 16 | } 17 | 18 | 19 | void kthread_mutex_lock(kthread_mutex_t *mutex) 20 | { 21 | do { 22 | while (mutex->value) { 23 | // kapi_futex_wait(mutex); 24 | sys_yield(); 25 | atomic_membar(); 26 | } 27 | } while (!atomic_cas(&mutex->value, 0, 0x1)); 28 | } 29 | 30 | int kthread_mutex_trylock(kthread_mutex_t *mutex) 31 | { 32 | if (mutex->value) { 33 | return 0; 34 | } 35 | 36 | return atomic_cas(&mutex->value, 0, 0x1); 37 | } 38 | 39 | int kthread_mutex_unlock(kthread_mutex_t *mutex) 40 | { 41 | if (!mutex->value) { 42 | return 0; 43 | } 44 | 45 | atomic_write(&mutex->value, 0); 46 | // kapi_futex_release(mutex); 47 | return 1; 48 | } 49 | -------------------------------------------------------------------------------- /src/klibc/kthread/tls.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/memory.h" 3 | #include "common/include/proc.h" 4 | #include "common/include/atomic.h" 5 | #include "klibc/include/stdio.h" 6 | #include "klibc/include/sys.h" 7 | #include "klibc/include/kthread.h" 8 | 9 | 10 | static kthread_mutex_t tls_mutex = KTHREAD_MUTEX_INIT; 11 | static unsigned long tls_size = PAGE_SIZE; 12 | static unsigned long cur_tls_offset = 0; 13 | 14 | 15 | unsigned long ktls_alloc(size_t size) 16 | { 17 | unsigned long result = 0; 18 | 19 | kthread_mutex_lock(&tls_mutex); 20 | 21 | if (cur_tls_offset + size <= tls_size) { 22 | result = cur_tls_offset; 23 | cur_tls_offset += size; 24 | } 25 | atomic_membar(); 26 | 27 | kthread_mutex_unlock(&tls_mutex); 28 | 29 | return result; 30 | } 31 | 32 | void *ktls_access(unsigned long tls_offset) 33 | { 34 | struct thread_control_block *tcb = get_tcb(); 35 | return tcb->tls + tls_offset; 36 | } 37 | 38 | void init_tls() 39 | { 40 | cur_tls_offset = sizeof(struct thread_control_block); 41 | } 42 | -------------------------------------------------------------------------------- /src/klibc/start.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/atomic.h" 3 | #include "klibc/include/sys.h" 4 | #include "klibc/include/stdio.h" 5 | #include "klibc/include/stdlib.h" 6 | #include "klibc/include/kthread.h" 7 | 8 | 9 | extern int main(int argc, char *argv[]); 10 | 11 | 12 | static void klib_init() 13 | { 14 | init_tls(); 15 | init_kthread(); 16 | 17 | init_halloc(); 18 | init_salloc(); 19 | init_malloc(); 20 | //test_malloc(); 21 | } 22 | 23 | asmlinkage void _start() 24 | { 25 | kprintf("Klib started!\n"); 26 | 27 | // Initialize klib 28 | klib_init(); 29 | 30 | // Make all writes effective 31 | atomic_membar(); 32 | 33 | // Call the main function 34 | main(0, NULL); 35 | 36 | // Done 37 | sys_unreahable(); 38 | } 39 | 40 | void klib_init_thread() 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /src/klibc/stdio/kprintf.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "klibc/include/stdio.h" 3 | #include "klibc/include/sys.h" 4 | #include "klibc/include/stdarg.h" 5 | 6 | 7 | #define BUF_SIZE 128 8 | 9 | 10 | int asmlinkage ksnprintf(char *buf, size_t size, char *fmt, ...) 11 | { 12 | // Args 13 | int ret = 0; 14 | va_list ap; 15 | va_start(ap, fmt); 16 | 17 | // Print 18 | ret = vsnprintf(buf, size, fmt, ap); 19 | 20 | va_end(ap); 21 | return ret; 22 | } 23 | 24 | 25 | int asmlinkage kprintf(char *fmt, ...) 26 | { 27 | // Buf 28 | char buf[BUF_SIZE]; 29 | size_t size = BUF_SIZE; 30 | 31 | // Args 32 | int ret = 0; 33 | va_list ap; 34 | va_start(ap, fmt); 35 | 36 | // Print 37 | ret = vsnprintf(buf, size, fmt, ap); 38 | syscall_kputs(buf); 39 | 40 | va_end(ap); 41 | return ret; 42 | } 43 | -------------------------------------------------------------------------------- /src/klibc/string/mem.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "klibc/include/string.h" 3 | 4 | 5 | void memcpy(void *dest, const void *src, size_t count) 6 | { 7 | size_t i; 8 | 9 | unsigned char *s = (unsigned char *)src; 10 | unsigned char *d = (unsigned char *)dest; 11 | 12 | for (i = 0; i < count; i++) { 13 | *(d++) = *(s++); 14 | } 15 | 16 | } 17 | 18 | void memset(void *src, int value, size_t size) 19 | { 20 | ulong i; 21 | unsigned char *ptr = (unsigned char *)src; 22 | 23 | for (i = 0; i < size; i++) { 24 | *(ptr++) = (unsigned char)value; 25 | } 26 | 27 | } 28 | 29 | void memzero(void *src, size_t size) 30 | { 31 | ulong i; 32 | unsigned char *ptr = (unsigned char *)src; 33 | 34 | for (i = 0; i < size; i++) { 35 | *(ptr++) = (unsigned char)0x0; 36 | } 37 | 38 | } 39 | 40 | int memcmp(const void *src1, const void *src2, size_t len) 41 | { 42 | unsigned char *cmp1 = (unsigned char *)src1; 43 | unsigned char *cmp2 = (unsigned char *)src2; 44 | 45 | ulong i; 46 | int result = 0; 47 | 48 | for (i = 0; i < len; i++) { 49 | if (*(cmp1 + i) > *(cmp2 + i)) { 50 | return 1; 51 | } else if (*(cmp1 + i) < *(cmp2 + i)) { 52 | return -1; 53 | } 54 | } 55 | 56 | return result; 57 | } 58 | -------------------------------------------------------------------------------- /src/klibc/string/str.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "klibc/include/stdlib.h" 3 | #include "klibc/include/string.h" 4 | 5 | 6 | size_t strlen(const char *s) 7 | { 8 | size_t len = 0; 9 | 10 | while (*s++) { 11 | len++; 12 | } 13 | 14 | return len; 15 | } 16 | 17 | int strcmp(const char *s1, const char *s2) 18 | { 19 | int result = 0; 20 | 21 | while (*s1 || *s2) { 22 | if (!s1 && !s2) { 23 | return 0; 24 | } 25 | 26 | if (*s1 != *s2) { 27 | return *s1 > *s2 ? 1 : -1; 28 | } 29 | 30 | s1++; 31 | s2++; 32 | } 33 | 34 | return result; 35 | } 36 | 37 | void strcpy(char *dest, const char *src) 38 | { 39 | do { 40 | *dest++ = *src; 41 | } while (*src++); 42 | 43 | *dest = '\0'; 44 | } 45 | 46 | char *strdup(const char *str) 47 | { 48 | size_t len = strlen(str); 49 | char *buf = malloc(sizeof(char) * (len + 1)); 50 | strcpy(buf, str); 51 | return buf; 52 | } 53 | -------------------------------------------------------------------------------- /src/klibc/sys/heap.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "klibc/include/string.h" 4 | #include "klibc/include/sys.h" 5 | 6 | 7 | unsigned long kapi_get_heap_end() 8 | { 9 | msg_t *s = kapi_msg(KAPI_HEAP_END_GET); 10 | msg_t *r = syscall_request(); 11 | 12 | return kapi_return_value(r); 13 | } 14 | 15 | unsigned long kapi_set_heap_end(unsigned long heap_end) 16 | { 17 | msg_t *s = kapi_msg(KAPI_HEAP_END_SET); 18 | msg_t *r = NULL; 19 | 20 | msg_param_value(s, heap_end); 21 | r = syscall_request(); 22 | 23 | return kapi_return_value(r); 24 | } 25 | 26 | unsigned long kapi_grow_heap(unsigned long amount) 27 | { 28 | msg_t *s = kapi_msg(KAPI_HEAP_END_GROW); 29 | msg_t *r = NULL; 30 | 31 | msg_param_value(s, amount); 32 | r = syscall_request(); 33 | 34 | return kapi_return_value(r); 35 | } 36 | 37 | unsigned long kapi_shrink_heap(unsigned long amount) 38 | { 39 | msg_t *s = kapi_msg(KAPI_HEAP_END_SHRINK); 40 | msg_t *r = NULL; 41 | 42 | msg_param_value(s, amount); 43 | r = syscall_request(); 44 | 45 | return kapi_return_value(r); 46 | } 47 | 48 | int kapi_brk(unsigned long heap_end) 49 | { 50 | unsigned long ret = kapi_set_heap_end(heap_end); 51 | return ret ? 1 : 0; 52 | } 53 | 54 | unsigned long kapi_sbrk(long amount) 55 | { 56 | if (amount == 0) { 57 | return kapi_get_heap_end(); 58 | } else if (amount > 0) { 59 | return kapi_grow_heap((unsigned long)amount); 60 | } else if (amount < 0) { 61 | return kapi_shrink_heap((unsigned long)(0 - amount)); 62 | } 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /src/klibc/sys/interrupt.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "klibc/include/string.h" 4 | #include "klibc/include/sys.h" 5 | 6 | 7 | int kapi_interrupt_reg(unsigned long irq, void *handler_entry) 8 | { 9 | msg_t *s = kapi_msg(KAPI_INTERRUPT_REG); 10 | 11 | msg_param_value(s, irq); 12 | msg_param_value(s, (unsigned long)handler_entry); 13 | 14 | syscall_request(); 15 | 16 | return 1; 17 | } 18 | 19 | int kapi_interrupt_unreg(unsigned long irq) 20 | { 21 | msg_t *s = kapi_msg(KAPI_INTERRUPT_UNREG); 22 | 23 | msg_param_value(s, irq); 24 | 25 | syscall_request(); 26 | 27 | return 1; 28 | } 29 | -------------------------------------------------------------------------------- /src/klibc/sys/kmap.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "common/include/proc.h" 4 | #include "klibc/include/sys.h" 5 | 6 | 7 | /* 8 | * KMap 9 | */ 10 | void *kapi_kmap(enum kmap_region region) 11 | { 12 | msg_t *s = kapi_msg(KAPI_KMAP); 13 | msg_t *r = NULL; 14 | 15 | msg_param_value(s, (unsigned long)region); 16 | r = syscall_request(); 17 | 18 | return (void *)kapi_return_value(r); 19 | } 20 | -------------------------------------------------------------------------------- /src/klibc/sys/msg.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "klibc/include/sys.h" 4 | 5 | 6 | static unsigned long cur_msg_num = USER_MSG_NUM_BASE; 7 | 8 | 9 | unsigned long alloc_msg_num() 10 | { 11 | return cur_msg_num++; 12 | } 13 | -------------------------------------------------------------------------------- /src/klibc/sys/stdio.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "klibc/include/string.h" 4 | #include "klibc/include/assert.h" 5 | #include "klibc/include/sys.h" 6 | 7 | 8 | unsigned long kapi_stdin_read(unsigned long console_id, void *buf, unsigned long count) 9 | { 10 | msg_t *s = kapi_msg(KAPI_STDIN_READ); 11 | msg_param_value(s, console_id); 12 | msg_param_value(s, count); 13 | 14 | msg_t *r = syscall_request(); 15 | char *data = (char *)((unsigned long)r + r->params[0].offset); 16 | unsigned long size = r->params[1].value; 17 | 18 | assert(size <= count); 19 | if (size && data && buf) { 20 | memcpy(buf, data, size); 21 | } 22 | 23 | return size; 24 | } 25 | 26 | unsigned long kapi_stdout_write(unsigned long console_id, void *buf, unsigned long count) 27 | { 28 | msg_t *s = kapi_msg(KAPI_STDOUT_WRITE); 29 | msg_t *r; 30 | 31 | msg_param_value(s, console_id); 32 | msg_param_buffer(s, buf, (size_t)count); 33 | msg_param_value(s, count); 34 | 35 | r = syscall_request(); 36 | return kapi_return_value(r); 37 | } 38 | 39 | unsigned long kapi_stderr_write(unsigned long console_id, void *buf, unsigned long count) 40 | { 41 | msg_t *s = kapi_msg(KAPI_STDERR_WRITE); 42 | msg_t *r; 43 | 44 | msg_param_value(s, console_id); 45 | msg_param_buffer(s, buf, (size_t)count); 46 | msg_param_value(s, count); 47 | 48 | r = syscall_request(); 49 | return kapi_return_value(r); 50 | } 51 | -------------------------------------------------------------------------------- /src/klibc/sys/sys.c: -------------------------------------------------------------------------------- 1 | #include "klibc/include/sys.h" 2 | 3 | 4 | void sys_unreahable() 5 | { 6 | while (1); 7 | } 8 | 9 | void sys_yield() 10 | { 11 | syscall_yield(); 12 | } 13 | -------------------------------------------------------------------------------- /src/klibc/time/time.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "klibc/include/sys.h" 3 | #include "klibc/include/time.h" 4 | 5 | 6 | /* 7 | * Time 8 | */ 9 | time_t time() 10 | { 11 | unsigned long high = 0; 12 | unsigned long low = 0; 13 | time_t time = 0; 14 | 15 | syscall_time(&high, &low); 16 | 17 | #if (ARCH_WIDTH == 64) 18 | time = low; 19 | #else 20 | time |= high; 21 | time <<= sizeof(unsigned long) * 8; 22 | time |= low; 23 | #endif 24 | 25 | return time; 26 | } 27 | 28 | // clock_t times(struct tms *buf); 29 | // int gettimeofday(struct timeval *p, struct timezone *z); 30 | -------------------------------------------------------------------------------- /src/loader/include/arg.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_ARG_H__ 2 | #define __LOADER_ARG_H__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Argument 10 | */ 11 | typedef __builtin_va_list va_list; 12 | #define va_start(ap, last) __builtin_va_start(ap, last) 13 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 14 | #define va_end(ap) __builtin_va_end(ap) 15 | 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /src/loader/include/cmdline.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_INCLUDE_CMDLINE__ 2 | #define __LOADER_INCLUDE_CMDLINE__ 3 | 4 | 5 | extern int query_cmdline(char *key, char **value_out, int *len_out); 6 | extern int check_cmdline(char *key, char *value); 7 | extern void parse_cmdline(char *base, int size); 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/loader/include/exec.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_EXEC_H__ 2 | #define __LOADER_EXEC_H__ 3 | 4 | 5 | #include "common/include/data.h" 6 | #include "common/include/coreimg.h" 7 | #include "common/include/bootparam.h" 8 | 9 | 10 | extern void load_images(struct coreimg_fat *coreimg, struct boot_parameters *bp, 11 | ulong offset_up, ulong offset_down); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/loader/include/firmware/ofw.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_PPC32_LOADER_INCLUDE_OFW__ 2 | #define __ARCH_PPC32_LOADER_INCLUDE_OFW__ 3 | 4 | 5 | /* 6 | * OFW services 7 | */ 8 | extern void ofw_init(ulong ofw_entry); 9 | extern void ofw_printf(char *fmt, ...); 10 | 11 | extern int ofw_mem_zone(int idx, ulong *start, ulong *size); 12 | 13 | extern int ofw_screen_is_graphic(); 14 | extern void ofw_fb_info(void **addr, int *width, int *height, int *depth, int *bpl); 15 | extern void ofw_escc_info(void **addr); 16 | 17 | extern int ofw_has_openpic(); 18 | extern ulong ofw_find_int_ctrl_base(); 19 | 20 | extern void *ofw_translate(void *virt); 21 | 22 | extern void ofw_quiesce(); 23 | 24 | extern void ofw_alloc(void **virt, void **phys, const int size, int align); 25 | 26 | extern struct ofw_tree_node *ofw_tree_build(); 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/loader/include/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_LIB_H__ 2 | #define __LOADER_LIB_H__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Alignment 10 | */ 11 | #define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) 12 | #define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) 13 | 14 | 15 | /* 16 | * BSS 17 | */ 18 | extern void init_bss(); 19 | 20 | 21 | /* 22 | * Endian 23 | */ 24 | extern u64 swap_endian64(u64 val); 25 | extern u32 swap_endian32(u32 val); 26 | extern u16 swap_endian16(u16 val); 27 | extern ulong swap_endian(ulong val); 28 | 29 | 30 | /* 31 | * Math 32 | */ 33 | extern void div_u32(u32 dividend, u32 divisor, u32 *quo_out, u32 *rem_out); 34 | extern void div_s32(s32 dividend, s32 divisor, s32 *quo_out, s32 *rem_out); 35 | extern void div_int(int dividend, int divisor, int *quo_out, int *rem_out); 36 | extern void div_uint(uint dividend, uint divisor, uint *quo_out, uint *rem_out); 37 | 38 | 39 | /* 40 | * String 41 | */ 42 | extern int strcmp2(char *src, char *dest, int len); 43 | extern int strcmp(char *s1, char *s2); 44 | extern int strlen(const char *s); 45 | 46 | 47 | /* 48 | * Memory 49 | */ 50 | extern void memcpy(void *dest, void *src, size_t count); 51 | extern void memset(void *src, int value, size_t size); 52 | extern void memzero(void *src, size_t size); 53 | extern int memcmp(void *src1, void *src2, size_t len); 54 | 55 | 56 | /* 57 | * Debug 58 | */ 59 | extern void panic(); 60 | 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/loader/include/mempool.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_INCLUDE_MEMPOOL__ 2 | #define __LOADER_INCLUDE_MEMPOOL__ 3 | 4 | 5 | extern void mempool_init(void *virt, void *phys, int size); 6 | extern void *mempool_alloc(int size, int align); 7 | extern void *mempool_to_phys(void *virt); 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/loader/include/print.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOADER_PRINT_H__ 2 | #define __LOADER_PRINT_H__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | extern void lprintf(char *fmt, ...); 9 | 10 | extern void init_framebuffer_draw(void *f, int w, int h, int d, int p); 11 | extern void framebuffer_draw_char(char ch); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/loader/lib/bss.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/lib.h" 3 | 4 | 5 | extern int __bss_start; 6 | extern int __bss_end; 7 | 8 | 9 | void init_bss() 10 | { 11 | int *start = (int *)ALIGN_UP((ulong)&__bss_start, sizeof(int)); 12 | int *cur; 13 | 14 | for (cur = start; cur < &__bss_end; cur++) { 15 | *cur = 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/loader/lib/debug.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/lib.h" 3 | 4 | 5 | void panic() 6 | { 7 | while (1); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/loader/lib/endian.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | 3 | 4 | u64 swap_endian64(u64 val) 5 | { 6 | u64 rrr = val & 0xffull; 7 | u64 rrl = (val >> 8) & 0xffull; 8 | 9 | u64 rlr = (val >> 16) & 0xffull; 10 | u64 rll = (val >> 24) & 0xffull; 11 | 12 | u64 lrr = (val >> 32) & 0xffull; 13 | u64 lrl = (val >> 40) & 0xffull; 14 | 15 | u64 llr = (val >> 48) & 0xffull; 16 | u64 lll = (val >> 56) & 0xffull; 17 | 18 | u64 swap = (rrr << 56) | (rrl << 48) | 19 | (rlr << 40) | (rll << 32) | 20 | (lrr << 24) | (lrl << 16) | 21 | (llr << 8) | lll; 22 | 23 | return swap; 24 | } 25 | 26 | u32 swap_endian32(u32 val) 27 | { 28 | u32 rr = val & 0xff; 29 | u32 rl = (val >> 8) & 0xff; 30 | u32 lr = (val >> 16) & 0xff; 31 | u32 ll = (val >> 24) & 0xff; 32 | 33 | u32 swap = (rr << 24) | (rl << 16) | (lr << 8) | ll; 34 | 35 | return swap; 36 | } 37 | 38 | u16 swap_endian16(u16 val) 39 | { 40 | u16 r = val & 0xff; 41 | u16 l = (val >> 8) & 0xff; 42 | 43 | u16 swap = (r << 8) | l; 44 | 45 | return swap; 46 | } 47 | 48 | ulong swap_endian(ulong val) 49 | { 50 | #if (ARCH_WIDTH == 64) 51 | return (ulong)swap_endian64((u64)val); 52 | #elif (ARCH_WIDTH == 32) 53 | return (ulong)swap_endian32((u32)val); 54 | #elif (ARCH_WIDTH == 16) 55 | return (ulong)swap_endian16((u16)val); 56 | #else 57 | #error Unsupport ARCH_WIDTH 58 | #endif 59 | } 60 | -------------------------------------------------------------------------------- /src/loader/mempool/mempool.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/lib.h" 3 | #include "loader/include/print.h" 4 | 5 | 6 | static int initialized = 0; 7 | 8 | static ulong mempool_virt_base; 9 | static ulong mempool_phys_base; 10 | static int mempool_size; 11 | static int mempool_offset; 12 | 13 | 14 | void mempool_init(void *virt, void *phys, int size) 15 | { 16 | mempool_virt_base = (ulong)virt; 17 | mempool_phys_base = (ulong)phys; 18 | mempool_size = size; 19 | mempool_offset = 0; 20 | 21 | initialized = 1; 22 | } 23 | 24 | void *mempool_alloc(int size, int align) 25 | { 26 | if (!initialized) { 27 | lprintf("Mempool not initialized!\n"); 28 | panic(); 29 | } 30 | 31 | if (align < sizeof(ulong)) { 32 | align = sizeof(ulong); 33 | } 34 | 35 | if (align) { 36 | size = ALIGN_UP(size, align); 37 | } 38 | 39 | if (mempool_offset + size > mempool_size) { 40 | return NULL; 41 | } 42 | 43 | ulong result = mempool_virt_base + mempool_offset; 44 | mempool_offset += size; 45 | 46 | return (void *)result; 47 | } 48 | 49 | void *mempool_to_phys(void *virt) 50 | { 51 | if (!initialized) { 52 | lprintf("Mempool not initialized!\n"); 53 | panic(); 54 | } 55 | 56 | ulong result = (ulong)virt; 57 | 58 | if (mempool_phys_base > mempool_virt_base) { 59 | result += mempool_phys_base - mempool_virt_base; 60 | } else { 61 | result -= mempool_virt_base - mempool_phys_base; 62 | } 63 | 64 | return (void *)result; 65 | } 66 | -------------------------------------------------------------------------------- /src/loader/periph/bcm2835/bcm2835.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/periph/bcm2835.h" 3 | 4 | 5 | // RPi 2 6 | // Base @ 0x3F000000ul 7 | // End @ 0x3FFFFFFFul 8 | 9 | void init_bcm2835(ulong bcm2835_base, ulong bcm2835_end) 10 | { 11 | init_bcm2835_timer(bcm2835_base); 12 | init_bcm2835_mailbox(bcm2835_base); 13 | init_bcm2835_gpio(bcm2835_base); 14 | // init_bcm2835_uart(bcm2835_base); 15 | init_bcm2835_pl011(bcm2835_base); 16 | init_bcm2835_led(); 17 | init_bcm2835_framebuffer(bcm2835_end); 18 | 19 | bcm2835_maximize_cpu_clock(); 20 | } 21 | 22 | 23 | /* 24 | void hardware_init(void) { 25 | int32_t board_revision; 26 | 27 | #if defined ( RPI2 ) || defined ( RPI3 ) 28 | #ifndef ARM_ALLOW_MULTI_CORE 29 | // put all secondary cores to sleep 30 | uint8_t core_number = 1; 31 | for (core_number = 1 ; core_number < 4; core_number ++) { 32 | *(uint32_t *) (SMP_CORE_BASE + (core_number * 0x10)) = (uint32_t) _init_core; 33 | } 34 | #endif 35 | #endif 36 | (void) console_init(); 37 | 38 | hardware_init_startup_micros = bcm2835_st_read(); 39 | 40 | sys_time_init(); 41 | 42 | bcm2835_rng_init(); 43 | 44 | (void) bcm2835_vc_set_power_state(BCM2835_VC_POWER_ID_SDCARD, BCM2835_VC_SET_POWER_STATE_ON_WAIT); 45 | 46 | 47 | } 48 | */ 49 | -------------------------------------------------------------------------------- /src/loader/periph/bcm2835/led.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/periph/bcm2835.h" 3 | 4 | 5 | enum bcm2835_led_type { 6 | BCM2835_LED_ORIGINAL, 7 | BCM2835_LED_PLUS, 8 | BCM2835_LED_GPIO_VIRT, 9 | BCM2835_LED_UNKNOWN, 10 | }; 11 | 12 | 13 | static enum bcm2835_led_type led_type = BCM2835_LED_UNKNOWN; 14 | 15 | 16 | void init_bcm2835_led() 17 | { 18 | u32 board_rev = bcm2835_get_board_revision(); 19 | if ((board_rev == 0xa02082) || (board_rev == 0xa22082)) { 20 | led_type = BCM2835_LED_GPIO_VIRT; 21 | } else if (board_rev > 0x00000f) { 22 | led_type = BCM2835_LED_PLUS; 23 | } 24 | 25 | bcm2835_led_off(); 26 | } 27 | 28 | void bcm2835_led_on() 29 | { 30 | switch (led_type) { 31 | case BCM2835_LED_ORIGINAL: 32 | bcm2835_gpio_led_set(); 33 | break; 34 | case BCM2835_LED_PLUS: 35 | bcm2835_gpio_led_clear(); 36 | break; 37 | case BCM2835_LED_GPIO_VIRT: 38 | default: 39 | break; 40 | } 41 | } 42 | 43 | void bcm2835_led_off() 44 | { 45 | switch (led_type) { 46 | case BCM2835_LED_ORIGINAL: 47 | bcm2835_gpio_led_clear(); 48 | break; 49 | case BCM2835_LED_PLUS: 50 | bcm2835_gpio_led_set(); 51 | break; 52 | case BCM2835_LED_GPIO_VIRT: 53 | default: 54 | break; 55 | } 56 | } 57 | 58 | void bcm2835_led_blink(int times, int interval_ms) 59 | { 60 | int i; 61 | int us = (interval_ms ? interval_ms : 300) * 1000; 62 | 63 | for (i = 0; i < times || !times; i++) { 64 | bcm2835_delay(us); 65 | bcm2835_led_on(); 66 | bcm2835_delay(us); 67 | bcm2835_led_off(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/loader/periph/bcm2835/timer.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/periph/bcm2835.h" 3 | 4 | 5 | #define BCM2835_TIMER_BASE (0x3000) 6 | 7 | 8 | struct bcm2835_timer { 9 | volatile u32 control_status; 10 | volatile u32 counter_lo; 11 | volatile u32 counter_hi; 12 | volatile u32 compare0; 13 | volatile u32 compare1; 14 | volatile u32 compare2; 15 | volatile u32 compare3; 16 | }; 17 | 18 | 19 | static volatile struct bcm2835_timer *timer; 20 | 21 | 22 | void init_bcm2835_timer(ulong bcm2835_base) 23 | { 24 | timer = (void *)(bcm2835_base + BCM2835_TIMER_BASE); 25 | } 26 | 27 | u64 bcm2835_timer_read() 28 | { 29 | u32 hi = timer->counter_hi; 30 | u32 lo = timer->counter_lo; 31 | while (timer->counter_hi != hi) { 32 | hi = timer->counter_hi; 33 | } 34 | 35 | u64 t = ((u64)hi << 32) | (u64)lo; 36 | return t; 37 | } 38 | 39 | void bcm2835_delay(u32 d) 40 | { 41 | const u64 cmp = bcm2835_timer_read() + (u64)d; 42 | u64 cur = 0; 43 | do { 44 | cur = bcm2835_timer_read(); 45 | } while (cur && cur < cmp); 46 | } 47 | -------------------------------------------------------------------------------- /src/mach/generic/README.md: -------------------------------------------------------------------------------- 1 | The *generic* machine does not have any machine-specific implementation. 2 | It is implemented in the arch-specific implementation. 3 | -------------------------------------------------------------------------------- /src/mach/malta/spaceholder: -------------------------------------------------------------------------------- 1 | This is a place holder 2 | -------------------------------------------------------------------------------- /src/mach/pc/spaceholder: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/mach/raspi2/hal/include/periph.h: -------------------------------------------------------------------------------- 1 | #ifndef __MACH_RASPI2_HAL_INCLUDE_PERIPH__ 2 | #define __MACH_RASPI2_HAL_INCLUDE_PERIPH__ 3 | 4 | 5 | extern void init_periph(); 6 | extern void start_periph(); 7 | 8 | extern int periph_get_irq_vector(); 9 | extern int periph_get_fiq_vector(); 10 | 11 | extern int periph_detect_num_cpus(); 12 | extern void periph_waekup_cpu(int cpu_id, ulong entry); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/mach/sun4m/loader/periph.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "loader/include/obp.h" 3 | #include "loader/include/print.h" 4 | 5 | 6 | void draw_char(char ch) 7 | { 8 | obp_draw_char(ch); 9 | } 10 | -------------------------------------------------------------------------------- /src/shell/builtin/builtin.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/string.h" 5 | #include "shell/include/builtin.h" 6 | 7 | 8 | #define BUILTIN_CMD_COUNT (sizeof(builtin_cmd_list) / sizeof(struct builtin_cmd)) 9 | 10 | 11 | struct builtin_cmd { 12 | char *name; 13 | int (*func)(int argc, char **argv); 14 | }; 15 | 16 | static struct builtin_cmd builtin_cmd_list[] = { 17 | { "hello", hello }, 18 | { "welcome", hello }, 19 | { "toddler", hello }, 20 | { "logo", hello }, 21 | { "echo", echo }, 22 | { "ls", ls }, 23 | { "cat", cat }, 24 | { "touch", touch }, 25 | { "cd", cd }, 26 | { "pwd", pwd }, 27 | { "rm", rm }, 28 | { "mv", mv }, 29 | { "date", date }, 30 | }; 31 | 32 | 33 | int find_builtin_cmd(char *name) 34 | { 35 | int i; 36 | 37 | // Built-in commands 38 | for (i = 0; i < BUILTIN_CMD_COUNT; i++) { 39 | struct builtin_cmd *c = &builtin_cmd_list[i]; 40 | if (!strcmp(c->name, name)) { 41 | return i; 42 | } 43 | } 44 | 45 | return -1; 46 | } 47 | 48 | int exec_builtin_cmd(int index, int argc, char **argv) 49 | { 50 | struct builtin_cmd *c = &builtin_cmd_list[index]; 51 | return c->func(argc, argv); 52 | } 53 | -------------------------------------------------------------------------------- /src/shell/builtin/cd.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/stdlib.h" 5 | #include "klibc/include/string.h" 6 | #include "klibc/include/sys.h" 7 | #include "shell/include/shell.h" 8 | 9 | 10 | int cd(int argc, char **argv) 11 | { 12 | int err = EOK; 13 | 14 | if (argc < 2) { 15 | return EOK; 16 | } 17 | 18 | // Find out the new cwd 19 | char *join = NULL; 20 | char *new_dir = NULL; 21 | char *dir = argv[1]; 22 | if (is_absolute_path(dir)) { 23 | join = strdup(dir); 24 | } else { 25 | char *cwd = get_cwd(); 26 | join = join_path(cwd, dir); 27 | free(cwd); 28 | } 29 | 30 | // Normalize 31 | new_dir = normalize_path(join); 32 | free(join); 33 | 34 | // Try opening the dir 35 | err = change_cwd(new_dir); 36 | 37 | // Clean up 38 | free(new_dir); 39 | 40 | return err; 41 | } 42 | -------------------------------------------------------------------------------- /src/shell/builtin/date.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/time.h" 5 | #include "shell/include/shell.h" 6 | 7 | 8 | int date(int argc, char **argv) 9 | { 10 | time_t t = time(); 11 | 12 | #if (ARCH_WIDTH == 64) 13 | kprintf("Timestamp: %lu\n",(unsigned long)t); 14 | #else 15 | kprintf("Timestamp: %lu%lu\n", 16 | (unsigned long)(t >> (sizeof(unsigned long) * 8)), 17 | (unsigned long)t 18 | ); 19 | #endif 20 | 21 | return EOK; 22 | } 23 | -------------------------------------------------------------------------------- /src/shell/builtin/echo.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/sys.h" 5 | #include "shell/include/shell.h" 6 | 7 | 8 | int echo(int argc, char **argv) 9 | { 10 | int i; 11 | 12 | for (i = 0; i < argc; i++) { 13 | if (i) { 14 | kprintf(" "); 15 | } 16 | 17 | kprintf("%s", argv[i]); 18 | } 19 | kprintf("\n"); 20 | 21 | return EOK; 22 | } 23 | -------------------------------------------------------------------------------- /src/shell/builtin/hello.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/sys.h" 5 | #include "shell/include/shell.h" 6 | 7 | 8 | int hello(int argc, char **argv) 9 | { 10 | int i; 11 | 12 | kprintf("This is Toddler shell!\n"); 13 | welcome(); 14 | 15 | if (argc) { 16 | kprintf("Args (%d): ", argc); 17 | for (i = 0; i < argc; i++) { 18 | if (i) { 19 | kprintf(", "); 20 | } 21 | 22 | kprintf("%s", argv[i]); 23 | } 24 | kprintf("\n"); 25 | } 26 | 27 | return EOK; 28 | } 29 | -------------------------------------------------------------------------------- /src/shell/builtin/pwd.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/stdlib.h" 5 | #include "klibc/include/sys.h" 6 | #include "shell/include/shell.h" 7 | 8 | 9 | int pwd(int argc, char **argv) 10 | { 11 | char *cwd = get_cwd(); 12 | kprintf("%s\n", cwd); 13 | free(cwd); 14 | 15 | return EOK; 16 | } 17 | -------------------------------------------------------------------------------- /src/shell/builtin/rm.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/errno.h" 3 | #include "klibc/include/stdio.h" 4 | #include "klibc/include/stdlib.h" 5 | #include "klibc/include/sys.h" 6 | #include "shell/include/shell.h" 7 | 8 | 9 | static int do_rm(char *name) 10 | { 11 | unsigned long id = open_path(name, 0); 12 | // kprintf("Open: %p\n", id); 13 | 14 | int err = kapi_urs_remove(id, 0); 15 | return err; 16 | } 17 | 18 | int rm(int argc, char **argv) 19 | { 20 | int err = EOK; 21 | 22 | if (argc > 1) { 23 | int i; 24 | 25 | for (i = 1; i < argc; i++) { 26 | err = do_rm(argv[i]); 27 | if (err != EOK) { 28 | break; 29 | } 30 | } 31 | } 32 | 33 | return err; 34 | } 35 | -------------------------------------------------------------------------------- /src/shell/include/builtin.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHELL_INCLUDE_BUILTIN__ 2 | #define __SHELL_INCLUDE_BUILTIN__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | extern int find_builtin_cmd(char *name); 9 | extern int exec_builtin_cmd(int index, int argc, char **argv); 10 | 11 | extern int hello(int argc, char **argv); 12 | extern int echo(int argc, char **argv); 13 | extern int ls(int argc, char **argv); 14 | extern int cat(int argc, char **argv); 15 | extern int touch(int argc, char **argv); 16 | extern int cd(int argc, char **argv); 17 | extern int pwd(int argc, char **argv); 18 | extern int rm(int argc, char **argv); 19 | extern int mv(int argc, char **argv); 20 | extern int date(int argc, char **argv); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/shell/include/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef __SHELL_INCLUDE_SHELL__ 2 | #define __SHELL_INCLUDE_SHELL__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * Main 10 | */ 11 | extern void welcome(); 12 | 13 | 14 | /* 15 | * Control routines 16 | */ 17 | extern int exec_cmd(char *cmd, int argc, char **argv); 18 | extern int parse_cmd(char *in, char **cmd, int *argc, char ***argv, char **stdin, char **stdout, char **stderr); 19 | extern int free_cmd(char *cmd, int argc, char **argv, char *in, char *out, char *err); 20 | 21 | 22 | /* 23 | * Path manipulation 24 | */ 25 | extern int is_valid_path(const char *path); 26 | extern int is_absolute_path(const char *path); 27 | extern int is_relative_path(const char *path); 28 | extern char *join_path(const char *a, const char *b); 29 | extern char *normalize_path(const char *path); 30 | 31 | 32 | /* 33 | * Working directory 34 | */ 35 | extern void init_cwd(); 36 | extern char *get_cwd(); 37 | extern int change_cwd(char *path); 38 | 39 | 40 | /* 41 | * Path operation helpers 42 | */ 43 | extern unsigned long open_path(char *name, unsigned int flags); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/system/fs/procfs/procfs.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/proc.h" 3 | #include "common/include/errno.h" 4 | #include "common/include/urs.h" 5 | #include "common/include/ua.h" 6 | #include "klibc/include/stdio.h" 7 | #include "klibc/include/stdlib.h" 8 | #include "klibc/include/string.h" 9 | #include "klibc/include/stdstruct.h" 10 | #include "klibc/include/assert.h" 11 | #include "klibc/include/time.h" 12 | #include "klibc/include/sys.h" 13 | #include "system/include/urs.h" 14 | #include "system/include/fs.h" 15 | 16 | 17 | struct procfs_node { 18 | }; 19 | 20 | void init_procfs() 21 | { 22 | init_process_monitor(); 23 | } 24 | -------------------------------------------------------------------------------- /src/system/include/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSTEM_INCLUDE_FS__ 2 | #define __SYSTEM_INCLUDE_FS__ 3 | 4 | 5 | #include "common/include/data.h" 6 | 7 | 8 | /* 9 | * CoreimgFS 10 | */ 11 | extern void init_coreimgfs(); 12 | 13 | 14 | /* 15 | * RamFS 16 | */ 17 | extern void init_ramfs(); 18 | extern int register_ramfs(char *path); 19 | extern int unregister_ramfs(char *path); 20 | extern void test_ramfs(); 21 | 22 | 23 | /* 24 | * ProcFS 25 | */ 26 | extern void init_procfs(); 27 | extern void init_process_monitor(); 28 | 29 | 30 | /* 31 | * FAT 12/16/32 32 | */ 33 | 34 | 35 | /* 36 | * EXT 2/3 37 | */ 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/system/include/kapi.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSTEM_INCLUDE_KAPI__ 2 | #define __SYSTEM_INCLUDE_KAPI__ 3 | 4 | #include "common/include/data.h" 5 | #include "common/include/syscall.h" 6 | 7 | 8 | /* 9 | * Init KAPI 10 | */ 11 | extern void init_kapi(); 12 | 13 | 14 | /* 15 | * URS 16 | */ 17 | extern asmlinkage void urs_reg_super_handler(msg_t *s); 18 | extern asmlinkage void urs_reg_op_handler(msg_t *s); 19 | 20 | extern asmlinkage void urs_open_handler(msg_t *s); 21 | extern asmlinkage void urs_close_handler(msg_t *s); 22 | extern asmlinkage void urs_read_handler(msg_t *s); 23 | extern asmlinkage void urs_write_handler(msg_t *s); 24 | extern asmlinkage void urs_list_handler(msg_t *s); 25 | 26 | extern asmlinkage void urs_create_handler(msg_t *s); 27 | extern asmlinkage void urs_remove_handler(msg_t *s); 28 | extern asmlinkage void urs_rename_handler(msg_t *s); 29 | 30 | extern asmlinkage void urs_stat_handler(msg_t *s); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/system/kapi/kapi.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "common/include/syscall.h" 3 | #include "klibc/include/sys.h" 4 | #include "klibc/include/stdio.h" 5 | #include "system/include/kapi.h" 6 | 7 | 8 | void init_kapi() 9 | { 10 | // kapi_reg(KAPI_FILE_WRITE, kapi_write_handler); 11 | 12 | // URS 13 | kapi_reg(KAPI_URS_REG_SUPER, urs_reg_super_handler); 14 | 15 | kapi_reg(KAPI_URS_OPEN, urs_open_handler); 16 | kapi_reg(KAPI_URS_CLOSE, urs_close_handler); 17 | kapi_reg(KAPI_URS_READ, urs_read_handler); 18 | kapi_reg(KAPI_URS_WRITE, urs_write_handler); 19 | kapi_reg(KAPI_URS_LIST, urs_list_handler); 20 | 21 | kapi_reg(KAPI_URS_CREATE, urs_create_handler); 22 | kapi_reg(KAPI_URS_REMOVE, urs_remove_handler); 23 | kapi_reg(KAPI_URS_RENAME, urs_rename_handler); 24 | 25 | kapi_reg(KAPI_URS_STAT, urs_stat_handler); 26 | } 27 | 28 | 29 | // char **environ; 30 | 31 | /* 32 | * Process 33 | */ 34 | // int fork(); 35 | // int execve(char *name, char **argv, char **env); 36 | // int kill(int pid, int sig); 37 | // int wait(int *status); 38 | // caddr_t sbrk(int incr); 39 | // void _exit(); 40 | // int getpid(); 41 | 42 | 43 | /* 44 | * Time 45 | */ 46 | // clock_t times(struct tms *buf); 47 | // int gettimeofday(struct timeval *p, struct timezone *z); 48 | 49 | -------------------------------------------------------------------------------- /src/system/system.c: -------------------------------------------------------------------------------- 1 | #include "common/include/data.h" 2 | #include "klibc/include/stdio.h" 3 | #include "klibc/include/sys.h" 4 | #include "klibc/include/kthread.h" 5 | #include "system/include/kapi.h" 6 | #include "system/include/urs.h" 7 | #include "system/include/fs.h" 8 | 9 | 10 | static unsigned long thread_test(unsigned long arg) 11 | { 12 | // __asm__ __volatile__ 13 | // ( 14 | // "xchgw %%bx, %%bx;" 15 | // : 16 | // : 17 | // ); 18 | 19 | kprintf("From thread test, arg: %lu\n", arg); 20 | return 0; 21 | } 22 | 23 | int main(int argc, char *argv[]) 24 | { 25 | int i = 0; 26 | char buf[64]; 27 | 28 | kprintf("Toddler system process started!\n"); 29 | 30 | // Initialize 31 | init_kapi(); 32 | init_urs(); 33 | init_coreimgfs(); 34 | init_ramfs(); 35 | init_procfs(); 36 | 37 | // FS tests 38 | //test_ramfs(); 39 | 40 | // u64 t = get_systime(); 41 | // unsigned long time_high = 0, time_low = 0; 42 | // syscall_time(&time_high, &time_low); 43 | // kprintf("Time: %x %x\n", (unsigned long)(t >> 32), (unsigned long)t); 44 | 45 | // Init done 46 | kprintf("System process initialized!\n"); 47 | kapi_process_started(0); 48 | 49 | // // Thread test 50 | // kthread_t thread; 51 | // for (i = 0; i < 2; i++) { 52 | // kthread_create(&thread, thread_test, (unsigned long)i); 53 | // } 54 | 55 | // Block here 56 | do { 57 | syscall_yield(); 58 | } while (1); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /tools/tmake.tools: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | tools_tools = { \ 5 | '.c' : { \ 6 | 'exec' : 'gcc', 7 | 'flags' : '', 8 | 'inc' : '-I__inc__', 9 | 'direct': '__src__', 10 | 'obj' : '-o __obj__ __src__', 11 | 'dep' : '-MM __src__ > __dep__', 12 | }, 13 | } 14 | 15 | 16 | def build_tools(): 17 | # Core image generator 18 | print_info('tool.coreimg', 'Building core image tool') 19 | direct_build_files( 20 | [ tools_src_dir + 'coreimg.c' ], 21 | tools_bin_dir + 'coreimg', 22 | tools = arch_tools['tools_tools'] 23 | ) 24 | 25 | # Floppy image generator 26 | print_info('tool.floppyimg', 'Building floppy image tool') 27 | direct_build_files( 28 | [ tools_src_dir + 'floppyimg.c' ], 29 | tools_bin_dir + 'floppyimg', 30 | tools = arch_tools['tools_tools'] 31 | ) 32 | 33 | 34 | # Setup arch tools 35 | arch_tools['tools_tools'] = tools_tools 36 | 37 | # Setup callback functions 38 | arch_funcs['build_tools'] = build_tools 39 | --------------------------------------------------------------------------------