⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 constructor.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * 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. *//* A constructor is responsible for building program instances.  The * constructor holds copies of each entry of the constituents node. In * addition, it holds the target process' keeper key, address space * key, symbol table ke, and initial PC. * * BOOTSTRAP NOTE 1: *  * To simplify system image construction, the constructor does some * minimal analysis at startup time.  If KC_PROD_CON0 and KC_PROD_XCON * are not void, they are accepted as holding the product constituents, * and KC_DCC should hold the domain creator for the constituents. *  * If initial constituents are found, the factory startup code assumes * that the factory should be initially sealed, and that no holes beyond * those that are apparent from the initial constituents are present, * and that KC_DCC is the actual domain creator. */#include <eros/target.h>#include <eros/Invoke.h>#include <eros/DiscrimKey.h>#include <eros/ReturnerKey.h>#include <eros/NodeKey.h>#include <eros/ProcessKey.h>#include <eros/Key.h>#include <eros/StdKeyType.h>#include <eros/ProcessState.h>#include <domain/domdbg.h>#include <domain/ConstructorKey.h>#include <domain/ProcessCreatorKey.h>#include <domain/PccKey.h>#include <domain/ProtoSpace.h>#include <domain/SpaceBankKey.h>#include <domain/Runtime.h>#include "constituents.h"uint32_t __rt_unkept = 1;#define KR_SCRATCH      KR_APP(0)#define KR_RETURNER     KR_APP(1)#define KR_OSTREAM      KR_APP(2)#define KR_YIELDCRE     KR_APP(3)#define KR_YIELDBITS    KR_APP(4)#define KR_NEWDOM       KR_APP(5)#define KR_PROD_CON0    KR_APP(6) /* product's constituents */#define KR_PROD_XCON    KR_APP(7) /* product's extended constituents */#define KR_RO_YIELDBITS KR_APP(8) /* product's extended constituents */#define KR_ARG0    KR_ARG(0)#define KR_ARG1    KR_ARG(1)#define KR_ARG2    KR_ARG(2)#if 0#define KC_DISCRIM  0#define KC_RETURNER 1#define KC_OSTREAM  2#define KC_DCC      3#define KC_PROTOSPC 4#define KC_MYDOMCRE 5#define KC_PROD_CON0 14#define KC_PROD_XCON 15#endif/* Extended Constituents: */#define XCON_KEEPER     0#define XCON_ADDRSPACE  1#define XCON_SYMTAB     2#define XCON_PC         3#define DEBUG if (0)typedef struct {  int frozen;  int has_holes;} ConstructorInfo;voidCheckDiscretion(uint32_t kr, ConstructorInfo *ci){  uint32_t result;  uint32_t keyInfo;  uint32_t isDiscreet;    node_copy(KR_CONSTIT, KC_DISCRIM, KR_SCRATCH);  result = discrim_verify(KR_SCRATCH, kr, &isDiscreet);  if (result == RC_OK && isDiscreet)    return;  node_copy(KR_CONSTIT, KC_YIELDCRE, KR_SCRATCH);  result = proccre_amplify_gate(KR_SCRATCH, kr, KR_SCRATCH, 0, &keyInfo);  if (result == RC_OK && keyInfo == 0) {    uint32_t isDiscreet;    /* This key is a requestor's key to a constructor. Ask the       constructor if it is discreet */    result = constructor_is_discreet(kr, &isDiscreet);    if (result == RC_OK && isDiscreet)      return;  }  ci->has_holes = 1;}voidInitConstructor(ConstructorInfo *ci){  uint32_t result;  uint32_t keyType;  ci->frozen = 0;  ci->has_holes = 0;    node_copy(KR_CONSTIT, KC_OSTREAM, KR_OSTREAM);  DEBUG kdprintf(KR_OSTREAM, "constructor init\n");    node_copy(KR_CONSTIT, KC_PROD_CON0, KR_PROD_CON0);  result = key_kt(KR_PROD_CON0, &keyType, 0);  if (result != RC_Void) {    /* This is an initially frozen constructor.  Use the provided       constituents, and assume that KC_YIELDCRE already holds the       proper domain creator. */    node_copy(KR_CONSTIT, KC_YIELDCRE, KR_YIELDCRE);    node_copy(KR_CONSTIT, KC_PROD_CON0, KR_PROD_CON0);    node_copy(KR_CONSTIT, KC_PROD_XCON, KR_PROD_XCON);    ci->frozen = 1;  }  else {    /* Build a new domain creator for use in crafting products */    /* use KR_YIELDCRE and KR_DISCRIM as scratch regs for a moment: */    node_copy(KR_CONSTIT, KC_PCC, KR_YIELDCRE);    node_copy(KR_SELF, ProcSched, KR_SCRATCH);    {      Message msg;      msg.snd_key0 = KR_BANK;      msg.snd_key1 = KR_SCRATCH;      msg.snd_key2 = KR_VOID;      msg.snd_key3 = KR_VOID;      msg.snd_data = 0;      msg.snd_len = 0;      msg.snd_code = OC_PCC_CreateProcessCreator;      msg.snd_invKey = KR_YIELDCRE;      msg.rcv_key0 = KR_YIELDCRE;      msg.rcv_key1 = KR_VOID;      msg.rcv_key2 = KR_VOID;      msg.rcv_key3 = KR_VOID;      msg.rcv_len = 0;		/* no data returned */      result = CALL(&msg);      DEBUG kdprintf(KR_OSTREAM, "GOT DOMCRE Result is 0x%08x\n", result);    }      spcbank_buy_nodes(KR_BANK, 2, KR_PROD_CON0, KR_PROD_XCON, KR_VOID);  }      /* Create a runtime bits node appropriate for our yields: */  spcbank_buy_nodes(KR_BANK, 1, KR_YIELDBITS, KR_VOID, KR_VOID);  node_clone(KR_YIELDBITS, KR_RTBITS);  node_swap(KR_YIELDBITS, RKT_CREATOR, KR_YIELDCRE, KR_VOID);  /* Now make the yieldbits key read-only. */  {    uint16_t keyData;    node_get_key_data(KR_YIELDBITS, &keyData);    node_make_node_key(KR_YIELDBITS, SEGMODE_RO | EROS_PAGE_BLSS,		       KR_RO_YIELDBITS);   }  node_copy(KR_CONSTIT, KC_RETURNER, KR_RETURNER);}/* In spite of unorthodox fabrication, the constructor self-destructs   in the usual way. */voidSepuku(){  /* FIX: giving up the constituent nodes breaks our products */    /* Give up the first constituent node. */  /* Give up the second constituent node */  spcbank_return_node(KR_BANK, KR_PROD_CON0);  spcbank_return_node(KR_BANK, KR_PROD_XCON);  spcbank_return_node(KR_BANK, KR_YIELDBITS);  /* node_copy(KR_CONSTIT, KC_MYDOMCRE, KR_DOMCRE); */  node_copy(KR_CONSTIT, KC_PROTOSPACE, KR_PROD_CON0);  spcbank_return_node(KR_BANK, KR_CONSTIT);  /* Invoke the protospace with arguments indicating that we should be     demolished as a small space domain */  protospace_destroy(KR_RETURNER, KR_PROD_CON0, KR_SELF,		     KR_CREATOR, KR_BANK, 1);}uint32_tMakeNewProduct(Message *msg){  uint32_t result;  struct Registers regs;  DEBUG kdprintf(KR_OSTREAM, "Making new product...\n");  result = proccre_create_process(KR_YIELDCRE, KR_ARG0, KR_NEWDOM);  if (result != RC_OK)    return result;  /* NOTE that if proccre_create_process succeeded, we know it's a good     space bank. */    /* Build a constiuents node, since we will need the scratch register     later */  result = spcbank_buy_nodes(KR_ARG0, 1, KR_SCRATCH, KR_VOID, KR_VOID);  if (result != RC_OK)    goto destroy_product;  /* clone the product constituents into the new constituents node: */  node_clone(KR_SCRATCH, KR_PROD_CON0);  (void) process_swap_keyreg(KR_NEWDOM, KR_CONSTIT, KR_SCRATCH, KR_VOID);  (void) process_swap_keyreg(KR_NEWDOM, KR_RTBITS, KR_RO_YIELDBITS, KR_VOID);  DEBUG kdprintf(KR_OSTREAM, "Populate new domain\n");  (void) node_copy(KR_CONSTIT, KC_PROTOSPACE, KR_SCRATCH);  /* Install protospace into the domain root: */  (void) process_swap(KR_NEWDOM, ProcAddrSpace, KR_SCRATCH, KR_VOID);  DEBUG kdprintf(KR_OSTREAM, "Installed protospace\n");  /* Install the schedule key into the domain: */  (void) process_swap(KR_NEWDOM, ProcSched, KR_ARG1, KR_VOID);    DEBUG kdprintf(KR_OSTREAM, "Installed sched\n");  /* Keeper constructor to keeper slot */  (void) node_copy(KR_PROD_XCON, XCON_KEEPER, KR_SCRATCH);  (void) process_swap(KR_NEWDOM, ProcKeeper, KR_SCRATCH, KR_VOID);  /* Fetch out the register values, mostly for the benefit of     Retrieving the PC -- this prevents us from needing to hard-code     the PC, which will inevitably change. */  (void) process_get_regs(KR_NEWDOM, &regs);  DEBUG kdprintf(KR_OSTREAM, "Got regs\n");  /* Unless we set them otherwise, the register values are zero.  The     PC has already been set.  We now need to initialize the stack     pointer and the segment registers. */  regs.CS = DOMAIN_CODE_SEG;  regs.SS = DOMAIN_DATA_SEG;  regs.DS = DOMAIN_DATA_SEG;  regs.ES = DOMAIN_DATA_SEG;  regs.FS = DOMAIN_DATA_SEG;  regs.GS = DOMAIN_DATA_SEG;  regs.pc = 0;			/* Place Holder!! */  regs.EFLAGS = 0x200;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -