Annotation of qemu/roms/SLOF/board-js2x/slof/OF.fs, revision 1.1

1.1     ! root        1: \ *****************************************************************************
        !             2: \ * Copyright (c) 2004, 2008 IBM Corporation
        !             3: \ * All rights reserved.
        !             4: \ * This program and the accompanying materials
        !             5: \ * are made available under the terms of the BSD License
        !             6: \ * which accompanies this distribution, and is available at
        !             7: \ * http://www.opensource.org/licenses/bsd-license.php
        !             8: \ *
        !             9: \ * Contributors:
        !            10: \ *     IBM Corporation - initial implementation
        !            11: \ ****************************************************************************/
        !            12: 
        !            13: \ The master file.  Everything else is included into here.
        !            14: 
        !            15: hex
        !            16: 
        !            17: ' ll-cr to cr
        !            18: 
        !            19: \ as early as possible we want to know if it is js20, js21 or bimini
        !            20: \ u3 = js20; u4 = js21/bimini
        !            21: \ the difference if bimini or js21 will be done later depending if
        !            22: \ obsidian or citrine is found
        !            23: \ f8000000 is probably the place of the u3/u4 version
        !            24: f8000000 rl@ CONSTANT uni-n-version
        !            25: uni-n-version 4 rshift  dup 3 = CONSTANT u3?  4 = CONSTANT u4?
        !            26: \ if (f4000682 >> 4) == 1... it is a bimini...
        !            27: f4000682 rb@ 4 rshift 1 = CONSTANT bimini?
        !            28: 
        !            29: \ to decide wether vga initialisation using bios emulation should be attempted,
        !            30: \ we need to know wether a vga-device was found during pci-scan.
        !            31: \ If it is found, this value will be set to the device's phandle
        !            32: 0 value vga-device-node?
        !            33: 
        !            34: \ planar-id reads back GPIO 29 30 31 and returns it as one value
        !            35: \ if planar-id >= 5 it should be GA2 else it is GA1 (JS20 only)
        !            36: defer planar-id  ( -- planar-id )
        !            37: 
        !            38: : (planar-id)  ( -- planar-id)
        !            39:    \ default implementation of planar-id just returns 8
        !            40:    \ the highest possible planar id for JS20 is 7
        !            41:    8
        !            42: ;
        !            43: 
        !            44: ' (planar-id) to planar-id
        !            45: 
        !            46: #include "header.fs"
        !            47: 
        !            48: \ I/O accesses.
        !            49: #include "io.fs"
        !            50: 
        !            51: \ XXX: Enable first UART on JS20, scripts forget to do this.  Sigh.
        !            52: 3 7 siocfg!  1 30 siocfg!
        !            53: 
        !            54: #include "serial.fs"
        !            55: 
        !            56: cr
        !            57: 
        !            58: #include "base.fs"
        !            59: 
        !            60: \ Little-endian accesses.  Also known as `wrong-endian'.
        !            61: #include <little-endian.fs>
        !            62: 
        !            63: \ do not free-mem if address is not within the heap
        !            64: \ workaround for NVIDIA card
        !            65: : free-mem  (  addr len -- )
        !            66:    over heap-start heap-end within  IF
        !            67:       free-mem
        !            68:    ELSE
        !            69:       2drop
        !            70:    THEN
        !            71: ;
        !            72: 
        !            73: : #join  ( lo hi #bits -- x )  lshift or ;
        !            74: : #split ( x #bits -- lo hi )  2dup rshift dup >r swap lshift xor r> ;
        !            75: 
        !            76: : blink ;
        !            77: 
        !            78: : reset-dual-emit ;
        !            79: 
        !            80: : console-clean-fifo ;
        !            81: 
        !            82: : bootmsg-nvupdate ;
        !            83: 
        !            84: : asm-cout 2drop drop ;
        !            85: 
        !            86: #include "logging.fs"
        !            87: 
        !            88: : log-string 2drop ;
        !            89: 
        !            90: #include "bootmsg.fs"
        !            91: 
        !            92: 000 cp
        !            93: 
        !            94: \ disable the nvram logging until we know if we are
        !            95: \ running from ram/takeover/js20 or in normal mode on js21
        !            96: : (nvramlog-write-byte)  drop ;
        !            97: ' (nvramlog-write-byte) to nvramlog-write-byte
        !            98: 
        !            99: #include "exception.fs"
        !           100: 
        !           101: : mm-log-warning 2drop ;
        !           102: 
        !           103: : write-mm-log ( data length type -- status )
        !           104:        3drop 0
        !           105: ;
        !           106: 
        !           107: 080 cp
        !           108: 
        !           109: #include "rtc.fs"
        !           110: 
        !           111: 100 cp
        !           112: 
        !           113: \ Input line editing.
        !           114: #include "accept.fs"
        !           115: 
        !           116: 120 cp
        !           117: 
        !           118: #include "dump.fs"
        !           119: 
        !           120: cistack ciregs >r1 ! \ kernel wants a stack :-)
        !           121: 
        !           122: #include "romfs.fs"
        !           123: 
        !           124: 140 cp
        !           125: #include "flash.fs"
        !           126: 
        !           127: \ 1 temp; 0 perm; let's default to temp
        !           128: 1 VALUE flashside?
        !           129: 
        !           130: \ claim the memory used by copy of the flash
        !           131: flash-header  IF
        !           132:    romfs-base dup flash-image-size 0 claim drop
        !           133: THEN
        !           134: 
        !           135: s" bootinfo" romfs-lookup drop c + l@ CONSTANT start-addr
        !           136: start-addr flash-addr <> CONSTANT takeover?
        !           137: 
        !           138: takeover? u3? or 0=  IF
        !           139:    \ we want nvram logging to work
        !           140:    ['] .nvramlog-write-byte to nvramlog-write-byte
        !           141: THEN
        !           142: 
        !           143: 160 cp
        !           144: 
        !           145: u4? IF f8002100 rl@ 0= ELSE false THEN  ?INCLUDE u4-mem.fs
        !           146: u3?  IF
        !           147:    planar-id 5 >=  IF
        !           148:       40000 to nvram-size
        !           149:    ELSE
        !           150:       \ change nvram-size to 8000 for GA1 blades
        !           151:       8000 to nvram-size
        !           152:    THEN
        !           153: THEN
        !           154: 
        !           155: 
        !           156: takeover?  IF
        !           157:    \ potentially comming from phype
        !           158:    u4?  IF
        !           159:       \ takeover on JS21 is using some nvram area
        !           160:       \ which might be available
        !           161:       \ on JS20 the nvram is too small and
        !           162:       \ we just overwrite the nvram
        !           163:       sec-nvram-base to nvram-base
        !           164:    THEN
        !           165:    sec-nvram-size to nvram-size
        !           166:    \ in takeover mode the nvram is probably not mapped
        !           167:    \ to the exact location where the nvram starts
        !           168:    \ doing a small check to see if we have a partition
        !           169:    \ starting with 70; this test is far from perfect but
        !           170:    \ takeover is not the most common mode of running slof
        !           171:    nvram-base rb@ 70 <>  IF  0 nvram-base rb!  THEN
        !           172: THEN
        !           173: 
        !           174: 200 cp
        !           175: 
        !           176: #include <slof-logo.fs>
        !           177: #include <banner.fs>
        !           178: 
        !           179: : .banner .slof-logo .banner ;
        !           180: 
        !           181: \ Get the secondary CPUs into our own spinloop.
        !           182: f8000050 rl@ CONSTANT master-cpu
        !           183: \ cr .( The master cpu is #) master-cpu .
        !           184: 
        !           185: VARIABLE cpu-mask
        !           186: : get-slave ( n -- online? )
        !           187:   0 3ff8 ! 18 lshift 30000000 or 48003f02 over l! icbi 10000 0 DO LOOP 3ff8 @ ;
        !           188: : mark-online ( n -- )  1 swap lshift cpu-mask @ or cpu-mask ! ;
        !           189: : get-slaves  40 0 DO i get-slave IF i mark-online THEN LOOP ;
        !           190: : cpu-report  ( -- )
        !           191:    cpu-mask @ 40 0  DO  dup 1 and  IF  ." #" i .  THEN  1 rshift  LOOP  drop
        !           192: ;
        !           193: 
        !           194: 220 cp
        !           195: master-cpu mark-online get-slaves
        !           196: 
        !           197: DEFER disable-watchdog ( -- )
        !           198: DEFER find-boot-sector ( -- )
        !           199: 
        !           200: 
        !           201: 240 cp
        !           202: \ Timebase frequency, in Hz.
        !           203: \ -1 VALUE tb-frequency
        !           204: d# 14318378 VALUE tb-frequency   \ default value - needed for "ms" to work
        !           205: -1 VALUE cpu-frequency
        !           206: 
        !           207: #include "helper.fs"
        !           208: 260 cp
        !           209: 
        !           210: #include <timebase.fs>
        !           211: 
        !           212: 280 cp
        !           213: 
        !           214: \ rtas-config is not used
        !           215: 0 CONSTANT rtas-config
        !           216: 
        !           217: #include "rtas.fs"
        !           218: 290 cp
        !           219: s" update_flash.fs" included
        !           220: 2a0 cp
        !           221: cpu-mask @ rtas-fetch-cpus drop
        !           222: 
        !           223: : of-start-cpu rtas-start-cpu ;
        !           224: 
        !           225: ' power-off to halt
        !           226: ' rtas-system-reboot to reboot
        !           227: 
        !           228: : other-firmware  rtas-get-flashside 0= IF 1 ELSE 0 THEN rtas-set-flashside reboot ;
        !           229: : disable-boot-watchdog rtas-stop-bootwatchdog drop ;
        !           230: ' disable-boot-watchdog to disable-watchdog
        !           231: 
        !           232: true value bmc?
        !           233: false value debug-boot?
        !           234: 
        !           235: \ for JS21/Bimini try to detect BMC... if kcs (io @ca8) status is not ff...
        !           236: u4? IF ca8 4 + io-c@ ff = IF false to bmc? true to debug-boot? THEN THEN
        !           237: 
        !           238: VARIABLE memnode
        !           239: 
        !           240: \ Hook to help loading our secondary boot loader.
        !           241: DEFER disk-read ( lba cnt addr -- )
        !           242: 0 VALUE disk-off
        !           243: 
        !           244: create vpd-cb 24 allot
        !           245: create vpd-bootlist 4 allot
        !           246: 2c0 cp
        !           247: #include "ipmi-vpd.fs"
        !           248: 2e0 cp
        !           249: #include <quiesce.fs>
        !           250: 300 cp
        !           251: #include <usb/usb-static.fs>
        !           252: 320 cp
        !           253: #include <scsi-loader.fs>
        !           254: #include <root.fs>
        !           255: 360 cp
        !           256: #include "tree.fs"
        !           257: 
        !           258: : .system-information  ( -- )
        !           259:    s"                   " type cr
        !           260:    s" SYSTEM INFORMATION" type cr
        !           261:    s"  Processor  = " type s" cpu" get-chosen  IF
        !           262:       drop l@ >r pvr@ s" pvr>name" r> $call-method type
        !           263:       s"  @ " type cpu-frequency d# 1000000 /
        !           264:       decimal . hex s" MHz" type
        !           265:    THEN  cr s"  I/O Bridge = " type u3?  IF
        !           266:       s" U3"  ELSE  s" U4"  THEN type
        !           267:    f8000000 rl@ 4 rshift s"  (" type 1 0.r s" ." type
        !           268:    f8000000 rl@ f and 1 0.r s" )" type cr
        !           269:    s"  SMP Size   = " type cpu-mask @ cnt-bits 1 0.r
        !           270:    s"  (" type cpu-report 8 emit s" )" type
        !           271:    cr s"  Boot-Date  = " type .date cr
        !           272:    s"  Memory     = " type s" memory" get-chosen  IF
        !           273:       drop l@ s" mem-report" rot $call-method  THEN
        !           274:    cr s"  Board Type = " type u3?  IF
        !           275:       s" JS20(GA" type planar-id 5 >=  IF
        !           276:          s" 2)" ELSE s" 1)" THEN type
        !           277:    ELSE bimini?  IF  s" Bimini"  ELSE  s" JS21"  THEN  type  THEN
        !           278:    s"  (" type .vpd-machine-type [char] / emit
        !           279:    .vpd-machine-serial [char] / emit
        !           280:    .vpd-hw-revision 8 emit  s" )" type cr
        !           281:    s"  MFG Date   = " type .vpd-manufacturer-date cr
        !           282:    s"  Part No.   = " type .vpd-part-number cr
        !           283:    s"  FRU No.    = " type .vpd-fru-number cr
        !           284:    s"  FRU Serial = " type .vpd-cardprefix-serial .vpd-card-serial cr
        !           285:    s"  UUID       = " type .vpd-uuid cr
        !           286:    s"  Flashside  = " type rtas-get-flashside 0=  IF
        !           287:       ." 0 (permanent)"
        !           288:    ELSE
        !           289:       ." 1 (temporary)" THEN cr
        !           290:    s"  Version    = " type 
        !           291:    takeover?  IF
        !           292:       romfs-base 38 + a type
        !           293:    ELSE
        !           294:       slof-build-id here swap rmove 
        !           295:       here slof-build-id nip type cr
        !           296:       s"  Build Date = " type bdate2human type
        !           297:    THEN
        !           298:    cr cr
        !           299: ;
        !           300: 
        !           301: 800 cp
        !           302: 
        !           303: #include "nvram.fs"
        !           304: takeover? not u4? and  IF
        !           305:    \ if were are not in takeover mode the nvram should look
        !           306:    \ something like this:
        !           307:    \ type  size  name
        !           308:    \ ========================
        !           309:    \  51  20000  ibm,CPU0log
        !           310:    \  51   5000  ibm,CPU1log
        !           311:    \  70   1000  common
        !           312:    \  7f  da000  <free-space>
        !           313:    \ the partition with the type 51 should have been added
        !           314:    \ by LLFW... if it does not exist then something went
        !           315:    \ wrong and we just destroy the whole thing
        !           316:    51 get-nvram-partition IF  0 0 nvram-c!  ELSE  2drop  THEN
        !           317: THEN
        !           318: 
        !           319: 880 cp
        !           320: 
        !           321: \ dmesg/dmesg2 not available if running in takeover/ram mode or on js20
        !           322: : dmesg  ( -- )  u3? takeover? or 0=  IF  dmesg  THEN ;
        !           323: : dmesg2  ( -- )  u3? takeover? or 0=  IF  dmesg2  THEN ;
        !           324: 
        !           325: #include "envvar.fs"
        !           326: check-for-nvramrc
        !           327: 
        !           328: 8a0 cp
        !           329: \ The client interface.
        !           330: #include "client.fs"
        !           331: \ ELF binary file format.
        !           332: #include "elf.fs"
        !           333: #include <loaders.fs>
        !           334: 
        !           335: : bios-exec ( arg len -- rc )
        !           336:    s" snk" romfs-lookup 0<> IF load-elf-file drop start-elf64
        !           337:    ELSE 2drop false THEN
        !           338: ;
        !           339: 
        !           340: \ check wether a VGA device was found during pci scan, if it was
        !           341: \ try to initialize it and create the needed device-nodes
        !           342: 0 value biosemu-vmem
        !           343: 100000 value biosemu-vmem-size
        !           344: 0 value screen-info
        !           345: 
        !           346: vga-device-node? 0<> use-biosemu? AND IF
        !           347:    s" VGA Device found: " type vga-device-node? node>path type s"  initializing..." type cr
        !           348:    \ claim virtual memory for biosemu of 1MB
        !           349:    biosemu-vmem-size 4 claim to biosemu-vmem
        !           350:    \ claim memory for screen-info struct (140 bytes)
        !           351:    d# 140 4 claim to screen-info
        !           352:    \ remember current-node (it might be node 0 so we cannot use get-node)
        !           353:    current-node @
        !           354:    \ change into vga device node
        !           355:    vga-device-node? set-node
        !           356:    \ run biosemu to initialize the vga card
        !           357:    \ s" Time before biosemu:" type .date cr
        !           358:    vga-device-node? node>path ( pathstr len )
        !           359:    s" biosemu " biosemu-vmem $cathex ( pathstr len paramstr len )
        !           360:    20 char-cat \ add a space ( pathstr len paramstr len )
        !           361:    biosemu-vmem-size $cathex \ add VMEM Size ( pathstr len paramstr len )
        !           362:    20 char-cat \ add a space ( pathstr len paramstr len )
        !           363:    2swap $cat ( paramstr+path len )
        !           364:    biosemu-debug 0<> IF
        !           365:       20 char-cat biosemu-debug $cathex \ add biosemu-debug as param
        !           366:       ( paramstr+path+biosemu-debug len )
        !           367:    THEN
        !           368:    bios-exec
        !           369:    \ s" Time after biosemu:" type .date cr
        !           370:    s" VGA initialization: detecting displays..." type cr
        !           371:    \ try to get info for two monitors
        !           372:    2 0 DO 
        !           373:       \ setup screen-info struct as input to get_vbe_info
        !           374:       s" DDC" 0 char-cat screen-info swap move \ null-terminated "DDC" as signature
        !           375:       d# 140 screen-info 4 + w! \ reserved size in bytes (see claim above)
        !           376:       i screen-info 6 + c! \ monitor number
        !           377:       \ 320 screen-info 7 + w! \ max. screen width (800)
        !           378:       500 screen-info 7 + w! \ max. screen width (1280)
        !           379:       \ following line would be the right thing to do, however environment seems not setup yet...
        !           380:       \ screen-#columns char-width * 500 min 280 max screen-info 7 + w! \ max. screen width, calculated from environment variable screen-#columns, but max. 1280, min. 640...
        !           381:       8 screen-info 9 + c! \ requested color depth (8bpp)
        !           382:       \ d# 16 screen-info 9 + c! \ requested color depth (16bpp)
        !           383:       \ execute get_vbe_info from load-base
        !           384:       \ s" Time before client exec:" type .date cr
        !           385:       \ since node>path overwrites strings created with s" 
        !           386:       \ we need to call it before assembling the parameter string
        !           387:       vga-device-node? node>path ( pathstr len )
        !           388:       s" get_vbe_info " biosemu-vmem $cathex ( pathstr len paramstr len )
        !           389:       20 char-cat \ add a space ( pathstr len paramstr len )
        !           390:       biosemu-vmem-size $cathex \ add VMEM Size ( pathstr len paramstr len )
        !           391:       20 char-cat \ add a space ( pathstr len paramstr len )
        !           392:       2swap $cat ( paramstr+path len )
        !           393:       20 char-cat
        !           394:       screen-info $cathex bios-exec
        !           395:       \ s" Time after client exec:" type .date cr
        !           396:       screen-info c@ 0<> IF
        !           397:         s"   display " type i . s" found..." type 
        !           398:         \ screen found
        !           399:         \ create device entry
        !           400:         get-node node>name \ get current nodes name (e.g. "vga") ( str len )
        !           401:         i \ put display-num on the stack ( str len displaynum )
        !           402:         new-device \ create new device
        !           403:            s" vga-display.fs" included
        !           404:         finish-device
        !           405:         s" created." type cr
        !           406:       THEN
        !           407:    LOOP
        !           408:    \ return to where we were before changing to vga device node
        !           409:    set-node
        !           410:    \ release the claimed memory
        !           411:    screen-info d# 140 release 
        !           412:    biosemu-vmem biosemu-vmem-size release
        !           413: 
        !           414:    s" VGA initialization done." type cr
        !           415: THEN \ vga-device-node?
        !           416: 
        !           417: : enable-framebuffer-output  ( -- )
        !           418: \ enable output on framebuffer
        !           419:    s" screen" find-alias ?dup  IF
        !           420:       \ we need to open/close the screen device once
        !           421:       \ before "ticking" display-emit to emit
        !           422:       open-dev close-node
        !           423:       s" display-emit" $find  IF 
        !           424:          to emit 
        !           425:       ELSE
        !           426:          2drop
        !           427:       THEN
        !           428:    THEN
        !           429: ;
        !           430: 
        !           431: enable-framebuffer-output
        !           432: 
        !           433: 8b0 cp
        !           434: 
        !           435: \ do not let the usb scan overwrite the atapi cdrom alias
        !           436: pci-cdrom-num TO cdrom-alias-num
        !           437: usb-scan
        !           438: 
        !           439: : create-aliases  ( -- )
        !           440:    s" net" s" net1" find-alias ?dup  IF  set-alias ELSE 2drop  THEN
        !           441:    s" disk" s" disk0" find-alias ?dup  IF  set-alias  ELSE  2drop  THEN
        !           442:    s" cdrom" s" cdrom0" find-alias ?dup  IF  set-alias  ELSE  2drop  THEN
        !           443: ;
        !           444: 
        !           445: create-aliases
        !           446: 
        !           447: 8ff cp
        !           448: 
        !           449: .system-information
        !           450: 
        !           451: : directserial
        !           452: u3? IF
        !           453:        s" /ht/isa/serial@3f8" io
        !           454: ELSE
        !           455:        s" direct-serial?" evaluate IF s" /ht/isa/serial@2f8" io ELSE s" /ht/isa/serial@3f8" io THEN
        !           456: THEN
        !           457: ;
        !           458: 
        !           459: directserial
        !           460:   
        !           461: \ on bimini we want to automatically enable screen and keyboard, if they are detected...
        !           462: bimini? IF
        !           463:    key? IF
        !           464:       cr ."    input available on current console input device, not switching input / output." cr
        !           465:    ELSE
        !           466:       \ this enables the framebuffer as primary output device
        !           467:       s" screen" find-alias  IF  drop
        !           468:          s" screen" output
        !           469:          \ at this point serial output is theoretically disabled
        !           470:          ."    screen detected and set as default output device" cr
        !           471:       THEN
        !           472:       \ enable USB keyboard
        !           473:       s" keyboard" find-alias  IF  drop
        !           474:          s" keyboard" input
        !           475:          \ at this point serial input is disabled
        !           476:          ."    keyboard detected and set as default input device" cr cr cr
        !           477:          s"   Press 's' to enter Open Firmware." type cr
        !           478:          500 ms
        !           479:       THEN
        !           480:    THEN
        !           481: THEN
        !           482: 
        !           483: : .flashside
        !           484:    cr ." The currently active flashside is: "
        !           485:    rtas-get-flashside 0= IF ." 0 (permanent)" ELSE
        !           486:    ." 1 (temporary)" THEN
        !           487: ;
        !           488: 
        !           489: bmc? IF  disable-watchdog  THEN
        !           490: 
        !           491: : flashsave  ( "{filename}" -- rc )
        !           492:   (parse-line) dup 0> IF
        !           493:     s" netsave "             \ command
        !           494:     get-flash-base $cathex   \ Flash base addr
        !           495:     s"  400000 " $cat        \ Flash size (4MB)
        !           496:     2swap $cat               \ add parameters from (parse-line)
        !           497:     evaluate
        !           498:   ELSE
        !           499:     cr
        !           500:     ." Usage: flashsave [bootp|dhcp,]filename[,siaddr][,ciaddr][,giaddr][,bootp-retries][,tftp-retries][,use_ci]"
        !           501:     cr 2drop
        !           502:   THEN
        !           503: ;
        !           504: 
        !           505: #include <vpd-bootlist.fs>
        !           506: 
        !           507: \ for the blades we read the bootlist from the VPD
        !           508: bimini? takeover? or 0=  IF  ['] vpd-boot-import to read-bootlist  THEN
        !           509: 
        !           510: \ for the bimini, we try to boot from disk, if it exists, 
        !           511: \ only if "boot-device" is not set in the nvram
        !           512: : bimini-bootlist
        !           513:    \ check nvram
        !           514:    s" boot-device" evaluate swap drop ( boot-device-strlen )
        !           515:    0= IF
        !           516:       \ no boot-device set in NVRAM, check if disk is available and set it...
        !           517:       \ clear boot-device list
        !           518:       0 0 set-boot-device
        !           519:       s" disk" find-alias ?dup IF
        !           520:          \ alias found, use it as default
        !           521:          add-boot-device
        !           522:       THEN
        !           523:    THEN
        !           524: ;
        !           525: 
        !           526: bimini? IF ['] bimini-bootlist to read-bootlist THEN
        !           527: 
        !           528: #include <start-up.fs>
        !           529: 
        !           530: #include <boot.fs>
        !           531: 
        !           532: cr .(   Welcome to Open Firmware)
        !           533: cr
        !           534: #include "copyright-oss.fs"
        !           535: cr
        !           536: 
        !           537: \ this CATCH is to ensure the code bellow always executes:  boot may ABORT!
        !           538: ' start-it CATCH drop
        !           539: 
        !           540: #include <history.fs>
        !           541: nvram-history? [IF]
        !           542: ." loading shell history .. "
        !           543: history-load
        !           544: ." done" cr
        !           545: [THEN]
        !           546: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.