merge
This commit is contained in:
commit
daf153009e
12 changed files with 84 additions and 133 deletions
|
@ -237,7 +237,7 @@ cpustart(int cpu)
|
|||
mb->clr[cpu].doorbell = 1;
|
||||
trapinit();
|
||||
clockinit();
|
||||
mmuinit1();
|
||||
mmuinit1(0);
|
||||
timersinit();
|
||||
cpuidprint();
|
||||
archreset();
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
MOVW $0x10000,R3; \
|
||||
MOVW R3,(R2)
|
||||
|
||||
#define PUTC(s)
|
||||
|
||||
/*
|
||||
* get cpu id, or zero if armv6
|
||||
*/
|
||||
|
|
|
@ -45,17 +45,6 @@ TEXT armstart(SB), 1, $-4
|
|||
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||
BARRIERS
|
||||
|
||||
/*
|
||||
* clear mach and page tables
|
||||
*/
|
||||
MOVW $PADDR(MACHADDR), R1
|
||||
MOVW $PADDR(KTZERO), R2
|
||||
_ramZ:
|
||||
MOVW R0, (R1)
|
||||
ADD $4, R1
|
||||
CMP R1, R2
|
||||
BNE _ramZ
|
||||
|
||||
/*
|
||||
* turn SMP on
|
||||
* invalidate tlb
|
||||
|
@ -67,6 +56,17 @@ _ramZ:
|
|||
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
|
||||
BARRIERS
|
||||
|
||||
/*
|
||||
* clear mach and page tables
|
||||
*/
|
||||
MOVW $PADDR(MACHADDR), R1
|
||||
MOVW $PADDR(KTZERO), R2
|
||||
_ramZ:
|
||||
MOVW R0, (R1)
|
||||
ADD $4, R1
|
||||
CMP R1, R2
|
||||
BNE _ramZ
|
||||
|
||||
/*
|
||||
* start stack at top of mach (physical addr)
|
||||
* set up page tables for kernel
|
||||
|
@ -96,7 +96,6 @@ _ramZ:
|
|||
/*
|
||||
* enable caches, mmu, and high vectors
|
||||
*/
|
||||
|
||||
MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||||
ORR $(CpChv|CpCdcache|CpCicache|CpCmmu), R0
|
||||
MCR CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
|
||||
|
|
|
@ -131,17 +131,6 @@ TEXT l2cacheuinv(SB), $-4
|
|||
BL wholecache(SB)
|
||||
MOVW.P 8(R13), R15
|
||||
|
||||
/*
|
||||
* these shift values are for the Cortex-A8 L1 cache (A=2, L=6) and
|
||||
* the Cortex-A8 L2 cache (A=3, L=6).
|
||||
* A = log2(# of ways), L = log2(bytes per cache line).
|
||||
* see armv7 arch ref p. 1403.
|
||||
*/
|
||||
#define L1WAYSH 30
|
||||
#define L1SETSH 6
|
||||
#define L2WAYSH 29
|
||||
#define L2SETSH 6
|
||||
|
||||
/*
|
||||
* callers are assumed to be the above l1 and l2 ops.
|
||||
* R0 is the function to call in the innermost loop.
|
||||
|
@ -184,11 +173,12 @@ TEXT wholecache+0(SB), $-4
|
|||
ADD $1, R2 /* R2 (sets) = ((R0 >> 13) & MASK(15)) + 1 */
|
||||
|
||||
/* precompute set/way shifts for inner loop */
|
||||
MOVW $6, R4
|
||||
CMP $0, R8 /* cache == 1? */
|
||||
MOVW.EQ $L1WAYSH, R3 /* yes */
|
||||
MOVW.EQ $L1SETSH, R4
|
||||
MOVW.NE $L2WAYSH, R3 /* no */
|
||||
MOVW.NE $L2SETSH, R4
|
||||
MOVW.EQ $30, R3 /* l1 */
|
||||
MOVW.NE $29, R3 /* l2 */
|
||||
CMP $16, R5 /* armv8 has 16-way l2, adjust shift */
|
||||
MOVW.EQ $28, R3
|
||||
|
||||
/* iterate over ways */
|
||||
MOVW $0, R7 /* R7: way */
|
||||
|
|
|
@ -98,7 +98,7 @@ localclockintr(Ureg *ureg, void *)
|
|||
{
|
||||
if(m->machno == 0)
|
||||
panic("cpu0: Unexpected local generic timer interrupt");
|
||||
cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask|Enable);
|
||||
cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask);
|
||||
timerintr(ureg, 0);
|
||||
}
|
||||
|
||||
|
@ -109,10 +109,6 @@ clockshutdown(void)
|
|||
|
||||
tm = (Armtimer*)ARMTIMER;
|
||||
tm->ctl = 0;
|
||||
if(cpuserver)
|
||||
wdogfeed();
|
||||
else
|
||||
wdogoff();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -125,10 +121,11 @@ clockinit(void)
|
|||
if(((cprdsc(0, CpID, CpIDfeat, 1) >> 16) & 0xF) != 0) {
|
||||
/* generic timer supported */
|
||||
if(m->machno == 0){
|
||||
*(ulong*)(ARMLOCAL + Localctl) = 0; /* input clock is 19.2Mhz crystal */
|
||||
*(ulong*)(ARMLOCAL + Localctl) = 0; /* input clock is 19.2Mhz crystal */
|
||||
*(ulong*)(ARMLOCAL + Prescaler) = 0x06aaaaab; /* divide by (2^31/Prescaler) for 1Mhz */
|
||||
}
|
||||
cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask);
|
||||
intrenable(IRQcntpns, localclockintr, nil, 0, "clock");
|
||||
}
|
||||
|
||||
tn = (Systimers*)SYSTIMERS;
|
||||
|
@ -150,8 +147,7 @@ clockinit(void)
|
|||
tm->load = 0;
|
||||
tm->ctl = TmrPrescale1|CntEnable|CntWidth32;
|
||||
intrenable(IRQtimer3, clockintr, nil, 0, "clock");
|
||||
}else
|
||||
intrenable(IRQcntpns, localclockintr, nil, 0, "clock");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -230,14 +226,10 @@ ulong
|
|||
void
|
||||
microdelay(int n)
|
||||
{
|
||||
Systimers *tn;
|
||||
u32int now, diff;
|
||||
ulong now;
|
||||
|
||||
diff = n + 1;
|
||||
tn = (Systimers*)SYSTIMERS;
|
||||
now = tn->clo;
|
||||
while(tn->clo - now < diff)
|
||||
;
|
||||
now = µs();
|
||||
while(µs() - now < n);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -66,7 +66,7 @@ extern int isaconfig(char*, int, ISAConf*);
|
|||
extern void l2cacheuwbinv(void);
|
||||
extern void links(void);
|
||||
extern void mmuinit(void*);
|
||||
extern void mmuinit1(void);
|
||||
extern void mmuinit1(int);
|
||||
extern void mmuinvalidate(void);
|
||||
extern void mmuinvalidateaddr(u32int);
|
||||
extern uintptr mmukmap(uintptr, uintptr, usize);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* Where configuration info is left for the loaded programme.
|
||||
*/
|
||||
#define BOOTARGS ((char*)CONFADDR)
|
||||
#define BOOTARGSLEN (MACHADDR-CONFADDR)
|
||||
#define BOOTARGSLEN (REBOOTADDR-PADDR(CONFADDR))
|
||||
#define MAXCONF 64
|
||||
#define MAXCONFLINE 160
|
||||
|
||||
|
@ -301,7 +301,7 @@ main(void)
|
|||
pageinit();
|
||||
userinit();
|
||||
launchinit();
|
||||
mmuinit1();
|
||||
mmuinit1(0);
|
||||
schedinit();
|
||||
assert(0); /* shouldn't have returned */
|
||||
}
|
||||
|
@ -550,6 +550,35 @@ confinit(void)
|
|||
|
||||
}
|
||||
|
||||
static void
|
||||
rebootjump(ulong entry, ulong code, ulong size)
|
||||
{
|
||||
static void (*f)(ulong, ulong, ulong);
|
||||
static Lock lk;
|
||||
|
||||
intrsoff();
|
||||
intrcpushutdown();
|
||||
|
||||
/* redo identity map */
|
||||
mmuinit1(1);
|
||||
|
||||
lock(&lk);
|
||||
if(f == nil){
|
||||
/* setup reboot trampoline function */
|
||||
f = (void*)REBOOTADDR;
|
||||
memmove(f, rebootcode, sizeof(rebootcode));
|
||||
cachedwbse(f, sizeof(rebootcode));
|
||||
}
|
||||
unlock(&lk);
|
||||
|
||||
cacheuwbinv();
|
||||
l2cacheuwbinv();
|
||||
|
||||
(*f)(entry, code, size);
|
||||
|
||||
for(;;);
|
||||
}
|
||||
|
||||
/*
|
||||
* exit kernel either on a panic or user request
|
||||
*/
|
||||
|
@ -558,14 +587,8 @@ exit(int)
|
|||
{
|
||||
cpushutdown();
|
||||
splfhi();
|
||||
if(m->machno != 0){
|
||||
void (*f)(ulong, ulong, ulong) = (void*)REBOOTADDR;
|
||||
intrsoff();
|
||||
intrcpushutdown();
|
||||
cacheuwbinv();
|
||||
(*f)(0, 0, 0);
|
||||
for(;;);
|
||||
}
|
||||
if(m->machno != 0)
|
||||
rebootjump(0, 0, 0);
|
||||
archreboot();
|
||||
}
|
||||
|
||||
|
@ -585,21 +608,14 @@ isaconfig(char *, int, ISAConf *)
|
|||
void
|
||||
reboot(void *entry, void *code, ulong size)
|
||||
{
|
||||
void (*f)(ulong, ulong, ulong);
|
||||
|
||||
writeconf();
|
||||
if (m->machno != 0) {
|
||||
procwired(up, 0);
|
||||
sched();
|
||||
}
|
||||
|
||||
/* setup reboot trampoline function */
|
||||
f = (void*)REBOOTADDR;
|
||||
memmove(f, rebootcode, sizeof(rebootcode));
|
||||
cachedwbse(f, sizeof(rebootcode));
|
||||
|
||||
cpushutdown();
|
||||
delay(500);
|
||||
delay(1000);
|
||||
|
||||
splfhi();
|
||||
|
||||
|
@ -611,14 +627,10 @@ reboot(void *entry, void *code, ulong size)
|
|||
|
||||
/* stop the clock (and watchdog if any) */
|
||||
clockshutdown();
|
||||
intrsoff();
|
||||
intrcpushutdown();
|
||||
|
||||
cacheuwbinv();
|
||||
l2cacheuwbinv();
|
||||
wdogoff();
|
||||
|
||||
/* off we go - never to return */
|
||||
(*f)(PADDR(entry), PADDR(code), size);
|
||||
rebootjump(PADDR(entry), PADDR(code), size);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define KSEGM 0xC0000000
|
||||
#define KZERO KSEG0 /* kernel address space */
|
||||
#define CONFADDR (KZERO+0x100) /* unparsed plan9.ini */
|
||||
#define REBOOTADDR (0x1c00) /* reboot code - physical address */
|
||||
#define MACHADDR (KZERO+0x2000) /* Mach structure */
|
||||
#define L2 (KZERO+0x3000) /* L2 ptes for vectors etc */
|
||||
#define VCBUFFER (KZERO+0x3400) /* videocore mailbox buffer */
|
||||
|
@ -62,9 +63,6 @@
|
|||
#define TSTKTOP (USTKTOP-USTKSIZE) /* sysexec temporary stack */
|
||||
#define TSTKSIZ 256
|
||||
|
||||
/* address at which to copy and execute rebootcode */
|
||||
#define REBOOTADDR (KZERO+0x1800)
|
||||
|
||||
/*
|
||||
* Legacy...
|
||||
*/
|
||||
|
|
|
@ -123,8 +123,8 @@ init.h:D: ../port/initcode.c init9.s
|
|||
|
||||
reboot.h:D: rebootcode.s arm.s arm.h mem.h
|
||||
$AS rebootcode.s
|
||||
# -lc is only for memmove. -T arg is PADDR(REBOOTADDR)
|
||||
$LD -l -s -T0x1800 -R4 -o reboot.out rebootcode.$O -lc
|
||||
# -lc is only for memmove. -T arg is REBOOTADDR
|
||||
$LD -l -s -T0x1c00 -R4 -o reboot.out rebootcode.$O -lc
|
||||
{echo 'uchar rebootcode[]={'
|
||||
xd -1x reboot.out |
|
||||
sed -e '1,2d' -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g'
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define L2AP(ap) l2ap(ap)
|
||||
#define L1ptedramattrs soc.l1ptedramattrs
|
||||
#define L2ptedramattrs soc.l2ptedramattrs
|
||||
#define PTEDRAM (PHYSDRAM|Dom0|L1AP(Krw)|Section|L1ptedramattrs)
|
||||
|
||||
enum {
|
||||
L1lo = UZERO/MiB, /* L1X(UZERO)? */
|
||||
|
@ -43,7 +44,7 @@ mmuinit(void *a)
|
|||
/*
|
||||
* identity map first MB of ram so mmu can be enabled
|
||||
*/
|
||||
l1[L1X(PHYSDRAM)] = PHYSDRAM|Dom0|L1AP(Krw)|Section|L1ptedramattrs;
|
||||
l1[L1X(PHYSDRAM)] = PTEDRAM;
|
||||
|
||||
/*
|
||||
* map i/o registers
|
||||
|
@ -65,19 +66,19 @@ mmuinit(void *a)
|
|||
l2[L2X(va)] = PHYSDRAM|L2AP(Krw)|Small|L2ptedramattrs;
|
||||
}
|
||||
|
||||
/*
|
||||
* enable/disable identity map of first MB of ram
|
||||
*/
|
||||
void
|
||||
mmuinit1()
|
||||
mmuinit1(int on)
|
||||
{
|
||||
PTE *l1;
|
||||
|
||||
l1 = m->mmul1;
|
||||
|
||||
/*
|
||||
* undo identity map of first MB of ram
|
||||
*/
|
||||
l1[L1X(PHYSDRAM)] = 0;
|
||||
l1[L1X(PHYSDRAM)] = on? PTEDRAM: Fault;
|
||||
cachedwbtlb(&l1[L1X(PHYSDRAM)], sizeof(PTE));
|
||||
mmuinvalidateaddr(PHYSDRAM);
|
||||
mmuinvalidate();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
*/
|
||||
#include "arm.s"
|
||||
|
||||
#define PTEDRAM (Dom0|L1AP(Krw)|Section)
|
||||
|
||||
#define WFI WORD $0xe320f003 /* wait for interrupt */
|
||||
#define WFE WORD $0xe320f002 /* wait for event */
|
||||
|
||||
|
@ -26,8 +24,16 @@ TEXT main(SB), 1, $-4
|
|||
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
|
||||
MOVW R1, CPSR
|
||||
|
||||
/* prepare to turn off mmu */
|
||||
BL cachesoff(SB)
|
||||
/* turn caches off */
|
||||
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||
BIC $(CpCdcache|CpCicache|CpCpredict), R1
|
||||
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||
BARRIERS
|
||||
|
||||
/* invalidate icache */
|
||||
MOVW $0, R0
|
||||
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
|
||||
BARRIERS
|
||||
|
||||
/* turn off mmu */
|
||||
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||
|
@ -49,7 +55,7 @@ dowfi:
|
|||
MOVW $0x40000060, R1
|
||||
ADD R2<<2, R1
|
||||
MOVW 0(R1), R0
|
||||
AND $0x10, R0
|
||||
AND $0x10, R0
|
||||
BEQ dowfi
|
||||
MOVW $0x8000, R1
|
||||
BL (R1)
|
||||
|
@ -72,47 +78,3 @@ bootcpu:
|
|||
ORR R8,R8
|
||||
B (R8)
|
||||
B 0(PC)
|
||||
|
||||
/*
|
||||
* turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert
|
||||
* to tiny addresses. upon return, it will be safe to turn off the mmu.
|
||||
* clobbers R0-R2, and returns with SP invalid.
|
||||
*/
|
||||
TEXT cachesoff(SB), 1, $-4
|
||||
MOVM.DB.W [R14,R1-R10], (R13) /* save regs on stack */
|
||||
|
||||
/* turn caches off, invalidate icache */
|
||||
MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||
BIC $(CpCdcache|CpCicache|CpCpredict), R1
|
||||
MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
|
||||
MOVW $0, R0
|
||||
MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
|
||||
|
||||
/* invalidate stale TLBs before changing them */
|
||||
BARRIERS
|
||||
MOVW $0, R0
|
||||
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
|
||||
BARRIERS
|
||||
|
||||
/* redo double map of first MiB PHYSDRAM = KZERO */
|
||||
MOVW 12(R(MACH)), R2 /* m->mmul1 (virtual addr) */
|
||||
MOVW $PTEDRAM, R1 /* PTE bits */
|
||||
MOVW R1, (R2)
|
||||
DSB
|
||||
MCR CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse
|
||||
|
||||
/* invalidate stale TLBs again */
|
||||
BARRIERS
|
||||
MOVW $0, R0
|
||||
MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
|
||||
BARRIERS
|
||||
|
||||
/* relocate SB and return address to PHYSDRAM addressing */
|
||||
MOVW $KSEGM, R1 /* clear segment bits */
|
||||
BIC R1, R12 /* adjust SB */
|
||||
MOVM.IA.W (R13), [R14,R1-R10] /* restore regs from stack */
|
||||
|
||||
MOVW $KSEGM, R1 /* clear segment bits */
|
||||
BIC R1, R14 /* adjust return address */
|
||||
|
||||
RET
|
||||
|
|
|
@ -318,9 +318,8 @@ uartdrained(void* arg)
|
|||
static void
|
||||
uartdrainoutput(Uart *p)
|
||||
{
|
||||
if(!p->enabled)
|
||||
if(!p->enabled || up == nil || !islo())
|
||||
return;
|
||||
|
||||
p->drain = 1;
|
||||
if(waserror()){
|
||||
p->drain = 0;
|
||||
|
|
Loading…
Reference in a new issue