{
char *str;
unsigned int v;
+ unsigned long l;
char c;
va_list ap;
fmt++;
continue;
}
+ if ((*fmt == 'l') && (*(fmt+1) == 'x')) {
+ l = va_arg(ap, unsigned long);
+ /* TODO: not 32-bit safe */
+ kputhex((uint16_t)(l >> 16));
+ kputhex((uint16_t)l);
+ fmt += 2;
+ }
if (*fmt == 'x' || *fmt == 'd' || *fmt == 'u') {
v = va_arg(ap, int);
if (*fmt == 'x')
U_DATA = udata
-; Keep these in sync with struct u_data!!
-#define U_DATA__U_PTAB (U_DATA+0) ; struct p_tab*
-#define U_DATA__U_PAGE (U_DATA+2) ; uint16_t
-#define U_DATA__U_PAGE2 (U_DATA+4) ; uint16_t
-#define U_DATA__U_INSYS (U_DATA+6) ; bool
-#define U_DATA__U_CALLNO (U_DATA+7) ; uint8_t
-#define U_DATA__U_SYSCALL_SP (U_DATA+8) ; void *
-#define U_DATA__U_RETVAL (U_DATA+10) ; int16_t
-#define U_DATA__U_ERROR (U_DATA+12) ; int16_t
-#define U_DATA__U_SP (U_DATA+14) ; void *
-#define U_DATA__U_ININTERRUPT (U_DATA+16) ; bool
-#define U_DATA__U_CURSIG (U_DATA+17) ; int8_t
-#define U_DATA__U_ARGN (U_DATA+18) ; uint16_t
-#define U_DATA__U_ARGN1 (U_DATA+20) ; uint16_t
-#define U_DATA__U_ARGN2 (U_DATA+22) ; uint16_t
-#define U_DATA__U_ARGN3 (U_DATA+24) ; uint16_t
-#define U_DATA__U_ISP (U_DATA+26) ; void * (initial stack pointer when _exec()ing)
-#define U_DATA__U_TOP (U_DATA+28) ; uint16_t
-#define U_DATA__U_BREAK (U_DATA+30) ; uint16_t
-#define U_DATA__U_SIGVEC (U_DATA+32) ; table of function pointers (void *)
+// Keep these in sync with struct u_data!!
+#define U_DATA__U_PTAB (U_DATA+0) // struct p_tab*
+#define U_DATA__U_PAGE (U_DATA+2) // uint16_t
+#define U_DATA__U_PAGE2 (U_DATA+4) // uint16_t
+#define U_DATA__U_INSYS (U_DATA+6) // bool
+#define U_DATA__U_CALLNO (U_DATA+7) // uint8_t
+#define U_DATA__U_SYSCALL_SP (U_DATA+8) // void *
+#define U_DATA__U_RETVAL (U_DATA+10) // int16_t
+#define U_DATA__U_ERROR (U_DATA+12) // int16_t
+#define U_DATA__U_SP (U_DATA+14) // void *
+#define U_DATA__U_ININTERRUPT (U_DATA+16) // bool
+#define U_DATA__U_CURSIG (U_DATA+17) // int8_t
+#define U_DATA__U_ARGN (U_DATA+18) // uint16_t
+#define U_DATA__U_ARGN1 (U_DATA+20) // uint16_t
+#define U_DATA__U_ARGN2 (U_DATA+22) // uint16_t
+#define U_DATA__U_ARGN3 (U_DATA+24) // uint16_t
+#define U_DATA__U_ISP (U_DATA+26) // void * (initial stack pointer when _exec()ing)
+#define U_DATA__U_TOP (U_DATA+28) // uint16_t
+#define U_DATA__U_BREAK (U_DATA+30) // uint16_t
+#define U_DATA__U_SIGVEC (U_DATA+32) // table of function pointers (void *)
-; Keep these in sync with struct p_tab!!
+// Keep these in sync with struct p_tab!!
P_TAB__P_STATUS_OFFSET = 0
P_TAB__P_TTY_OFFSET = 1
P_TAB__P_PID_OFFSET = 2
P_TAB__P_PAGE_OFFSET = 14
-P_RUNNING = 1 ; value from include/kernel.h
-P_READY = 2 ; value from include/kernel.h
+P_RUNNING = 1 // value from include/kernel.h
+P_READY = 2 // value from include/kernel.h
-OS_BANK = 0 ; value from include/kernel.h
+OS_BANK = 0 // value from include/kernel.h
-EAGAIN = 11 ; value from include/kernel.h
+EAGAIN = 11 // value from include/kernel.h
+#include "platform-msp430fr5969/kernel.def"
#include "kernel430x.def"
.section ".lowtext"
* may be the user process or the kernel's. We haven't saved any
* registers yet. */
- mov SP, &istack_switched_sp ; save old stack (16 bit!)
+ movx.w SP, &istack_switched_sp ; save old stack (16 bit!)
mov #istack_top, SP ; load new one
pushm.a #13, r15 ; save all registers (r15 to r3)
popm.a #13, r15 ; restore all registers (r15 to r3)
- mov &istack_switched_sp, SP ; restore stack
+ movx.w &istack_switched_sp, SP ; restore stack
reti
+proc doexec
+ dint
+ #if 0
+ di
+ call map_process_always
+
+ pop bc ; return address
+ pop de ; start address
+
+ ld hl, (U_DATA__U_ISP)
+ ld sp, hl ; Initialize user stack, below main() parameters and the environment
+
+ ; u_data.u_insys = false
+ xor a
+ ld (U_DATA__U_INSYS), a
+
+ ex de, hl
+
+ ; for the relocation engine - tell it where it is
+ ld iy, #PROGLOAD
+ ei
+ jp (hl)
+#endif
+ jmp .
../dev/mbr.c \
../devio.c \
../filesys.c \
+ ../inode.c \
../lowlevel-msp430x.S \
../kdata.c \
../process.c \
../simple.c \
../start.c \
../swap.c \
+ ../syscall_exec16.c \
+ ../syscall_fs.c \
../timer.c \
../tty.c \
../usermem.c \
-mlarge
kernel.ldflags += \
- -g
+ -s
kernel.libgcc = $(shell $(TARGETCC) -mlarge --print-libgcc)
kernel.result = $(TOP)/kernel-$(PLATFORM).elf
extern int __user_base;
#define TICKSPERSEC 64 /* Ticks per second */
-#define PROGBASE ((uint16_t)(size_t)&__user_base) /* also data base */
+#define PROGBASE ((uint32_t)(size_t)&__user_base) /* also data base */
#define PROGLOAD PROGBASE /* also data base */
#define PROGTOP 0xfe00 /* Top of program */
.globl init_early
.globl init_hardware
-; Set up the stacks.
-
-
.section ".noinit"
; The interrupt stack.
.globl istack_switched_sp
.comm istack_switched_sp, 2
-; The userdata/system stack structure. See Kernel/include/kernel.h.
-.globl udata
-udata:
- .fill 512
-kstack_top:
-
-.text
+.section ".lowtext", "ax", @progbits
.globl __main
__main:
; Disable watchdog timer.
mov.b #0, &CSCTL0_H ; Relock clock registers
; Init stack.
- mov #kstack_top, SP
+ movx.a #kstack_top, SP
; Wipe BSS.
- mov #__bssstart, r12
- mov #0, r13
- mov #__bsssize, r14
- calla #memset
-
- ; Wipe the extra, big bit of BSS.
- mov #__bigbssstart, r12
+ movx.a #__bssstart, r12
mov #0, r13
- mov #__bigbsssize, r14
+ movx.a #__bsssize, r14
calla #memset
; Set some kernel variables.
- mov.w #64, &ramsize
- mov.w #32, &procmem
+ movx.w #64, &ramsize
+ movx.w #32, &procmem
; Call C routines.
calla #tty_rawinit
__reti:
reti
-.globl trap_monitor
-trap_monitor:
+proc trap_monitor
bic.w #GIE, SR
jmp trap_monitor
-.globl abort
-abort:
+proc abort
bic.w #GIE, SR
- mov #1f, r12
- mov #kstack_top, sp
+ movx.a #1f, r12
+ movx.a #kstack_top, sp
calla #kprintf
jmp .
-.data
+.data 1
1: .asciz "[abort]\n"
.text
-.globl ei
-ei:
+proc ei
bis.w #GIE, SR
reta
-.globl di
-di:
+proc di
; Return the old interrupt status in r12.
mov SR, r12
and #~GIE, r12
bic.w #GIE, SR
reta
-.globl irqrestore
-irqrestore:
+proc irqrestore
bic.w #GIE, SR ; Ensure off
bis.w r12, SR ; Mask in saved value
reta
#define standard_interrupt(name, irq) \
.globl name ## _trampoline { \
- .section ".lowtext", "ax", @progbits { \
+ .section ".lowtext" { \
name ## _trampoline: \
- mov.b #(irq), &last_interrupt { \
+ movx.b #(irq), &last_interrupt { \
bra #interrupt_handler { \
.section #name, "ax", @progbits { \
.word name ## _trampoline
#define fallback_interrupt(name) \
- .text { \
- 1: mov #3f, r12 { \
- mov #kstack_top, sp { \
+ .section ".lowtext" { \
+ 1: movx.a #3f, r12 { \
+ movx.a #kstack_top, sp { \
calla #kprintf { \
2: jmp 2b { \
.data { \
U_DATA = udata
+.macro proc NAME
+ .section .text.\NAME
+ .globl \NAME
+ \NAME:
+.endm
+
BSL : ORIGIN = 0x1000, LENGTH = 0x0800
SRAM : ORIGIN = 0x1C00, LENGTH = 0x0800 /* END=0x23FF, size 2048 */
- LOROM : ORIGIN = 0x4400, LENGTH = 0x8000-0x4400
+ LOROM : ORIGIN = 0x4400, LENGTH = 0x7e00-0x4400
+ UDATA : ORIGIN = 0x7e00, LENGTH = 0x015c
+ SYSCALL : ORIGIN = 0x7ffc, LENGTH = 0x0004
USER : ORIGIN = 0x8000, LENGTH = 0xfe00-0x8000
LOROMX : ORIGIN = 0xfe00, LENGTH = 0xff80-0xfe00
HIROM : ORIGIN = 0x10000, LENGTH = 0x3FFF
PROVIDE(__user_base = ORIGIN(USER));
PROVIDE(__user_length = LENGTH(USER));
+PROVIDE(udata = ORIGIN(UDATA));
+PROVIDE(kstack_top = ORIGIN(UDATA) + LENGTH(UDATA));
SECTIONS
{
KEEP (*(.resetvec))
} > RESETVEC
+
.rodata : {
. = ALIGN(2);
*(.plt)
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
- } > HIROM
+ } > LOROM
+
+ .lowtext : {
+ . = ALIGN(2);
+ PROVIDE (_start = .);
+ *(.lowtext)
+ } > LOROM
.text : {
. = ALIGN(2);
- PROVIDE (_start = .);
KEEP (*(SORT(.crt_*)))
- *(.lowtext .text .stub .text.* .gnu.linkonce.t.* .text:*)
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
KEEP (*(.init))
KEEP (*(.fini))
KEEP (*(.tm_clone_table))
- } > LOROM
+ } > HIROM
.data : {
. = ALIGN(2);
} > LOROM
PROVIDE (__bsssize = SIZEOF(.bss));
- .bigbss (NOLOAD) : {
- . = ALIGN(2);
- PROVIDE (__bigbssstart = .);
- *(.bigbss .bigbss.*)
- . = ALIGN(2);
- PROVIDE (__bigbssend = .);
- } > LOROM
- PROVIDE (__bigbsssize = SIZEOF(.bigbss));
-
.noinit (NOLOAD) : {
. = ALIGN(2);
PROVIDE (__noinit_start = .);
bic.w #GIE, SR ; interrupts off
mov #0, r12 ; set return code
pushm.a #12, r15 ; save all registers (r15 to r4)
- pushx.a SR ; ...and the status register
- mova SP, &U_DATA__U_SP ; save stack pointer
+ push SR ; ...and the status register
+ movx SP, &U_DATA__U_SP ; save stack pointer
clra &inint
;calla #getproc
- calla #switchin ; switch in new process
+ jmp switchin ; switch in new process
calla #trap_monitor ; should never reach here
.globl switchin
switchin:
bic.w #GIE, SR ; interrupts off
- mova &U_DATA__U_SP, SP ; restore stack pointer
- popx.a SR ; restore status register
+ movx &U_DATA__U_SP, SP ; restore stack pointer
+ pop SR ; restore status register
popm.a #12, r15 ; restore all registers (r15 to r4)
bis.w #GIE, SR ; interrupts on
reta
*j = NO_FILE;
}
/* Poke the execve arguments into user data space so _execve() can read them back */
+ kprintf("PROGLOAD=%lx\n", (void*)PROGLOAD);
uput(arg, (void *)PROGLOAD, sizeof(arg));
/* Poke in argv[0] - FIXME: Endianisms... */
uputw(PROGLOAD+1 , (void *)(PROGLOAD + 7));
if (fmount(root_dev, NULLINODE, 0))
panic("no filesys");
-#if 0
root = i_open(root_dev, ROOTINODE);
if (!root)
panic("no root");
udata.u_root = i_ref(root);
rdtime32(&udata.u_time);
exec_or_die();
-#endif
}
static int header_ok(uint8_t *pp)
{
register uint8_t *p = pp;
- if (*p != EMAGIC && *p != EMAGIC_2)
- return 0;
+ #if defined(EMAGIC) || defined(EMAGIC_2)
+ if (*p != EMAGIC && *p != EMAGIC_2)
+ return 0;
+ #endif
p += 3;
if (*p++ != 'F' || *p++ != 'Z' || *p++ != 'X' || *p++ != '1')
return 0;
top = ramtop;
+ kprintf("name=%lx\n", name);
if (!(ino = n_open(name, NULLINOPTR)))
return (-1);