📄 linedisc.c
字号:
/* * Copyright (C) 1998, 1999, Jonathan Adams. * Copyright (C) 2001, The EROS Group. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <eros/target.h>#include <eros/Invoke.h>#include <eros/ReturnerKey.h>#include <eros/ProcessKey.h>#include <eros/NodeKey.h>#include <eros/SleepKey.h>#include <eros/Key.h>#include <eros/StdKeyType.h>#include <domain/Runtime.h>#include "constituents.h"#include "linedisc.h"#include "cmpxchg.h"#include <domain/SpaceBankKey.h>#include <domain/ConstructorKey.h>#include <domain/ProtoSpace.h>#include <domain/domdbg.h>#define KR_DOMCRE 3#define KR_RETURNER 6#define KR_OSTREAM 7 /* DEBUGGING */#define KR_BUDDOM 8 /* for shoving the return key into */#define KR_CHRSRC 9#define KR_SCRATCH 10#define KR_SCRATCH2 11#define KR_ARG0 28 /* at startup, holds charsrc key */#define KR_ARG1 29#define KR_ARG2 30#define KR_RESUME 31 /* DON'T USE IT FOR ANYTHING ELSE! */const uint32_t defInputFlags = LD_In_DoInpProc | LD_In_Echo;/* (LD_In_DoInpProc | LD_In_LineMode | LD_In_Echo | LD_In_EchoCtrl | LD_In_VisErase | LD_In_VisKill | LD_In_SwapCRNL ); */const uint32_t defOutputFlags = (LD_Out_DoOutpProc | LD_Out_NLtoCRNL | LD_Out_CRtoNL );/* make sure this matches the positions in LineDiscKey.h */const uint16_t defCtrlChars[LD_Num_CC] = { LD_CC_EraseDef, LD_CC_AltEraseDef, LD_CC_EraseWordDef, LD_CC_KillLineDef, LD_CC_ReprintDef, LD_CC_QuoteDef, LD_CC_SFStopDef, LD_CC_SFStartDef};/* this is the under-routine for YIELD, defined in util.h */void __yield(void) /* SMASHES KR_SCRATCH2 */{ node_copy(KR_CONSTIT,KC_SLEEP,KR_SCRATCH2); sl_sleep(KR_SCRATCH2,0); /* sleep for 0 ms -- yields the processor */}void init_shared(void){ register uint32_t idx; assert(sizeof(struct shared) <= EROS_PAGE_SIZE); init_write_buff_ctl(&SHARED.wrt_buff.ctl); SHARED.readerWants = UINT32_MAX; SHARED.inpProcFlags = defInputFlags; SHARED.outpProcFlags = defOutputFlags; for (idx = 0; idx < LD_Num_CC; idx++) { SHARED.control_chars[idx] = defCtrlChars[idx]; } CLEAR_MASK(SHARED.char_mask); SHARED.linedisc_status = LD_Stat_Ready;}uint32_t start_buddy(uint32_t krSharedPage){ Message msg; register uint32_t retval; DEBUG(init) kprintf(KR_OSTREAM, "LineDisc: Calling buddy constructor\n"); /* make sure we won't smash the shared page */ assert(krSharedPage != KR_BUDDOM); node_copy(KR_CONSTIT, KC_BUDDYC, KR_BUDDOM); retval = constructor_request(KR_BUDDOM, KR_BANK, KR_SCHED, KR_CHRSRC, /* pass over the char source */ KR_BUDDOM); assert("Constructing buddy" && retval == RC_OK); /* KR_SCRATCH now holds a START key to our buddy. We CALL him back to trade the shared page for his domain key. */ DEBUG(init) kprintf(KR_OSTREAM, "LineDisc: Calling buddy with shared page, expecting a domkey\n"); msg.snd_key0 = krSharedPage; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_w1 = 0u; msg.snd_w2 = 0u; msg.snd_w3 = 0u; msg.snd_len = 0u; /* no data */ msg.rcv_key0 = KR_BUDDOM; /* he'll return a domain key */ msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_VOID; msg.rcv_key3 = KR_VOID; msg.rcv_len = 0u; /* no data */ msg.snd_invKey = KR_BUDDOM; msg.snd_code = RC_OK; /* We're doing fine */ retval = CALL(&msg); assert("starting buddy" && retval == RC_OK); DEBUG(init) kprintf(KR_OSTREAM, "LineDisc: Buddy CALLED me -- success!\n"); return RC_OK;}uint32_t wakeup_buddy(enum LD_WakeupReasons reasons){ charsrc_post_event(KR_CHRSRC, reasons | CharSrc_UserEvent(0)); return RC_OK;}void destroy_self(uint32_t retCode, bool buddyThere){ register uint32_t retval; uint32_t keyType; if (buddyThere) { /* tell my pal to jump off the bridge first */ DEBUG(destroy) kprintf(KR_OSTREAM, "LineDisc: Telling my buddy to suicide\n"); SHARED.linedisc_status = LD_Stat_TearDown; wakeup_buddy(LD_Wakeup_TearDown); /* wait for him to acknowledge */ while (SHARED.linedisc_status == LD_Stat_TearDown) YIELD(); /* he's gone now */ } /* get my address space into scratch */ retval = process_copy(KR_SELF, ProcAddrSpace, KR_SCRATCH); assert(retval == RC_OK); DEBUG(destroy) kprintf(KR_OSTREAM, "LineDisc: destroying databuff page\n"); /* get data page into scratch2 */ retval = node_copy(KR_SCRATCH, DATABUFF_SLOT, KR_SCRATCH2); assert(retval == RC_OK); key_kt(KR_SCRATCH2, &keyType, 0); if (keyType == AKT_Page) { /* sell the page back to the space bank */ retval = spcbank_return_data_page(KR_BANK, KR_SCRATCH2); if (retval != RC_OK) { kdprintf(KR_OSTREAM,"Returning databuff page to spacebank failed!\n"); } } else { DEBUG(destroy) kprintf(KR_OSTREAM, "LineDisc: Databuff not page\n"); } DEBUG(destroy) kprintf(KR_OSTREAM, "LineDisc: destroying shared page\n"); /* get shared page into scratch2 */ retval = node_copy(KR_SCRATCH, SHARED_SLOT, KR_SCRATCH2); assert(retval == RC_OK); key_kt(KR_SCRATCH2, &keyType, 0); if (keyType == AKT_Page) { /* sell the page back to the space bank */ retval = spcbank_return_data_page(KR_BANK, KR_SCRATCH2); if (retval != RC_OK) { kdprintf(KR_OSTREAM,"Returning shared page to spacebank failed!\n"); } } else { DEBUG(destroy) kprintf(KR_OSTREAM, "LineDisc: Shared not page\n"); } DEBUG(destroy) kdprintf(KR_OSTREAM, "LineDisc: Suiciding\n"); /* all of my stuff is gone, my buddy's gone -- better kill myself */ node_copy(KR_CONSTIT,KC_PROTO,KR_SCRATCH); /* FIXME: Due to Intel's broken architecture, I can't return anything but RC_OK to the caller. If retCode != RC_OK, what should I do? */ protospace_destroy(KR_RETURNER, KR_SCRATCH, KR_SELF, KR_DOMCRE, KR_BANK, 1); /* small space */ /* NOTREACHED */}#ifndef NDEBUGint __assert(const char *expr, const char *file, int line){ kdprintf(KR_OSTREAM, "%s:%d: Assertion failed: '%s'\n", file, line, expr); return 0;}#endifvoidinitialize_linedisc(void){ register uint32_t retval; /* copy stuff out of constit */ node_copy(KR_CONSTIT, KC_RETURNER, KR_RETURNER); node_copy(KR_CONSTIT, KC_OSTREAM, KR_OSTREAM); /* copy the character source key into its key reg. (I could use KR_SELF, but the Returner key is much cooler) */ copy_key_reg(KR_RETURNER, KR_ARG0, KR_CHRSRC); DEBUG(init) kprintf(KR_OSTREAM, "LineDisc: Returner worked -- buying shared page\n"); retval = process_copy(KR_SELF, ProcAddrSpace, KR_SCRATCH); assert("process_copy(ProcAddrSpace)" && retval == RC_OK); /* buy a new page and insert it into address space for the databuff*/ retval = spcbank_buy_data_pages(KR_BANK, 1, KR_SCRATCH2, 0, 0); assert("spcbank_buy_data_pages(1)" && retval == RC_OK); /* swap the new node in, putting the old contents over the address node */ retval = node_swap(KR_SCRATCH, DATABUFF_SLOT, KR_SCRATCH2, KR_SCRATCH); assert("node_swap(AddrSpc,DATABUFF_SLOT,newPage)" && retval == RC_OK); DEBUG(init) { uint32_t keyType; kprintf(KR_OSTREAM, "LineDisc: Databuff page installed -- checking " "previous occupant.\n"); key_kt(KR_SCRATCH, &keyType, 0); if (keyType != RC_Void) { kdprintf(KR_OSTREAM, "Hey! the previous occupant wasn't void!\n"); } kprintf(KR_OSTREAM, "LineDisc: Checking that databuff is actually there.\n"); assert(DATABUFF[0] == 0); DATABUFF[0] = 1; assert(DATABUFF[0] != 0); DATABUFF[0] = 0; kprintf(KR_OSTREAM, "LineDisc: Databuff there. \n"); } retval = process_copy(KR_SELF, ProcAddrSpace, KR_SCRATCH); assert("process_copy(ProcAddrSpace)" && retval == RC_OK); /* buy the page for the shared data */ retval = spcbank_buy_data_pages(KR_BANK, 1, KR_SCRATCH2, 0, 0); assert("spcbank_buy_data_pages(1)" && retval == RC_OK); /* swap the new node in, putting the old contents over the address node */ retval = node_swap(KR_SCRATCH, SHARED_SLOT, KR_SCRATCH2, KR_SCRATCH); assert("node_swap(AddrSpc,SHARED_SLOT,newPage)" && retval == RC_OK); DEBUG(init) { uint32_t keyType; kprintf(KR_OSTREAM, "LineDisc: Shared page installed -- checking " "previous occupant.\n"); key_kt(KR_SCRATCH, &keyType, 0); if (keyType != RC_Void) { kdprintf(KR_OSTREAM, "Hey! the previous occupant wasn't void!\n"); } } DEBUG(init) kprintf(KR_OSTREAM, "Initializing shared data\n"); init_shared(); DEBUG(init) kprintf(KR_OSTREAM, "LineDisc: Successfully initialized shared page\n"); /* initialize buddy */ retval = start_buddy(KR_SCRATCH2); assert("starting buddy" && retval == RC_OK); /* now get a start key so we can rock-and-roll */ retval = process_make_start_key(KR_SELF, 0u, KR_ARG0); assert("Making start key" && retval == RC_OK); /* done intializing */ return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -