typedef int16_t susize_t;
typedef uint32_t clock_t;
-extern void ei(void);
+static inline void ei(void)
+{
+ asm volatile ("eint");
+}
+
+#if 0
+static inline irqflags_t di(void)
+{
+ irqflags_t flags;
+ asm volatile (
+ "mov SR, %0\n"
+ "dint\n"
+ : "=g" (flags));
+ return flags;
+}
+
+static inline void irqrestore(irqflags_t flags)
+{
+ asm volatile (
+ "dint\n"
+ "and #0x0008, %0\n"
+ "bis.w %0, SR\n"
+ : "+g" (flags));
+}
+#endif
+
extern irqflags_t di(void);
extern void irqrestore(irqflags_t f);
-
#undef EMAGIC /* No executable header for MSP430X */
+/* Allow a minimum of 512 bytes gap between stack and top of allocations */
+#define brk_limit() (udata.u_syscall_sp - 512)
+
extern void* memcpy(void*, const void*, size_t);
extern void* memset(void*, int, size_t);
extern size_t strlen(const char *);
#include <stdarg.h>
#include "iomacros.h"
#include "intrinsics.h"
+#include "msp430fr5969.h"
__interrupt void interrupt_handler(void)
{
"g" (start_addr));
}
+static void unix_syscall_main(uint16_t arg0, uint16_t arg1, uint16_t arg2,
+ uint16_t arg3)
+{
+ struct u_data* u = &udata;
+ u->u_argn = arg0;
+ u->u_argn1 = arg1;
+ u->u_argn2 = arg2;
+ u->u_argn3 = arg3;
+ ei();
+
+ unix_syscall();
+
+ di();
+}
+
__attribute__ ((naked)) void unix_syscall_entry(void)
{
asm volatile (
+ "dint\n"
"mov.b r11, %0\n"
- "mov r12, %1\n"
- "mov r13, %2\n"
- "mov r14, %3\n"
- "mov r15, %4\n"
- "jmp unix_syscall_main\n"
+ "mov.w sp, %1\n"
+ "movx.a #kstack_top, sp\n"
+ "calla %2\n"
+ "mov.w %1, sp\n"
+ "mov.w %3, r12\n"
+ "mov.w %4, r13\n"
+ "eint\n"
+ "reta\n"
: "=m" (udata.u_callno),
- "=m" (udata.u_argn),
- "=m" (udata.u_argn1),
- "=m" (udata.u_argn2),
- "=m" (udata.u_argn3)
- :
+ "=m" (udata.u_syscall_sp)
+ : "g" (unix_syscall_main),
+ "g" (udata.u_retval),
+ "g" (udata.u_error)
);
}
-void unix_syscall_main(void)
+int16_t dofork(ptptr child)
{
- kprintf("syscall %d(%x, %x, %x, %x)!\n", udata.u_callno,
- udata.u_argn, udata.u_argn1, udata.u_argn2, udata.u_argn3);
+ kprintf("dofork\n");
for (;;);
}
$(hide) (cd $(dir $@) && $(kernelversion.abssrcs) $(VERSION) $(SUBVERSION))
$(hide) mv $(dir $@)/version.c $@
-
kernel.srcs = \
../dev/blkdev.c \
../dev/devsd.c \
../inode.c \
../lowlevel-msp430x.c \
../kdata.c \
+ ../mm.c \
../process.c \
../simple.c \
../start.c \
../swap.c \
../syscall_exec16.c \
../syscall_fs.c \
+ ../syscall_fs2.c \
+ ../syscall_other.c \
+ ../syscall_proc.c \
../timer.c \
../tty.c \
../usermem.c \
-mlarge \
-Wno-int-to-pointer-cast \
-Wno-pointer-to-int-cast \
+ -fno-inline \
+ -fno-common \
-g \
kernel.asflags += \
#define CONFIG_SINGLETASK
#define PTABSIZE 1
+#define CONFIG_NO_STARTUP_MESSAGE
+
/* Simple user copies for now (change when ROM the kernel) */
#define CONFIG_USERMEM_DIRECT
-#define BANK_KERNEL
-#define BANK_PROCESS
+#define BANK_KERNEL /* */
+#define BANK_PROCESS /* */
/* Pure swap */
#define CONFIG_SWAP_ONLY
#undef CONFIG_VT
extern int __user_base;
+extern int __user_top;
#define TICKSPERSEC 64 /* Ticks per second */
-#define PROGBASE ((uint32_t)(size_t)&__user_base) /* also data base */
+#define PROGBASE ((uaddr_t)&__user_base) /* also data base */
#define PROGLOAD PROGBASE /* also data base */
-#define PROGTOP 0xfe00 /* Top of program */
+#define PROGTOP ((uaddr_t)&__user_top) /* Top of program */
-#define SWAPBASE ((uint16_t)&udata)
+#define SWAPBASE PROGBASE
#define SWAPTOP PROGTOP
#define SWAP_SIZE ((SWAPTOP - SWAPBASE)/512)
-#define MAX_SWAPS 32
+#define MAX_SWAPS 8
#define swap_map(x) ((uint8_t*)(x))
#define BOOT_TTY (512 + 1) /* Set this to default device for stdio, stderr */
#define NDEVS 1 /* Devices 0..NDEVS-1 are capable of being mounted */
/* (add new mountable devices to beginning area.) */
#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */
-#define NBUFS 6 /* Number of block buffers */
-#define NMOUNTS 2 /* Number of mounts at a time */
+#define NBUFS 4 /* Number of block buffers */
+#define NMOUNTS 1 /* Number of mounts at a time */
+#define UFTSIZE 4 /* Number of user files */
+#define OFTSIZE 7 /* Number of open files */
#define SD_DRIVE_COUNT 1
#define MAX_BLKDEV 1
.globl init_early
.globl init_hardware
-.section ".noinit"
-
-.section ".lowtext", "ax", @progbits
-.globl __main
-__main:
+lowproc trap_reboot
; Disable watchdog timer.
mov.w #(WDTPW | WDTHOLD), &WDTCTL
mov.b #0, &CSCTL0_H ; Relock clock registers
; Init stack.
- movx.a #kstack_top, SP
+ mov.a #kstack_top, SP
; Wipe BSS.
- movx.a #__bssstart, r12
+ mov.w #__bssstart, r12
+ mov #0, r13
+ mov.w #__bsssize, r14
+ calla #memset
+
+ mov.w #__bss2start, r12
mov #0, r13
- movx.a #__bsssize, r14
+ mov.w #__bss2size, r14
calla #memset
; Set some kernel variables.
- movx.w #64, &ramsize
- movx.w #32, &procmem
+ mov.w #64, &ramsize
+ mov.w #32, &procmem
; Call C routines.
calla #tty_rawinit
1: .asciz "[abort]\n"
.text
-proc ei
- bis.w #GIE, SR
- reta
-
proc di
; Return the old interrupt status in r12.
mov SR, r12
.long unix_syscall_entry
.section "__interrupt_vector_reset", "ax", @progbits
- .word __main
+ .word trap_reboot
.text
.globl last_interrupt
{ nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl },
/* 2: /dev/tty TTY devices */
{ tty_open, tty_close, tty_read, tty_write, tty_ioctl },
- /* 3: /dev/lpr Printer devices */
- { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl },
- /* 4: /dev/mem etc System devices (one offs) */
- { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl },
/* Pack to 7 with nxio if adding private devices and start at 8 */
};
U_DATA = udata
-.macro proc NAME
- .section .text.\NAME
- .globl \NAME
- \NAME:
+.macro proc n
+ .section ".text.\n", "ax", @progbits
+ .globl \n
+ \n:
+.endm
+
+.macro lowproc n
+ .section ".lowtext.\n", "ax", @progbits
+ .globl \n
+ \n:
.endm
#include <kdata.h>
#include <printf.h>
-uaddr_t ramtop = PROGTOP;
+uaddr_t ramtop;
void platform_idle(void)
{
RESETVEC : ORIGIN = 0xFFFE, LENGTH = 0x0002
BSL : ORIGIN = 0x1000, LENGTH = 0x0800
- SRAM : ORIGIN = 0x1C00, LENGTH = 0x0800 /* END=0x23FF, size 2048 */
- LOROM : ORIGIN = 0x4400, LENGTH = 0x7c00-0x4400
- UDATA : ORIGIN = 0x7c00, LENGTH = 0x7ffc-0x7c00
+ SRAMLO : ORIGIN = 0x1C00, LENGTH = 0x0400
+ SRAMHI : ORIGIN = 0x2000, LENGTH = 0x0400
+ LOROM : ORIGIN = 0x4400, LENGTH = 0x7ffc-0x4400
SYSCALL : ORIGIN = 0x7ffc, LENGTH = 0x0004
USER : ORIGIN = 0x8000, LENGTH = 0xfe00-0x8000
LOROMX : ORIGIN = 0xfe00, LENGTH = 0xff80-0xfe00
PROVIDE(__user_base = ORIGIN(USER));
PROVIDE(__user_length = LENGTH(USER));
-PROVIDE(udata = ORIGIN(UDATA));
-PROVIDE(kstack_top = ORIGIN(UDATA) + LENGTH(UDATA));
+PROVIDE(__user_top = ORIGIN(USER) + LENGTH(USER));
+PROVIDE(udata = ORIGIN(SRAMLO));
+PROVIDE(kstack_top = ORIGIN(SRAMLO) + LENGTH(SRAMLO));
SECTIONS
{
.rodata : {
. = ALIGN(2);
- *(.plt)
- *(.rodata .rodata.* .gnu.linkonce.r.* .const .const:*)
- *(.rodata1)
- *(.eh_frame_hdr)
- KEEP (*(.eh_frame))
- KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
- PROVIDE (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- PROVIDE (__fini_array_end = .);
- LONG(0); /* Sentinel. */
-
- /* gcc uses crtbegin.o to find the start of the constructors, so
- we make sure it is first. Because this is a wildcard, it
- doesn't matter if the user does not actually link against
- crtbegin.o; the linker won't look for a file to match a
- wildcard. The wildcard also means that it doesn't matter which
- directory crtbegin.o is in. */
- KEEP (*crtbegin*.o(.ctors))
-
- /* We don't want to include the .ctor section from from the
- crtend.o file until after the sorted ctors. The .ctor section
- from the crtend file contains the end of ctors marker and it
- must be last */
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
-
- KEEP (*crtbegin*.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
+ *(.rodata .rodata.* .const .const:*)
} > LOROM
.syscall : {
.lowtext : {
. = ALIGN(2);
PROVIDE (_start = .);
- *(.lowtext)
+ *(.lowtext .lowtext.*)
+ *(.text._*)
+ *(.text.kprintf)
+ *(.text.readi)
+ *(.text.writei)
+ *(.text.fuzix_main)
+ *(.text.sgrpsig)
} > LOROM
-
+
.text : {
. = ALIGN(2);
KEEP (*(SORT(.crt_*)))
- *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
- KEEP (*(.text.*personality*))
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.interp .hash .dynsym .dynstr .gnu.version*)
+ *(.text .text.* .text:*)
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
- . = ALIGN(2);
- KEEP (*(.init))
- KEEP (*(.fini))
- KEEP (*(.tm_clone_table))
} > HIROM
+ .sram : {
+ . = ALIGN(2);
+ PROVIDE (__bss2start = .);
+ *(.bss.ptab);
+ *(.bss.blk_op);
+ *(.bss.of_tab);
+ *(.bss.tbuf1);
+ . = ALIGN(2);
+ PROVIDE (__bss2end = .);
+ } > SRAMHI
+ PROVIDE (__bss2size = SIZEOF(.sram));
+
.data : {
. = ALIGN(2);
PROVIDE (__datastart = .);
- KEEP (*(.jcr))
- *(.data.rel.ro.local) *(.data.rel.ro*)
- *(.dynamic)
-
- *(.data .data.* .gnu.linkonce.d.*)
- KEEP (*(.gnu.linkonce.d.*personality*))
- SORT(CONSTRUCTORS)
- *(.data1)
- *(.got.plt) *(.got)
+ *(.data .data.*)
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
. = ALIGN(2);
- *(.sdata .sdata.* .gnu.linkonce.s.* D_2 D_1)
+ *(.sdata .sdata.*)
. = ALIGN(2);
_edata = .;
PROVIDE (edata = .);
PROVIDE (__dataend = .);
- } > LOROM AT>LOROM
+
+ *(COMMON)
+ } > LOROMX
/* Note that crt0 assumes this is a multiple of two; all the
start/stop symbols are also assumed word-aligned. */
.bss : {
. = ALIGN(2);
PROVIDE (__bssstart = .);
- *(.dynbss)
- *(.sbss .sbss.*)
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN(2);
- *(COMMON)
PROVIDE (__bssend = .);
} > LOROM
PROVIDE (__bsssize = SIZEOF(.bss));
- .noinit (NOLOAD) : {
- . = ALIGN(2);
- PROVIDE (__noinit_start = .);
- *(.noinit)
- . = ALIGN(2);
- PROVIDE (__noinit_end = .);
- end = .;
- } > SRAM
-
.MP430.attributes 0 :
{
KEEP (*(.MSP430.attributes))
panic("no tty");
/* Sign on messages */
+#ifndef CONFIG_NO_STARTUP_MESSAGE
kprintf(
"FUZIX version %s\n"
"Copyright (c) 1988-2002 by H.F.Bower, D.Braun, S.Nitschke, H.Peraza\n"
"Copyright (c) 2013-2015 Will Sowerbutts <will@sowerbutts.com>\n"
"Copyright (c) 2014-2015 Alan Cox <alan@etchedpixels.co.uk>\nDevboot\n",
uname_str);
+#endif
#ifndef SWAPDEV
#ifdef PROC_SIZE
ptab_end = &ptab[maxproc];
/* Parameters message */
- kprintf("kernel stack from %lx to %lx\n", (&udata+1), 0x7ffcL);
kprintf("%dkB total RAM, %dkB available to processes (%d processes max)\n", ramsize, procmem, maxproc);
bufinit();
fstabinit();
udata.u_count = 512;
udata.u_base = (uint8_t *)base;
- /* This is necessary on the MSP430. Why??? */
- *(uint8_t volatile*)base;
-
if (cdread(i->c_dev, 0) < 0) {
kputs("bload failed.\n");
return -1;