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:
parent
4c06bc4b0d
commit
e1fec74952
285
sys/arch/m68k/m68k/copy.s
Normal file
285
sys/arch/m68k/m68k/copy.s
Normal 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
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
revision 1.1 intentionally removed
|
||||
revision 1.2 intentionally removed
|
||||
|
@ -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
285
sys/arch/sun3/sun3/copy.s
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include "asm.h"
|
||||
#include "assym.s"
|
||||
/*
|
||||
* Primitives
|
||||
*/
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "asm.h"
|
||||
|
||||
ENTRY(getvbr)
|
||||
movc vbr, d0
|
||||
|
64
sys/arch/sun3/sun3/signal.s
Normal file
64
sys/arch/sun3/sun3/signal.s
Normal 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:
|
@ -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();
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user