clock.c: now compiles even if address is bogus :)

conf.c: compiled, until prom addition :)
cons.c: add entry for prom driver
lib.s: remove some includes; we're being included by locore.s
locore.s: include asm.h, syscall.h, add icode
m68k.s: now included by locore.s
added signal.s; contains signal support
sun3_startup.c: fixed compile bug in vector table initialization; fixed mon
	usage
swapgeneric.c: doesn't refer to drivers we don't have
This commit is contained in:
glass 1993-06-27 00:46:09 +00:00
parent 4c06bc4b0d
commit e1fec74952
13 changed files with 753 additions and 64 deletions

285
sys/arch/m68k/m68k/copy.s Normal file
View File

@ -0,0 +1,285 @@
.text
/*
* copyinstr(fromaddr, toaddr, maxlength, &lencopied)
*
* Copy a null terminated string from the user address space into
* the kernel address space.
* NOTE: maxlength must be < 64K
*/
ENTRY(copyinstr)
movl _curpcb,a0 | current pcb
movl #Lcisflt1,a0@(PCB_ONFAULT) | set up to catch faults
movl sp@(4),a0 | a0 = fromaddr
movl sp@(8),a1 | a1 = toaddr
moveq #0,d0
movw sp@(14),d0 | d0 = maxlength
jlt Lcisflt1 | negative count, error
jeq Lcisdone | zero count, all done
subql #1,d0 | set up for dbeq
Lcisloop:
movsb a0@+,d1 | grab a byte
movb d1,a1@+ | copy it
dbeq d0,Lcisloop | if !null and more, continue
jne Lcisflt2 | ran out of room, error
moveq #0,d0 | got a null, all done
Lcisdone:
tstl sp@(16) | return length desired?
jeq Lcisret | no, just return
subl sp@(4),a0 | determine how much was copied
movl sp@(16),a1 | return location
movl a0,a1@ | stash it
Lcisret:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault addr
rts
Lcisflt1:
moveq #EFAULT,d0 | copy fault
jra Lcisdone
Lcisflt2:
moveq #ENAMETOOLONG,d0 | ran out of space
jra Lcisdone
/*
* copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
*
* Copy a null terminated string from the kernel
* address space to the user address space.
* NOTE: maxlength must be < 64K
*/
ENTRY(copyoutstr)
movl _curpcb,a0 | current pcb
movl #Lcosflt1,a0@(PCB_ONFAULT) | set up to catch faults
movl sp@(4),a0 | a0 = fromaddr
movl sp@(8),a1 | a1 = toaddr
moveq #0,d0
movw sp@(14),d0 | d0 = maxlength
jlt Lcosflt1 | negative count, error
jeq Lcosdone | zero count, all done
subql #1,d0 | set up for dbeq
Lcosloop:
movb a0@+,d1 | grab a byte
movsb d1,a1@+ | copy it
dbeq d0,Lcosloop | if !null and more, continue
jne Lcosflt2 | ran out of room, error
moveq #0,d0 | got a null, all done
Lcosdone:
tstl sp@(16) | return length desired?
jeq Lcosret | no, just return
subl sp@(4),a0 | determine how much was copied
movl sp@(16),a1 | return location
movl a0,a1@ | stash it
Lcosret:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault addr
rts
Lcosflt1:
moveq #EFAULT,d0 | copy fault
jra Lcosdone
Lcosflt2:
moveq #ENAMETOOLONG,d0 | ran out of space
jra Lcosdone
/*
* copystr(fromaddr, toaddr, maxlength, &lencopied)
*
* Copy a null terminated string from one point to another in
* the kernel address space.
* NOTE: maxlength must be < 64K
*/
ENTRY(copystr)
movl sp@(4),a0 | a0 = fromaddr
movl sp@(8),a1 | a1 = toaddr
moveq #0,d0
movw sp@(14),d0 | d0 = maxlength
jlt Lcsflt1 | negative count, error
jeq Lcsdone | zero count, all done
subql #1,d0 | set up for dbeq
Lcsloop:
movb a0@+,a1@+ | copy a byte
dbeq d0,Lcsloop | if !null and more, continue
jne Lcsflt2 | ran out of room, error
moveq #0,d0 | got a null, all done
Lcsdone:
tstl sp@(16) | return length desired?
jeq Lcsret | no, just return
subl sp@(4),a0 | determine how much was copied
movl sp@(16),a1 | return location
movl a0,a1@ | stash it
Lcsret:
rts
Lcsflt1:
moveq #EFAULT,d0 | copy fault
jra Lcsdone
Lcsflt2:
moveq #ENAMETOOLONG,d0 | ran out of space
jra Lcsdone
/*
* Copyin(from, to, len)
*
* Copy specified amount of data from user space into the kernel.
* NOTE: len must be < 64K
*/
ENTRY(copyin)
movl d2,sp@- | scratch register
movl _curpcb,a0 | current pcb
movl #Lciflt,a0@(PCB_ONFAULT) | set up to catch faults
movl sp@(16),d2 | check count
jlt Lciflt | negative, error
jeq Lcidone | zero, done
movl sp@(8),a0 | src address
movl sp@(12),a1 | dest address
movl a0,d0
btst #0,d0 | src address odd?
jeq Lcieven | no, go check dest
movsb a0@+,d1 | yes, get a byte
movb d1,a1@+ | put a byte
subql #1,d2 | adjust count
jeq Lcidone | exit if done
Lcieven:
movl a1,d0
btst #0,d0 | dest address odd?
jne Lcibyte | yes, must copy by bytes
movl d2,d0 | no, get count
lsrl #2,d0 | convert to longwords
jeq Lcibyte | no longwords, copy bytes
subql #1,d0 | set up for dbf
Lcilloop:
movsl a0@+,d1 | get a long
movl d1,a1@+ | put a long
dbf d0,Lcilloop | til done
andl #3,d2 | what remains
jeq Lcidone | all done
Lcibyte:
subql #1,d2 | set up for dbf
Lcibloop:
movsb a0@+,d1 | get a byte
movb d1,a1@+ | put a byte
dbf d2,Lcibloop | til done
Lcidone:
moveq #0,d0 | success
Lciexit:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault catcher
movl sp@+,d2 | restore scratch reg
rts
Lciflt:
moveq #EFAULT,d0 | got a fault
jra Lciexit
/*
* Copyout(from, to, len)
*
* Copy specified amount of data from kernel to the user space
* NOTE: len must be < 64K
*/
ENTRY(copyout)
movl d2,sp@- | scratch register
movl _curpcb,a0 | current pcb
movl #Lcoflt,a0@(PCB_ONFAULT) | catch faults
movl sp@(16),d2 | check count
jlt Lcoflt | negative, error
jeq Lcodone | zero, done
movl sp@(8),a0 | src address
movl sp@(12),a1 | dest address
movl a0,d0
btst #0,d0 | src address odd?
jeq Lcoeven | no, go check dest
movb a0@+,d1 | yes, get a byte
movsb d1,a1@+ | put a byte
subql #1,d2 | adjust count
jeq Lcodone | exit if done
Lcoeven:
movl a1,d0
btst #0,d0 | dest address odd?
jne Lcobyte | yes, must copy by bytes
movl d2,d0 | no, get count
lsrl #2,d0 | convert to longwords
jeq Lcobyte | no longwords, copy bytes
subql #1,d0 | set up for dbf
Lcolloop:
movl a0@+,d1 | get a long
movsl d1,a1@+ | put a long
dbf d0,Lcolloop | til done
andl #3,d2 | what remains
jeq Lcodone | all done
Lcobyte:
subql #1,d2 | set up for dbf
Lcobloop:
movb a0@+,d1 | get a byte
movsb d1,a1@+ | put a byte
dbf d2,Lcobloop | til done
Lcodone:
moveq #0,d0 | success
Lcoexit:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault catcher
movl sp@+,d2 | restore scratch reg
rts
Lcoflt:
moveq #EFAULT,d0 | got a fault
jra Lcoexit
/*
* {fu,su},{byte,sword,word}
*/
ALTENTRY(fuiword, _fuword)
ENTRY(fuword)
movl sp@(4),a0 | address to read
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsl a0@,d0 | do read from user space
jra Lfsdone
ENTRY(fusword)
movl sp@(4),a0
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
moveq #0,d0
movsw a0@,d0 | do read from user space
jra Lfsdone
ALTENTRY(fuibyte, _fubyte)
ENTRY(fubyte)
movl sp@(4),a0 | address to read
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
moveq #0,d0
movsb a0@,d0 | do read from user space
jra Lfsdone
Lfserr:
moveq #-1,d0 | error indicator
Lfsdone:
clrl a1@(PCB_ONFAULT) | clear fault address
rts
ALTENTRY(suiword, _suword)
ENTRY(suword)
movl sp@(4),a0 | address to write
movl sp@(8),d0 | value to put there
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsl d0,a0@ | do write to user space
moveq #0,d0 | indicate no fault
jra Lfsdone
ENTRY(susword)
movl sp@(4),a0 | address to write
movw sp@(10),d0 | value to put there
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsw d0,a0@ | do write to user space
moveq #0,d0 | indicate no fault
jra Lfsdone
ALTENTRY(suibyte, _subyte)
ENTRY(subyte)
movl sp@(4),a0 | address to write
movb sp@(11),d0 | value to put there
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsb d0,a0@ | do write to user space
moveq #0,d0 | indicate no fault
jra Lfsdone

View File

@ -2,18 +2,20 @@
* machine-dependent clock routines; intersil7170
* by Adam Glass
*
* $Header: /cvsroot/src/sys/arch/sun3/sun3/clock.c,v 1.3 1993/06/26 01:17:52 glass Exp $
* $Header: /cvsroot/src/sys/arch/sun3/sun3/clock.c,v 1.4 1993/06/27 00:46:09 glass Exp $
*/
#include "param.h"
#include "kernel.h"
#include "intersil7170.h"
#include "psl.h"
#include "cpu.h"
#include <machine/psl.h>
#include <machine/cpu.h>
#include "obio.h"
#define intersil_clock (struct intersil7170 *) CLOCK_ADDR)
#define CLOCK_ADDR 0x6000000
#define intersil_clock ((struct intersil7170 *) CLOCK_ADDR)
#define intersil_command(run, interrupt) \
(run | interrupt | INTERSIL_CMD_FREQ_32K | INTERSIL_CMD_24HR_MODE | \
INTERSIL_CMD_NORMAL_MODE)
@ -46,10 +48,7 @@ static int month_days[12] = {
*
* Resettodr restores the time of day hardware after a time change.
*
* A note on the real-time clock:
* We actually load the clock with CLK_INTERVAL-1 instead of CLK_INTERVAL.
* This is because the counter decrements to zero after N+1 enabled clock
* periods where N is the value loaded into the counter.
* also microtime support
*/
/*
@ -58,7 +57,7 @@ static int month_days[12] = {
void startrtclock()
{
intersil_clock->command_reg = intersil_command(INTERSIL_CMD_RUN,
INTERSIL_IDISABLE);
INTERSIL_CMD_IDISABLE);
intersil_clock->interrupt_reg = INTERSIL_INTER_CSECONDS;
}
@ -67,7 +66,7 @@ void enablertclock()
/* make sure irq5/7 stuff is resolved :) */
intersil_clock->command_reg = intersil_command(INTERSIL_CMD_RUN,
INTERSIL_IENABLE);
INTERSIL_CMD_IENABLE);
}
void intersil_counter_state(map)
@ -95,10 +94,10 @@ struct timeval intersil_to_timeval()
now.tv_sec = 0;
now.tv_usec = 0;
#define range_check_high(field, high)
now_state->field > high
#define range_check(field, low, high)
now_state->field < low || now_state->field > high
#define range_check_high(field, high) \
now_state.field > high
#define range_check(field, low, high) \
now_state.field < low || now_state.field > high
if (range_check_high(csecs, 99) ||
range_check_high(hours, 23) ||
@ -109,21 +108,21 @@ struct timeval intersil_to_timeval()
range_check_high(year, 99) ||
range_check_high(day, 6)) return now;
if ((INTERSIL_UNIX_BASE - INTERSIL_YEAR_BASE) > now_state->year)
if ((INTERSIL_UNIX_BASE - INTERSIL_YEAR_BASE) > now_state.year)
return now;
for (i = INTERSIL_UNIX_BASE-INTERSIL_YEAR_BASE;
i < now_state->year, i++)
if (INTERSIL_LEAP_YEAR(INTERSIL_YEAR_BASE+now_state->year))
i < now_state.year; i++)
if (INTERSIL_LEAP_YEAR(INTERSIL_YEAR_BASE+now_state.year))
now.tv_sec += SECS_PER_LEAP;
else now.tv_sec += SECS_PER_YEAR;
for (i = 1; i < now_state->month; i++)
now.tv_sec += SECS_PER_MONTH(i, INTERSIL_YEAR_BASE+now_state->year);
now.tv_sec += SECS_DAY*(now_state->date-1);
now.tv_sec += SECS_PER_HOUR * now_state->hours;
now.tv_sec += 60 * now_state->minutes;
now.tv_sec += 60 * now_state->seconds;
for (i = 1; i < now_state.month; i++)
now.tv_sec += SECS_PER_MONTH(i, INTERSIL_YEAR_BASE+now_state.year);
now.tv_sec += SECS_DAY*(now_state.date-1);
now.tv_sec += SECS_HOUR * now_state.hours;
now.tv_sec += 60 * now_state.minutes;
now.tv_sec += 60 * now_state.seconds;
return now;
}
/*
@ -136,6 +135,7 @@ void inittodr(base)
int s;
struct timeval clock_time;
long diff_time;
void resettodr();
clock_time = intersil_to_timeval();
@ -143,7 +143,7 @@ void inittodr(base)
if (clock_time.tv_sec < base) {
printf("WARNING: real-time clock reports a time earlier than last\n");
printf(" write to root filesystem. Trusting filesystem..."\n);
printf(" write to root filesystem. Trusting filesystem...\n");
time.tv_sec = base;
resettodr();
return;
@ -160,29 +160,29 @@ set_time:
}
void timeval_to_intersil(now, map)
timeval now;
struct intersil_map *map;
struct timeval now;
struct intersil_map *map;
{
for (map->year = INTERSIL_UNIX_BASE-INTERSIL_BASE_YEAR;
now > SECS_YEAR(map->year);
for (map->year = INTERSIL_UNIX_BASE-INTERSIL_YEAR_BASE;
now.tv_sec > SECS_YEAR(map->year);
map->year++)
now -= SECS_YEAR(map->year);
now.tv_sec -= SECS_YEAR(map->year);
for (map->month = 1; now >=0; map->month++)
now -= SECS_PER_MONTH(map->monthINTERSIL_BASE_YEAR+map->year);
for (map->month = 1; now.tv_sec >=0; map->month++)
now.tv_sec -= SECS_PER_MONTH(map->month, INTERSIL_YEAR_BASE+map->year);
map->month--;
now -= SECS_PER_MONTH(map->monthINTERSIL_BASE_YEAR+map->year);
now.tv_sec -= SECS_PER_MONTH(map->month, INTERSIL_YEAR_BASE+map->year);
map->date = now % SECS_DAY ;
map /= SECS_DAY;
map->minutes = now %60;
now /= 60;
map->seconds = now %60;
now /= 60;
map->date = now.tv_sec % SECS_DAY ;
now.tv_sec /= SECS_DAY;
map->minutes = now.tv_sec %60;
now.tv_sec /= 60;
map->seconds = now.tv_sec %60;
now.tv_sec /= 60;
map->day = map->date %7;
map->csec = now / 10000;
map->csecs = now.tv_usec / 10000;
}
@ -195,21 +195,38 @@ void resettodr()
timeval_to_intersil(time, &hdw_format);
intersil_clock->command_reg = intersil_command(INTERSIL_CMD_STOP,
INTERSIL_IDISABLE);
INTERSIL_CMD_IDISABLE);
intersil_clock->counters.csecs = hdw_format->csecs ;
intersil_clock->counters.hours = hdw_format->hours ;
intersil_clock->counters.minutes = hdw_format->minutes ;
intersil_clock->counters.seconds = hdw_format->seconds ;
intersil_clock->counters.month = hdw_format->month ;
intersil_clock->counters.date = hdw_format->date ;
intersil_clock->counters.year = hdw_format->year ;
intersil_clock->counters.day = hdw_format->day ;
intersil_clock->counters.csecs = hdw_format.csecs ;
intersil_clock->counters.hours = hdw_format.hours ;
intersil_clock->counters.minutes = hdw_format.minutes ;
intersil_clock->counters.seconds = hdw_format.seconds ;
intersil_clock->counters.month = hdw_format.month ;
intersil_clock->counters.date = hdw_format.date ;
intersil_clock->counters.year = hdw_format.year ;
intersil_clock->counters.day = hdw_format.day ;
intersil_clock->command_reg = intersil_command(INTERSIL_CMD_RUN,
INTERSIL_IENABLE);
INTERSIL_CMD_IENABLE);
}
void microtime(tvp)
register struct timeval *tvp;
{
int s;
static struct timeval lasttime;
/* as yet...... this makes little sense*/
*tvp = time;
if (tvp->tv_sec == lasttime.tv_sec &&
tvp->tv_usec <= lasttime.tv_usec &&
(tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
tvp->tv_sec++;
tvp->tv_usec -= 1000000;
}
lasttime = *tvp;
splx(s);
}

View File

@ -1 +1 @@
revision 1.1 intentionally removed
revision 1.2 intentionally removed

View File

@ -52,13 +52,14 @@
#include "cons.h"
#include "promcn.h"
#include "prom.h"
int promcnprobe(), promcninit(), promcngetc(), promcnputc();
struct consdev constab[] = {
#if NPROMCN
{promcnprobe, promcninit, promcngetc, promcnputc}
#if NPROM
{promcnprobe, promcninit, promcngetc, promcnputc},
#endif
{ 0 },
};

285
sys/arch/sun3/sun3/copy.s Normal file
View File

@ -0,0 +1,285 @@
.text
/*
* copyinstr(fromaddr, toaddr, maxlength, &lencopied)
*
* Copy a null terminated string from the user address space into
* the kernel address space.
* NOTE: maxlength must be < 64K
*/
ENTRY(copyinstr)
movl _curpcb,a0 | current pcb
movl #Lcisflt1,a0@(PCB_ONFAULT) | set up to catch faults
movl sp@(4),a0 | a0 = fromaddr
movl sp@(8),a1 | a1 = toaddr
moveq #0,d0
movw sp@(14),d0 | d0 = maxlength
jlt Lcisflt1 | negative count, error
jeq Lcisdone | zero count, all done
subql #1,d0 | set up for dbeq
Lcisloop:
movsb a0@+,d1 | grab a byte
movb d1,a1@+ | copy it
dbeq d0,Lcisloop | if !null and more, continue
jne Lcisflt2 | ran out of room, error
moveq #0,d0 | got a null, all done
Lcisdone:
tstl sp@(16) | return length desired?
jeq Lcisret | no, just return
subl sp@(4),a0 | determine how much was copied
movl sp@(16),a1 | return location
movl a0,a1@ | stash it
Lcisret:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault addr
rts
Lcisflt1:
moveq #EFAULT,d0 | copy fault
jra Lcisdone
Lcisflt2:
moveq #ENAMETOOLONG,d0 | ran out of space
jra Lcisdone
/*
* copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
*
* Copy a null terminated string from the kernel
* address space to the user address space.
* NOTE: maxlength must be < 64K
*/
ENTRY(copyoutstr)
movl _curpcb,a0 | current pcb
movl #Lcosflt1,a0@(PCB_ONFAULT) | set up to catch faults
movl sp@(4),a0 | a0 = fromaddr
movl sp@(8),a1 | a1 = toaddr
moveq #0,d0
movw sp@(14),d0 | d0 = maxlength
jlt Lcosflt1 | negative count, error
jeq Lcosdone | zero count, all done
subql #1,d0 | set up for dbeq
Lcosloop:
movb a0@+,d1 | grab a byte
movsb d1,a1@+ | copy it
dbeq d0,Lcosloop | if !null and more, continue
jne Lcosflt2 | ran out of room, error
moveq #0,d0 | got a null, all done
Lcosdone:
tstl sp@(16) | return length desired?
jeq Lcosret | no, just return
subl sp@(4),a0 | determine how much was copied
movl sp@(16),a1 | return location
movl a0,a1@ | stash it
Lcosret:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault addr
rts
Lcosflt1:
moveq #EFAULT,d0 | copy fault
jra Lcosdone
Lcosflt2:
moveq #ENAMETOOLONG,d0 | ran out of space
jra Lcosdone
/*
* copystr(fromaddr, toaddr, maxlength, &lencopied)
*
* Copy a null terminated string from one point to another in
* the kernel address space.
* NOTE: maxlength must be < 64K
*/
ENTRY(copystr)
movl sp@(4),a0 | a0 = fromaddr
movl sp@(8),a1 | a1 = toaddr
moveq #0,d0
movw sp@(14),d0 | d0 = maxlength
jlt Lcsflt1 | negative count, error
jeq Lcsdone | zero count, all done
subql #1,d0 | set up for dbeq
Lcsloop:
movb a0@+,a1@+ | copy a byte
dbeq d0,Lcsloop | if !null and more, continue
jne Lcsflt2 | ran out of room, error
moveq #0,d0 | got a null, all done
Lcsdone:
tstl sp@(16) | return length desired?
jeq Lcsret | no, just return
subl sp@(4),a0 | determine how much was copied
movl sp@(16),a1 | return location
movl a0,a1@ | stash it
Lcsret:
rts
Lcsflt1:
moveq #EFAULT,d0 | copy fault
jra Lcsdone
Lcsflt2:
moveq #ENAMETOOLONG,d0 | ran out of space
jra Lcsdone
/*
* Copyin(from, to, len)
*
* Copy specified amount of data from user space into the kernel.
* NOTE: len must be < 64K
*/
ENTRY(copyin)
movl d2,sp@- | scratch register
movl _curpcb,a0 | current pcb
movl #Lciflt,a0@(PCB_ONFAULT) | set up to catch faults
movl sp@(16),d2 | check count
jlt Lciflt | negative, error
jeq Lcidone | zero, done
movl sp@(8),a0 | src address
movl sp@(12),a1 | dest address
movl a0,d0
btst #0,d0 | src address odd?
jeq Lcieven | no, go check dest
movsb a0@+,d1 | yes, get a byte
movb d1,a1@+ | put a byte
subql #1,d2 | adjust count
jeq Lcidone | exit if done
Lcieven:
movl a1,d0
btst #0,d0 | dest address odd?
jne Lcibyte | yes, must copy by bytes
movl d2,d0 | no, get count
lsrl #2,d0 | convert to longwords
jeq Lcibyte | no longwords, copy bytes
subql #1,d0 | set up for dbf
Lcilloop:
movsl a0@+,d1 | get a long
movl d1,a1@+ | put a long
dbf d0,Lcilloop | til done
andl #3,d2 | what remains
jeq Lcidone | all done
Lcibyte:
subql #1,d2 | set up for dbf
Lcibloop:
movsb a0@+,d1 | get a byte
movb d1,a1@+ | put a byte
dbf d2,Lcibloop | til done
Lcidone:
moveq #0,d0 | success
Lciexit:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault catcher
movl sp@+,d2 | restore scratch reg
rts
Lciflt:
moveq #EFAULT,d0 | got a fault
jra Lciexit
/*
* Copyout(from, to, len)
*
* Copy specified amount of data from kernel to the user space
* NOTE: len must be < 64K
*/
ENTRY(copyout)
movl d2,sp@- | scratch register
movl _curpcb,a0 | current pcb
movl #Lcoflt,a0@(PCB_ONFAULT) | catch faults
movl sp@(16),d2 | check count
jlt Lcoflt | negative, error
jeq Lcodone | zero, done
movl sp@(8),a0 | src address
movl sp@(12),a1 | dest address
movl a0,d0
btst #0,d0 | src address odd?
jeq Lcoeven | no, go check dest
movb a0@+,d1 | yes, get a byte
movsb d1,a1@+ | put a byte
subql #1,d2 | adjust count
jeq Lcodone | exit if done
Lcoeven:
movl a1,d0
btst #0,d0 | dest address odd?
jne Lcobyte | yes, must copy by bytes
movl d2,d0 | no, get count
lsrl #2,d0 | convert to longwords
jeq Lcobyte | no longwords, copy bytes
subql #1,d0 | set up for dbf
Lcolloop:
movl a0@+,d1 | get a long
movsl d1,a1@+ | put a long
dbf d0,Lcolloop | til done
andl #3,d2 | what remains
jeq Lcodone | all done
Lcobyte:
subql #1,d2 | set up for dbf
Lcobloop:
movb a0@+,d1 | get a byte
movsb d1,a1@+ | put a byte
dbf d2,Lcobloop | til done
Lcodone:
moveq #0,d0 | success
Lcoexit:
movl _curpcb,a0 | current pcb
clrl a0@(PCB_ONFAULT) | clear fault catcher
movl sp@+,d2 | restore scratch reg
rts
Lcoflt:
moveq #EFAULT,d0 | got a fault
jra Lcoexit
/*
* {fu,su},{byte,sword,word}
*/
ALTENTRY(fuiword, _fuword)
ENTRY(fuword)
movl sp@(4),a0 | address to read
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsl a0@,d0 | do read from user space
jra Lfsdone
ENTRY(fusword)
movl sp@(4),a0
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
moveq #0,d0
movsw a0@,d0 | do read from user space
jra Lfsdone
ALTENTRY(fuibyte, _fubyte)
ENTRY(fubyte)
movl sp@(4),a0 | address to read
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
moveq #0,d0
movsb a0@,d0 | do read from user space
jra Lfsdone
Lfserr:
moveq #-1,d0 | error indicator
Lfsdone:
clrl a1@(PCB_ONFAULT) | clear fault address
rts
ALTENTRY(suiword, _suword)
ENTRY(suword)
movl sp@(4),a0 | address to write
movl sp@(8),d0 | value to put there
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsl d0,a0@ | do write to user space
moveq #0,d0 | indicate no fault
jra Lfsdone
ENTRY(susword)
movl sp@(4),a0 | address to write
movw sp@(10),d0 | value to put there
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsw d0,a0@ | do write to user space
moveq #0,d0 | indicate no fault
jra Lfsdone
ALTENTRY(suibyte, _subyte)
ENTRY(subyte)
movl sp@(4),a0 | address to write
movb sp@(11),d0 | value to put there
movl _curpcb,a1 | current pcb
movl #Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault
movsb d0,a0@ | do write to user space
moveq #0,d0 | indicate no fault
jra Lfsdone

View File

@ -42,6 +42,7 @@
#include "../include/control.h"
#include "../include/param.h"
#include "../include/memmap.h"
#include <sys/errno.h>
main()
{
@ -61,6 +62,10 @@ main()
printf("#define\tMAINMEM_MONMAP %d\n", MAINMEM_MONMAP);
/* kernel-isms */
printf("#define\tKERNBASE %d\n", KERNBASE);
/* errno-isms */
printf("#define EFAULT %d\n", EFAULT);
printf("#define ENAMETOOLONG %d\n", ENAMETOOLONG);
exit(0);
}

View File

@ -1,5 +1,3 @@
#include "asm.h"
#include "assym.s"
/*
* Primitives
*/

View File

@ -1,5 +1,6 @@
#include "assym.s"
#include "../include/asm.h"
#include "syscall.h"
| remember this is a fun project :)
@ -63,4 +64,35 @@ bsszero: clrl a0@
movl #_start, sp
jsr _bootstrap
.text
/*
* Icode is copied out to process 1 to exec init.
* If the exec fails, process 1 exits.
*/
.globl _icode,_szicode
.text
_icode:
clrl sp@-
pea pc@((argv-.)+2)
pea pc@((init-.)+2)
clrl sp@-
moveq #SYS_execve,d0
trap #0
moveq #SYS_exit,d0
trap #0
init:
.asciz "/sbin/init"
.even
argv:
.long init+6-_icode | argv[0] = "init" ("/sbin/init" + 6)
.long eicode-_icode | argv[1] follows icode after copyout
.long 0
eicode:
_szicode:
.long _szicode-_icode
#include "lib.s"
#include "copy.s"
#include "m68k.s"
#include "signal.s"

View File

@ -12,7 +12,7 @@ static void initialize_vector_table()
old_vector_table = getvbr();
for (i = 0; i < NVECTORS; i++) {
if (vector_table[i] == COPY_ENTRY)
vector_table[i] = old_vector[i];
vector_table[i] = old_vector_table[i];
}
setvbr(vector_table);
}
@ -26,7 +26,7 @@ void bootstrap()
for (i=0; i < 11; i++) {
mon_putchar(hello[i]);
}
mon_printf("\nPROM Version: %d\n", romp->v_romvec_version);
mon_printf("\nPROM Version: %d\n", romp->romvecVersion);
initialize_vector_table();
mon_exit_to_mon();

View File

@ -1,4 +1,3 @@
#include "asm.h"
ENTRY(getvbr)
movc vbr, d0

View File

@ -0,0 +1,64 @@
.text
/*
* The sigreturn() syscall comes here. It requires special handling
* because we must open a hole in the stack to fill in the (possibly much
* larger) original stack frame.
*/
sigreturn:
lea sp@(-84),sp | leave enough space for largest frame
movl sp@(84),sp@ | move up current 8 byte frame
movl sp@(88),sp@(4)
movw #84,sp@- | default: adjust by 84 bytes
moveml #0xFFFF,sp@- | save user registers
movl usp,a0 | save the user SP
movl a0,sp@(60) | in the savearea
movl #SYS_sigreturn,sp@- | push syscall number
jbsr _syscall | handle it
addql #4,sp | pop syscall#
movl sp@(60),a0 | grab and restore
movl a0,usp | user SP
lea sp@(64),a1 | pointer to HW frame
movw a1@+,d0 | do we need to adjust the stack?
jeq Lsigr1 | no, just continue
moveq #92,d1 | total size
subw d0,d1 | - hole size = frame size
lea a1@(92),a0 | destination
addw d1,a1 | source
lsrw #1,d1 | convert to word count
subqw #1,d1 | minus 1 for dbf
Lsigrlp:
movw a1@-,a0@- | copy a word
dbf d1,Lsigrlp | continue
movl a0,a1 | new HW frame base
Lsigr1:
movl a1,sp@(60) | new SP value
moveml sp@+,#0x7FFF | restore user registers
movl sp@,sp | and our SP
jra rei | all done
/*
* Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig().
*
* Stack looks like:
*
* sp+0 -> signal number
* sp+4 signal specific code
* sp+8 pointer to signal context frame (scp)
* sp+12 address of handler
* sp+16 saved hardware state
* .
* .
* scp+0-> beginning of signal context frame
*/
.globl _sigcode, _esigcode
.data
_sigcode:
movl sp@(12),a0 | signal handler addr (4 bytes)
jsr a0@ | call signal handler (2 bytes)
addql #4,sp | pop signo (2 bytes)
trap #1 | special syscall entry (2 bytes)
movl d0,sp@(4) | save errno (4 bytes)
moveq #1,d0 | syscall == exit (2 bytes)
trap #0 | exit(errno) (2 bytes)
.align 2
_esigcode:

View File

@ -12,7 +12,7 @@ static void initialize_vector_table()
old_vector_table = getvbr();
for (i = 0; i < NVECTORS; i++) {
if (vector_table[i] == COPY_ENTRY)
vector_table[i] = old_vector[i];
vector_table[i] = old_vector_table[i];
}
setvbr(vector_table);
}
@ -26,7 +26,7 @@ void bootstrap()
for (i=0; i < 11; i++) {
mon_putchar(hello[i]);
}
mon_printf("\nPROM Version: %d\n", romp->v_romvec_version);
mon_printf("\nPROM Version: %d\n", romp->romvecVersion);
initialize_vector_table();
mon_exit_to_mon();

View File

@ -42,6 +42,8 @@
/*#include "../dev/device.h"*/
#include "sd.h"
/*
* Generic configuration; all in one
*/
@ -58,8 +60,9 @@ struct genericconf {
char *gc_name;
dev_t gc_root;
} genericconf[] = {
{ (caddr_t)&rddriver, "rd", makedev(2, 0), },
#if NSD > 0
{ (caddr_t)&sddriver, "sd", makedev(4, 0), },
#endif
{ 0 },
};