/*
 * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_RUNTIME_ICACHE_HPP
#define SHARE_RUNTIME_ICACHE_HPP

#include "memory/allStatic.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "utilities/macros.hpp"

// Interface for updating the instruction cache.  Whenever the VM modifies
// code, part of the processor instruction cache potentially has to be flushed.

// Default implementation is in icache.cpp, and can be hidden per-platform.
// Most platforms must provide only ICacheStubGenerator::generate_icache_flush().
// Platforms that don't require icache flushing can just nullify the public
// members of AbstractICache in their ICache class.  AbstractICache should never
// be referenced other than by deriving the ICache class from it.
//
// The code for the ICache class and for generate_icache_flush() must be in
// architecture-specific files, i.e., icache_<arch>.hpp/.cpp

class AbstractICache : AllStatic {
 public:
  // The flush stub signature
  typedef int (*flush_icache_stub_t)(address addr, int lines, int magic);

 protected:
  // The flush stub function address
  static flush_icache_stub_t _flush_icache_stub;

  // Call the flush stub
  static void call_flush_stub(address start, int lines);

 public:
  enum {
    stub_size      = 0, // Size of the icache flush stub in bytes
    line_size      = 0, // Icache line size in bytes
    log2_line_size = 0  // log2(line_size)
  };

  // Initialization phases:
  //  1 = Initial phase, nothing is known about the machine features.
  //      The stub generated at this phase must use the most basic mechanism,
  //      until optimized final stub is generated.
  //  2 = Final stub that uses the optimized flush mechanism. Happens after
  //      CPU feature detection determines which mechanism is usable.
  static void initialize(int phase);
  static void invalidate_word(address addr);
  static void invalidate_range(address start, int nbytes);
};


// Must be included before the definition of ICacheStubGenerator
// because ICacheStubGenerator uses ICache definitions.

#include CPU_HEADER(icache)

class ICacheStubGenerator : public StubCodeGenerator {
 private:
   const char* _stub_name;

 public:
  ICacheStubGenerator(const char* stub_name, CodeBuffer *c) : StubCodeGenerator(c), _stub_name(stub_name) {}

  // Generate the icache flush stub.
  //
  // Since we cannot flush the cache when this stub is generated,
  // it must be generated first, and just to be sure, we do extra
  // work to allow a check that these instructions got executed.
  //
  // The flush stub has three parameters (see flush_icache_stub_t).
  //
  //   addr  - Start address, must be aligned at log2_line_size
  //   lines - Number of line_size icache lines to flush
  //   magic - Magic number copied to result register to make sure
  //           the stub executed properly
  //
  // A template for generate_icache_flush is
  //
  //    #define __ _masm->
  //
  //    void ICacheStubGenerator::generate_icache_flush(
  //      ICache::flush_icache_stub_t* flush_icache_stub
  //    ) {
  //      StubCodeMark mark(this, "ICache", "flush_icache_stub");
  //
  //      address start = __ pc();
  //
  //      // emit flush stub asm code
  //
  //      // Must be set here so StubCodeMark destructor can call the flush stub.
  //      *flush_icache_stub = (ICache::flush_icache_stub_t)start;
  //    };
  //
  //    #undef __
  //
  // The first use of flush_icache_stub must apply it to itself.  The
  // StubCodeMark destructor in generate_icache_flush will call Assembler::flush,
  // which in turn will call invalidate_range (see asm/assembler.cpp), which
  // in turn will call the flush stub *before* generate_icache_flush returns.
  // The usual method of having generate_icache_flush return the address of the
  // stub to its caller, which would then, e.g., store that address in
  // flush_icache_stub, won't work.  generate_icache_flush must itself set
  // flush_icache_stub to the address of the stub it generates before
  // the StubCodeMark destructor is invoked.

  void generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub);
};

#endif // SHARE_RUNTIME_ICACHE_HPP
