Make hwid_t a struct to help catch errors

上级 44725ca6
...@@ -140,10 +140,10 @@ void kbdintr(void); ...@@ -140,10 +140,10 @@ void kbdintr(void);
// lapic.c // lapic.c
hwid_t lapicid(void); hwid_t lapicid(void);
void lapicstartap(u8, u32 addr); void lapicstartap(hwid, u32 addr);
void lapiceoi(void); void lapiceoi(void);
void lapic_tlbflush(u32); void lapic_tlbflush(hwid);
void lapic_sampconf(u32); void lapic_sampconf(hwid);
void lapicpc(char mask); void lapicpc(char mask);
// mp.c // mp.c
......
...@@ -119,6 +119,12 @@ struct taskstate ...@@ -119,6 +119,12 @@ struct taskstate
u16 iomba; u16 iomba;
u8 iopb[0]; u8 iopb[0];
} __attribute__ ((packed, aligned(16))); } __attribute__ ((packed, aligned(16)));
typedef struct hwid {
u8 num;
} hwid_t;
#define HWID(xnum) (struct hwid){ num: (u8)(xnum) }
#endif #endif
#define INT_P (1<<7) /* interrupt descriptor present */ #define INT_P (1<<7) /* interrupt descriptor present */
......
#pragma once
typedef unsigned char u8; typedef unsigned char u8;
typedef char s8; typedef char s8;
typedef unsigned short u16; typedef unsigned short u16;
...@@ -16,8 +18,8 @@ typedef uptr paddr; ...@@ -16,8 +18,8 @@ typedef uptr paddr;
// Page Map Entry (refers to any entry in any level) // Page Map Entry (refers to any entry in any level)
typedef u64 pme_t; typedef u64 pme_t;
// Logical CPU ID type
typedef u8 cpuid_t; typedef u8 cpuid_t;
typedef u8 hwid_t;
#ifdef XV6 #ifdef XV6
// POSIX types // POSIX types
......
...@@ -213,7 +213,7 @@ inittls(void) ...@@ -213,7 +213,7 @@ inittls(void)
cpuid_t id = -1; cpuid_t id = -1;
for (id = 0; id < NCPU; id++) for (id = 0; id < NCPU; id++)
if (cpus[id].hwid == lapicid()) if (cpus[id].hwid.num == lapicid().num)
break; break;
assert(id != -1); assert(id != -1);
...@@ -246,7 +246,7 @@ tlbflush(u64 myreq) ...@@ -246,7 +246,7 @@ tlbflush(u64 myreq)
for (int i = 0; i < ncpu; i++) for (int i = 0; i < ncpu; i++)
if (cpus[i].tlbflush_done < myreq) if (cpus[i].tlbflush_done < myreq)
lapic_tlbflush(i); lapic_tlbflush(cpus[i].hwid);
for (int i = 0; i < ncpu; i++) for (int i = 0; i < ncpu; i++)
while (cpus[i].tlbflush_done < myreq) while (cpus[i].tlbflush_done < myreq)
......
...@@ -140,17 +140,16 @@ lapicpc(char mask) ...@@ -140,17 +140,16 @@ lapicpc(char mask)
hwid_t hwid_t
lapicid(void) lapicid(void)
{ {
// Cannot call cpu when interrupts are enabled: if (readrflags() & FL_IF) {
// result not guaranteed to last long enough to be used!
if(readrflags()&FL_IF){
cli(); cli();
panic("cpunum() called from %p with interrupts enabled\n", panic("cpunum() called from %p with interrupts enabled\n",
__builtin_return_address(0)); __builtin_return_address(0));
} }
if(lapic) if (lapic == nullptr)
return lapic[ID]>>24; panic("lapicid");
return 0;
return HWID(lapic[ID]>>24);
} }
// Acknowledge interrupt. // Acknowledge interrupt.
...@@ -163,30 +162,30 @@ lapiceoi(void) ...@@ -163,30 +162,30 @@ lapiceoi(void)
// Send IPI // Send IPI
void void
lapic_ipi(int cpu, int ino) lapic_ipi(hwid_t hwid, int ino)
{ {
lapicw(ICRHI, cpu << 24); lapicw(ICRHI, hwid.num << 24);
lapicw(ICRLO, FIXED | DEASSERT | ino); lapicw(ICRLO, FIXED | DEASSERT | ino);
if (lapicwait() < 0) if (lapicwait() < 0)
panic("lapic_ipi: lapicwait failure"); panic("lapic_ipi: lapicwait failure");
} }
void void
lapic_tlbflush(u32 cpu) lapic_tlbflush(hwid_t hwid)
{ {
lapic_ipi(cpu, T_TLBFLUSH); lapic_ipi(hwid, T_TLBFLUSH);
} }
void void
lapic_sampconf(u32 cpu) lapic_sampconf(hwid_t hwid)
{ {
lapic_ipi(cpu, T_SAMPCONF); lapic_ipi(hwid, T_SAMPCONF);
} }
// Start additional processor running bootstrap code at addr. // Start additional processor running bootstrap code at addr.
// See Appendix B of MultiProcessor Specification. // See Appendix B of MultiProcessor Specification.
void void
lapicstartap(u8 apicid, u32 addr) lapicstartap(hwid hwid, u32 addr)
{ {
int i; int i;
volatile u16 *wrv; volatile u16 *wrv;
...@@ -202,11 +201,11 @@ lapicstartap(u8 apicid, u32 addr) ...@@ -202,11 +201,11 @@ lapicstartap(u8 apicid, u32 addr)
// "Universal startup algorithm." // "Universal startup algorithm."
// Send INIT (level-triggered) interrupt to reset other CPU. // Send INIT (level-triggered) interrupt to reset other CPU.
lapicw(ICRHI, apicid<<24); lapicw(ICRHI, hwid.num<<24);
lapicw(ICRLO, apicid | INIT | LEVEL | ASSERT); lapicw(ICRLO, hwid.num | INIT | LEVEL | ASSERT);
lapicwait(); lapicwait();
microdelay(10000); microdelay(10000);
lapicw(ICRLO, apicid |INIT | LEVEL); lapicw(ICRLO, hwid.num |INIT | LEVEL);
lapicwait(); lapicwait();
microdelay(10000); // should be 10ms, but too slow in Bochs! microdelay(10000); // should be 10ms, but too slow in Bochs!
...@@ -216,7 +215,7 @@ lapicstartap(u8 apicid, u32 addr) ...@@ -216,7 +215,7 @@ lapicstartap(u8 apicid, u32 addr)
// should be ignored, but it is part of the official Intel algorithm. // should be ignored, but it is part of the official Intel algorithm.
// Bochs complains about the second one. Too bad for Bochs. // Bochs complains about the second one. Too bad for Bochs.
for(i = 0; i < 2; i++){ for(i = 0; i < 2; i++){
lapicw(ICRHI, apicid<<24); lapicw(ICRHI, hwid.num<<24);
lapicw(ICRLO, STARTUP | (addr>>12)); lapicw(ICRLO, STARTUP | (addr>>12));
microdelay(200); microdelay(200);
} }
......
...@@ -81,7 +81,7 @@ bootothers(void) ...@@ -81,7 +81,7 @@ bootothers(void)
*(u64*)(code-12) = (u64)stack + KSTACKSIZE; *(u64*)(code-12) = (u64)stack + KSTACKSIZE;
bstate = 0; bstate = 0;
lapicstartap(c->id, v2p(code)); lapicstartap(c->hwid, v2p(code));
// Wait for cpu to finish mpmain() // Wait for cpu to finish mpmain()
while(bstate == 0) while(bstate == 0)
; ;
......
...@@ -113,14 +113,10 @@ initmp(void) ...@@ -113,14 +113,10 @@ initmp(void)
proc = (struct mpproc*)p; proc = (struct mpproc*)p;
if (ncpu == NCPU) if (ncpu == NCPU)
panic("initmp: too many CPUs"); panic("initmp: too many CPUs");
if(ncpu != proc->apicid){
cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu, proc->apicid);
//ismp = 0;
}
if(proc->flags & MPBOOT) if(proc->flags & MPBOOT)
bcpu = &cpus[ncpu]; bcpu = &cpus[ncpu];
cpus[ncpu].id = ncpu; cpus[ncpu].id = ncpu;
cpus[ncpu].hwid = proc->apicid; cpus[ncpu].hwid = HWID(proc->apicid);
ncpu++; ncpu++;
p += sizeof(struct mpproc); p += sizeof(struct mpproc);
continue; continue;
......
...@@ -85,7 +85,7 @@ sampstart(void) ...@@ -85,7 +85,7 @@ sampstart(void)
for(struct cpu *c = cpus; c < cpus+ncpu; c++) { for(struct cpu *c = cpus; c < cpus+ncpu; c++) {
if(c == cpus+mycpu()->id) if(c == cpus+mycpu()->id)
continue; continue;
lapic_sampconf(c->id); lapic_sampconf(c->hwid);
} }
sampconf(); sampconf();
popcli(); popcli();
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论