/* * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. * Copyright (C) 2011 Google, Inc. * * Author: * Jay Cheng * James Wylder * Benoit Goby * Colin Cross * Hiroshi DOYU * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * 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. * */ #include #include #include #include #define DRV_NAME "tegra-ahb" #define AHB_ARBITRATION_DISABLE 0x00 #define AHB_ARBITRATION_PRIORITY_CTRL 0x04 #define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29) #define PRIORITY_SELECT_USB BIT(6) #define PRIORITY_SELECT_USB2 BIT(18) #define PRIORITY_SELECT_USB3 BIT(17) #define AHB_GIZMO_AHB_MEM 0x0c #define ENB_FAST_REARBITRATE BIT(2) #define DONT_SPLIT_AHB_WR BIT(7) #define AHB_GIZMO_APB_DMA 0x10 #define AHB_GIZMO_IDE 0x18 #define AHB_GIZMO_USB 0x1c #define AHB_GIZMO_AHB_XBAR_BRIDGE 0x20 #define AHB_GIZMO_CPU_AHB_BRIDGE 0x24 #define AHB_GIZMO_COP_AHB_BRIDGE 0x28 #define AHB_GIZMO_XBAR_APB_CTLR 0x2c #define AHB_GIZMO_VCP_AHB_BRIDGE 0x30 #define AHB_GIZMO_NAND 0x3c #define AHB_GIZMO_SDMMC4 0x44 #define AHB_GIZMO_XIO 0x48 #define AHB_GIZMO_BSEV 0x60 #define AHB_GIZMO_BSEA 0x70 #define AHB_GIZMO_NOR 0x74 #define AHB_GIZMO_USB2 0x78 #define AHB_GIZMO_USB3 0x7c #define IMMEDIATE BIT(18) #define AHB_GIZMO_SDMMC1 0x80 #define AHB_GIZMO_SDMMC2 0x84 #define AHB_GIZMO_SDMMC3 0x88 #define AHB_MEM_PREFETCH_CFG_X 0xd8 #define AHB_ARBITRATION_XBAR_CTRL 0xdc #define AHB_MEM_PREFETCH_CFG3 0xe0 #define AHB_MEM_PREFETCH_CFG4 0xe4 #define AHB_MEM_PREFETCH_CFG1 0xec #define AHB_MEM_PREFETCH_CFG2 0xf0 #define PREFETCH_ENB BIT(31) #define MST_ID(x) (((x) & 0x1f) << 26) #define AHBDMA_MST_ID MST_ID(5) #define USB_MST_ID MST_ID(6) #define USB2_MST_ID MST_ID(18) #define USB3_MST_ID MST_ID(17) #define ADDR_BNDRY(x) (((x) & 0xf) << 21) #define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0) #define AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID 0xf8 #define AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE BIT(17) static struct platform_driver tegra_ahb_driver; static const u32 tegra_ahb_gizmo[] = { AHB_ARBITRATION_DISABLE, AHB_ARBITRATION_PRIORITY_CTRL, AHB_GIZMO_AHB_MEM, AHB_GIZMO_APB_DMA, AHB_GIZMO_IDE, AHB_GIZMO_USB, AHB_GIZMO_AHB_XBAR_BRIDGE, AHB_GIZMO_CPU_AHB_BRIDGE, AHB_GIZMO_COP_AHB_BRIDGE, AHB_GIZMO_XBAR_APB_CTLR, AHB_GIZMO_VCP_AHB_BRIDGE, AHB_GIZMO_NAND, AHB_GIZMO_SDMMC4, AHB_GIZMO_XIO, AHB_GIZMO_BSEV, AHB_GIZMO_BSEA, AHB_GIZMO_NOR, AHB_GIZMO_USB2, AHB_GIZMO_USB3, AHB_GIZMO_SDMMC1, AHB_GIZMO_SDMMC2, AHB_GIZMO_SDMMC3, AHB_MEM_PREFETCH_CFG_X, AHB_ARBITRATION_XBAR_CTRL, AHB_MEM_PREFETCH_CFG3, AHB_MEM_PREFETCH_CFG4, AHB_MEM_PREFETCH_CFG1, AHB_MEM_PREFETCH_CFG2, AHB_ARBITRATION_AHB_MEM_WRQUE_MST_ID, }; struct tegra_ahb { void __iomem *regs; struct device *dev; u32 ctx[0]; }; static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset) { return readl(ahb->regs + offset); } static inline void gizmo_writel(struct tegra_ahb *ahb, u32 value, u32 offset) { writel(value, ahb->regs + offset); } #ifdef CONFIG_ARCH_TEGRA_3x_SOC static int tegra_ahb_match_by_smmu(struct device *dev, void *data) { struct tegra_ahb *ahb = dev_get_drvdata(dev); struct device_node *dn = data; return (ahb->dev->of_node == dn) ? 1 : 0; } int tegra_ahb_enable_smmu(struct device_node *dn) { struct device *dev; u32 val; struct tegra_ahb *ahb; dev = driver_find_device(&tegra_ahb_driver.driver, NULL, dn, tegra_ahb_match_by_smmu); if (!dev) return -EPROBE_DEFER; ahb = dev_get_drvdata(dev); val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL); val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE; gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL); return 0; } EXPORT_SYMBOL(tegra_ahb_enable_smmu); #endif static int tegra_ahb_suspend(struct device *dev) { int i; struct tegra_ahb *ahb = dev_get_drvdata(dev); for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++) ahb->ctx[i] = gizmo_readl(ahb, tegra_ahb_gizmo[i]); return 0; } static int tegra_ahb_resume(struct device *dev) { int i; struct tegra_ahb *ahb = dev_get_drvdata(dev); for (i = 0; i < ARRAY_SIZE(tegra_ahb_gizmo); i++) gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]); return 0; } static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm, tegra_ahb_suspend, tegra_ahb_resume, NULL); static void tegra_ahb_gizmo_init(struct tegra_ahb *ahb) { u32 val; val = gizmo_readl(ahb, AHB_GIZMO_AHB_MEM); val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR; gizmo_writel(ahb, val, AHB_GIZMO_AHB_MEM); val = gizmo_readl(ahb, AHB_GIZMO_USB); val |= IMMEDIATE; gizmo_writel(ahb, val, AHB_GIZMO_USB); val = gizmo_readl(ahb, AHB_GIZMO_USB2); val |= IMMEDIATE; gizmo_writel(ahb, val, AHB_GIZMO_USB2); val = gizmo_readl(ahb, AHB_GIZMO_USB3); val |= IMMEDIATE; gizmo_writel(ahb, val, AHB_GIZMO_USB3); val = gizmo_readl(ahb, AHB_ARBITRATION_PRIORITY_CTRL); val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3 | AHB_PRIORITY_WEIGHT(7); gizmo_writel(ahb, val, AHB_ARBITRATION_PRIORITY_CTRL); val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG1); val &= ~MST_ID(~0); val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG1); val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG2); val &= ~MST_ID(~0); val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG2); val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG3); val &= ~MST_ID(~0); val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG3); val = gizmo_readl(ahb, AHB_MEM_PREFETCH_CFG4); val &= ~MST_ID(~0); val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); gizmo_writel(ahb, val, AHB_MEM_PREFETCH_CFG4); } static int __devinit tegra_ahb_probe(struct platform_device *pdev) { struct resource *res; struct tegra_ahb *ahb; size_t bytes; bytes = sizeof(*ahb) + sizeof(u32) * ARRAY_SIZE(tegra_ahb_gizmo); ahb = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL); if (!ahb) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; ahb->regs = devm_request_and_ioremap(&pdev->dev, res); if (!ahb->regs) return -EBUSY; ahb->dev = &pdev->dev; platform_set_drvdata(pdev, ahb); tegra_ahb_gizmo_init(ahb); return 0; } static int __devexit tegra_ahb_remove(struct platform_device *pdev) { return 0; } static const struct of_device_id tegra_ahb_of_match[] __devinitconst = { { .compatible = "nvidia,tegra30-ahb", }, { .compatible = "nvidia,tegra20-ahb", }, {}, }; static struct platform_driver tegra_ahb_driver = { .probe = tegra_ahb_probe, .remove = __devexit_p(tegra_ahb_remove), .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .of_match_table = tegra_ahb_of_match, .pm = &tegra_ahb_pm, }, }; module_platform_driver(tegra_ahb_driver); MODULE_AUTHOR("Hiroshi DOYU "); MODULE_DESCRIPTION("Tegra AHB driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:" DRV_NAME); n125' href='#n125'>125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
#!/usr/bin/env rspec
require 'spec_helper'

require 'puppet/application/master'
require 'puppet/daemon'
require 'puppet/network/server'

describe Puppet::Application::Master, :fails_on_windows => true do
  before :each do
    @master = Puppet::Application[:master]
    @daemon = stub_everything 'daemon'
    Puppet::Daemon.stubs(:new).returns(@daemon)
    Puppet::Util::Log.stubs(:newdestination)

    Puppet::Node.indirection.stubs(:terminus_class=)
    Puppet::Node.indirection.stubs(:cache_class=)
    Puppet::Node::Facts.indirection.stubs(:terminus_class=)
    Puppet::Node::Facts.indirection.stubs(:cache_class=)
    Puppet::Transaction::Report.indirection.stubs(:terminus_class=)
    Puppet::Resource::Catalog.indirection.stubs(:terminus_class=)
    Puppet::SSL::Host.stubs(:ca_location=)
  end

  it "should operate in master run_mode" do
    @master.class.run_mode.name.should equal(:master)
  end

  it "should ask Puppet::Application to parse Puppet configuration file" do
    @master.should_parse_config?.should be_true
  end

  it "should declare a main command" do
    @master.should respond_to(:main)
  end

  it "should declare a compile command" do
    @master.should respond_to(:compile)
  end

  it "should declare a preinit block" do
    @master.should respond_to(:preinit)
  end

  describe "during preinit" do
    before :each do
      @master.stubs(:trap)
    end

    it "should catch INT" do
      @master.stubs(:trap).with { |arg,block| arg == :INT }

      @master.preinit
    end

    it "should create a Puppet Daemon" do
      Puppet::Daemon.expects(:new).returns(@daemon)

      @master.preinit
    end

    it "should give ARGV to the Daemon" do
      argv = stub 'argv'
      ARGV.stubs(:dup).returns(argv)
      @daemon.expects(:argv=).with(argv)

      @master.preinit
    end

  end

  [:debug,:verbose].each do |option|
    it "should declare handle_#{option} method" do
      @master.should respond_to("handle_#{option}".to_sym)
    end

    it "should store argument value when calling handle_#{option}" do
      @master.options.expects(:[]=).with(option, 'arg')
      @master.send("handle_#{option}".to_sym, 'arg')
    end
  end

  describe "when applying options" do
    before do
      @master.command_line.stubs(:args).returns([])
    end

    it "should set the log destination with --logdest" do
      Puppet::Log.expects(:newdestination).with("console")

      @master.handle_logdest("console")
    end

    it "should put the setdest options to true" do
      @master.options.expects(:[]=).with(:setdest,true)

      @master.handle_logdest("console")
    end

    it "should parse the log destination from ARGV" do
      @master.command_line.stubs(:args).returns(%w{--logdest /my/file})

      Puppet::Util::Log.expects(:newdestination).with("/my/file")

      @master.parse_options
    end
  end

  describe "during setup" do
    before :each do
      Puppet::Log.stubs(:newdestination)
      Puppet.stubs(:settraps)
      Puppet::SSL::CertificateAuthority.stubs(:instance)
      Puppet::SSL::CertificateAuthority.stubs(:ca?)
      Puppet.settings.stubs(:use)

      @master.options.stubs(:[]).with(any_parameters)
    end

    it "should abort stating that the master is not supported on Windows" do
      Puppet.features.stubs(:microsoft_windows?).returns(true)

      expect { @master.setup }.to raise_error(Puppet::Error, /Puppet master is not supported on Microsoft Windows/)
    end

    it "should set log level to debug if --debug was passed" do
      @master.options.stubs(:[]).with(:debug).returns(true)
      @master.setup
      Puppet::Log.level.should == :debug
    end

    it "should set log level to info if --verbose was passed" do
      @master.options.stubs(:[]).with(:verbose).returns(true)
      @master.setup
      Puppet::Log.level.should == :info
    end

    it "should set console as the log destination if no --logdest and --daemonize" do
      @master.stubs(:[]).with(:daemonize).returns(:false)

      Puppet::Log.expects(:newdestination).with(:syslog)

      @master.setup
    end

    it "should set syslog as the log destination if no --logdest and not --daemonize" do
      Puppet::Log.expects(:newdestination).with(:syslog)

      @master.setup
    end

    it "should set syslog as the log destination if --rack" do
      @master.options.stubs(:[]).with(:rack).returns(:true)

      Puppet::Log.expects(:newdestination).with(:syslog)

      @master.setup
    end

    it "should print puppet config if asked to in Puppet config" do
      Puppet.settings.stubs(:print_configs?).returns(true)
      Puppet.settings.expects(:print_configs).returns(true)
      expect { @master.setup }.to exit_with 0
    end

    it "should exit after printing puppet config if asked to in Puppet config" do
      Puppet.settings.stubs(:print_configs?).returns(true)
      expect { @master.setup }.to exit_with 1
    end

    it "should tell Puppet.settings to use :main,:ssl,:master and :metrics category" do
      Puppet.settings.expects(:use).with(:main,:master,:ssl,:metrics)

      @master.setup
    end

    it "should cache class in yaml" do
      Puppet::Node.indirection.expects(:cache_class=).with(:yaml)

      @master.setup
    end

    describe "with no ca" do

      it "should set the ca_location to none" do
        Puppet::SSL::Host.expects(:ca_location=).with(:none)

        @master.setup
      end

    end

    describe "with a ca configured" do

      before :each do
        Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)
      end

      it "should set the ca_location to local" do
        Puppet::SSL::Host.expects(:ca_location=).with(:local)

        @master.setup
      end

      it "should tell Puppet.settings to use :ca category" do
        Puppet.settings.expects(:use).with(:ca)

        @master.setup
      end

      it "should instantiate the CertificateAuthority singleton" do
        Puppet::SSL::CertificateAuthority.expects(:instance)

        @master.setup
      end


    end

  end

  describe "when running" do
    before do
      @master.preinit
    end

    it "should dispatch to compile if called with --compile" do
      @master.options[:node] = "foo"
      @master.expects(:compile)
      @master.run_command
    end

    it "should dispatch to main otherwise" do
      @master.options[:node] = nil

      @master.expects(:main)
      @master.run_command
    end

    describe "the compile command" do
      before do
        Puppet.stubs(:[]).with(:environment)
        Puppet.stubs(:[]).with(:manifest).returns("site.pp")
        Puppet.stubs(:err)
        @master.stubs(:jj)
        Puppet.features.stubs(:pson?).returns true
      end

      it "should fail if pson isn't available" do
        Puppet.features.expects(:pson?).returns false
        lambda { @master.compile }.should raise_error
      end

      it "should compile a catalog for the specified node" do
        @master.options[:node] = "foo"
        Puppet::Resource::Catalog.indirection.expects(:find).with("foo").returns Puppet::Resource::Catalog.new
        $stdout.stubs(:puts)

        expect { @master.compile }.to exit_with 0
      end

      it "should convert the catalog to a pure-resource catalog and use 'jj' to pretty-print the catalog" do
        catalog = Puppet::Resource::Catalog.new
        Puppet::Resource::Catalog.indirection.expects(:find).returns catalog

        catalog.expects(:to_resource).returns("rescat")

        @master.options[:node] = "foo"
        @master.expects(:jj).with("rescat")

        expect { @master.compile }.to exit_with 0
      end

      it "should exit with error code 30 if no catalog can be found" do
        @master.options[:node] = "foo"
        Puppet::Resource::Catalog.indirection.expects(:find).returns nil
        $stderr.expects(:puts)
        expect { @master.compile }.to exit_with 30
      end

      it "should exit with error code 30 if there's a failure" do
        @master.options[:node] = "foo"
        Puppet::Resource::Catalog.indirection.expects(:find).raises ArgumentError
        $stderr.expects(:puts)
        expect { @master.compile }.to exit_with 30
      end
    end

    describe "the main command" do
      before :each do
        @master.preinit
        @server = stub_everything 'server'
        Puppet::Network::Server.stubs(:new).returns(@server)
        @app = stub_everything 'app'
        Puppet::SSL::Host.stubs(:localhost)
        Puppet::SSL::CertificateAuthority.stubs(:ca?)
        Process.stubs(:uid).returns(1000)
        Puppet.stubs(:service)
        Puppet.stubs(:[])
        Puppet.stubs(:notice)
        Puppet.stubs(:start)
      end

      it "should create a Server" do
        Puppet::Network::Server.expects(:new)

        @master.main
      end

      it "should give the server to the daemon" do
        @daemon.expects(:server=).with(@server)

        @master.main
      end

      it "should create the server with the right XMLRPC handlers" do
        Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers] == [:Status, :FileServer, :Master, :Report, :Filebucket]}

        @master.main
      end

      it "should create the server with a :ca xmlrpc handler if needed" do
        Puppet.stubs(:[]).with(:ca).returns(true)
        Puppet::Network::Server.expects(:new).with { |args| args[:xmlrpc_handlers].include?(:CA) }

        @master.main
      end

      it "should generate a SSL cert for localhost" do
        Puppet::SSL::Host.expects(:localhost)

        @master.main
      end

      it "should make sure to *only* hit the CA for data" do
        Puppet::SSL::CertificateAuthority.stubs(:ca?).returns(true)

        Puppet::SSL::Host.expects(:ca_location=).with(:only)

        @master.main
      end

      it "should drop privileges if running as root" do
        Puppet.features.stubs(:root?).returns true

        Puppet::Util.expects(:chuser)

        @master.main
      end

      it "should daemonize if needed" do
        Puppet.stubs(:[]).with(:daemonize).returns(true)

        @daemon.expects(:daemonize)

        @master.main
      end

      it "should start the service" do
        @daemon.expects(:start)

        @master.main
      end

      describe "with --rack", :if => Puppet.features.rack? do
        before do
          require 'puppet/network/http/rack'
          Puppet::Network::HTTP::Rack.stubs(:new).returns(@app)
        end

        it "it should create the app with REST and XMLRPC support" do
          @master.options.stubs(:[]).with(:rack).returns(:true)