X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86%2Flib.c;h=2039924d5051837e9f6082381093a5b57bd40489;hb=c1b33e91984102c1aa9a2ffe19f02c315b481726;hp=6b3d72281a23012c9c4bb85ac6b78117a57f9f12;hpb=d5ba2e6250feee1c3a30c0b40ec03f3d9d77fb56;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/lib.c b/KernelLand/Kernel/arch/x86/lib.c index 6b3d7228..2039924d 100644 --- a/KernelLand/Kernel/arch/x86/lib.c +++ b/KernelLand/Kernel/arch/x86/lib.c @@ -8,6 +8,7 @@ #include #include #include // GetCPUNum +#include #define TRACE_LOCKS 0 @@ -28,6 +29,7 @@ extern tMutex glPhysAlloc; Uint64 __divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem); Uint64 __udivdi3(Uint64 Num, Uint64 Den); Uint64 __umoddi3(Uint64 Num, Uint64 Den); +void Debug_SerialIRQHandler(int irq, void *unused); // === GLOBALS === int gbDebug_SerialSetup = 0; @@ -85,6 +87,12 @@ void SHORTLOCK(struct sShortSpinlock *Lock) __ASM__ ("pushf;\n\tpop %0" : "=r"(IF)); IF &= 0x200; // AND out all but the interrupt flag + if( CPU_HAS_LOCK(Lock) ) + { + Panic("Double lock of %p, %p req, %p has", Lock, __builtin_return_address(0), Lock->LockedBy); + for(;;); + } + #if TRACE_LOCKS if( TRACE_LOCK_COND ) { @@ -98,6 +106,7 @@ void SHORTLOCK(struct sShortSpinlock *Lock) // Wait for another CPU to release __AtomicTestSetLoop( (Uint*)&Lock->Lock, cpu ); Lock->IF = IF; + Lock->LockedBy = __builtin_return_address(0); #if TRACE_LOCKS if( TRACE_LOCK_COND ) @@ -182,7 +191,9 @@ void Debug_PutCharDebug(char ch) outb(SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit outb(SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it outb(SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + outb(SERIAL_PORT + 1, 0x05); // Enable ERBFI (Rx Full), ELSI (Line Status) gbDebug_SerialSetup = 1; + IRQ_AddHandler(4, Debug_SerialIRQHandler, NULL); } while( (inb(SERIAL_PORT + 5) & 0x20) == 0 ); outb(SERIAL_PORT, ch); @@ -195,6 +206,17 @@ void Debug_PutStringDebug(const char *String) Debug_PutCharDebug(*String++); } +void Debug_SerialIRQHandler(int irq, void *unused) +{ + if( (inb(SERIAL_PORT+5) & 0x01) == 0 ) { + Debug("IRQ4, no data"); + return ; + } + + char ch = inb(SERIAL_PORT); + Serial_ByteReceived(gSerial_KernelDebugPort, ch); +} + // === IO Commands === void outb(Uint16 Port, Uint8 Data) { @@ -344,6 +366,10 @@ DEF_DIVMOD(64); Uint64 DivMod64U(Uint64 Num, Uint64 Div, Uint64 *Rem) { + if( Div == 16 ) { + if(Rem) *Rem = Num & 15; + return Num >> 4; + } if( Div < 0x100000000ULL && Num < 0xFFFFFFFF * Div ) { Uint32 rem, ret_32; __asm__ __volatile__(